Laravel | Get specified data for current page - laravel

I'm trying to get meta data for each page
Each page has a unique slug
In appServiceProvider I have:
$view->with('seopage', Page::all());
In blade view (section head) I have:
<title>
#foreach($seopage as $sm)
{{ $sm->main_title }}
#endforeach
</title>
<meta name="description" content="
#if(Request::is('/*'))
#foreach($seopage as $sp)
{{ $sp->site_description }}
#endforeach
#endif
">
But it is getting all titles and descriptions for me at the moment. How can I get data for specified page?
Page model have unique SLUG variable. Thanks

In appServiceProvider you can share page which belongs to specified page:
$page = Page::where('slug', Request::path())->first();
View::share('seopage', $page);
And in view you can retreive shared variable:
<meta name="description" content="
#if(Request::is('/*') && isset($seopage))
{{ $seopage->site_description }}
#endif
">

You must be have unique uri column in seopage table
The you must be use
use Illuminate\Support\Facades\Route;
.....
$uri = \Route::current()->uri;
$seopage = Page::where('uri', $uri)->first();
if ($seopage) {
$seo = sprintf(
'<title>%s</title>' . PHP_EOL
. '<meta name="description" content="%s>',
$seopage->main_title ,
$seopage->site_description
);
} else {
$seo = '';
}
$view->with('seo', $seo);
In Blade use
{{ $seo }}

Related

Laravel: pagination on $images = json_decode( );

I wish to add pagination for my certificates, 8 certs in 1 page. How can I make it? Thanks in advance.
certificates Controller:
class certificatesController extends Controller
{
public function index()
{
$currentid = null;
$certificates = certificates::first();
$images = json_decode($certificates->image);
return view('certificate.index', compact('images', 'certificates', 'currentid'));
}
}
index blade:
#foreach ($images as $img)
<div class="grid-item">
<!-- photo item -->
<a class="img-box" href="{{ asset('source/upload/certificates/800x600/'.$img) }}">
<img src="{{ asset('source/upload/certificates/800x600/'.$img) }}" alt="">
</a></a>
<!-- end photo item -->
</div>
#endforeach
To limit number of items in per page in pagination in query then you can pass parameter to paginate() method like below
$certificates = certificates::paginate(8);
the only argument passed to the paginate method is the number of items you would like displayed "per page". In this case, let's specify that we would like to display 8 items per page:
In blade template
#foreach ($certificates as $certificate)
#endforeach
{{ ($certificates->links() }}
Ref:https://laravel.com/docs/8.x/pagination#paginating-query-builder-results

How to display default image if no filename exists in Laravel database

I want to display an image for each entry in a list of posts. The name of the images are unique file names. They are all saved in a database (MySQL) table. There is more than one image for each post. The code works right. Except, when there is a post without an image filename. This is a possible scenario but i can't get the code to work. In the event there's no existing filename for a post, i want to display a default filename.
Here's my code:
Images logic:
/**
* Get a vehicle's top or main image data from the image table
*/
public function topImage($id)
{
$image = Vehiclefulldataimage::where('vehiclefulldatas_id', $id)
->orderBy('id', 'ASC')->first();
return $image;
}
Here's the blade view, Posts:
#if (count($posts) > 0)
#foreach($posts as $post)
<?php $imageFilename = (new \App\Models\Logic\Images)->topImage($post->id); ?>
<!--Item-->
<li>
<div class="preview">
#if ($imageFilename = 0)
<img src="{{ asset('images') . '/' . 'defaultImage.jpg' }}" alt="No photo">
#else
<img src="{{ asset('images') . '/' . $imageFilename->disk_image_filename }}" alt="{{ ucfirst($imageFilename->caption) . ' | ' . $post->title }}">
#endif
</div>
<div class="desc">
<h3>{{ str_limit($post->title, 100, '...') }}</h3>
</div>
</li>
<!--/Item-->
#endforeach
#endif
This is the error message i get:
"Trying to get property of Non Object"
Try the following code:
You are using an assignment operator instead of comparison operator
//#if (count($posts) > 0)
#if (!$posts->isEmpty())
#foreach($posts as $post)
<?php $imageFilename = (new \App\Models\Logic\Images)->topImage($post->id); ?>
<!--Item-->
<li>
<div class="preview">
//#if ($imageFilename = 0) this is an assignment operator not comparison operator
#if ($imageFilename->isEmpty())
<img src="{{ asset('images') . '/' . 'defaultImage.jpg' }}" alt="No photo">
#else
<img src="{{ asset('images') . '/' . $imageFilename->disk_image_filename }}" alt="{{ ucfirst($imageFilename->caption) . ' | ' . $post->title }}">
#endif
</div>
<div class="desc">
<h3>{{ str_limit($post->title, 100, '...') }}</h3>
</div>
</li>
<!--/Item-->
#endforeach
#endif
Check your if statement....what you're doing there is an assignment and not a condition test...you can include a column..with a string pointing to the path of your default image..and set it to default...then load it...as default image
All of the answers above fix your problem. However, I recommend you to fix this problem by using Laravel features, Mutators.
https://laravel.com/docs/5.8/eloquent-mutators
Laravel mutators allow you to format or modify your Model attribute.
Just in your Vehiclefulldataimage model write the code below:
public function getImageAttribute($value)
{
//can write more logic here.
return $value ?: 'path/to/your/default/image';
}
Then you don't care more if condition blade template. If your image is empty the mutator returns the default image. So, everywhere when your retrieve Vehiclefulldataimage instance the mutator works properly
Thanks everyone.
After looking at all the answers, i did a simple alteration to my code. I altered:
#if ($imageFilename = 0)
to:
#if ($imageFilename == null)
Thus, my code now looks:
#if (count($posts) > 0)
#foreach($posts as $post)
<?php $imageFilename = (new \App\Models\Logic\Images)->topImage($post->id); ?>
<!--Item-->
<li>
<div class="preview">
#if ($imageFilename == null)
<img src="{{ asset('images') . '/' . 'defaultImage.jpg' }}" alt="No photo">
#else
<img src="{{ asset('images') . '/' . $imageFilename->disk_image_filename }}" alt="{{ ucfirst($imageFilename->caption) . ' | ' . $post->title }}">
#endif
</div>
<div class="desc">
<h3>{{ str_limit($post->title, 100, '...') }}</h3>
</div>
</li>
<!--/Item-->
#endforeach
#endif

how to share data to all view in laravel 5.7

I have a login form. I want when user login success, my controller will select data of this user and share to all view.
I read laravel docs. [This][1] advises me to use the "View::share('key', 'value');"
in boot method of AppServiceProvider, but i dont know how to call it in my controller
my controller:
if( Auth::attempt(['mssv' => $username,'password' =>$password])) {
$user=SinhVien::where('mssv',$username)->first();
//i want to share $user to all view in here
$success = new MessageBag(['successlogin' => 'Login Success]);
return redirect()->back()->withErrors($success);
}
else {
$errors = new MessageBag(['errorlogin' => 'Login Fail']);
return redirect()->back()->withErrors($errors);
}
and in all view blade, I use:
{{$user->name}}
Please help!
[1]: https://laravel.com/docs/5.7/views#sharing-data-with-all-views
In your blades you would then have access to the key from the View::share('key', 'value'); you put in the AppServiceProvider.
So if the key is user, in your blades you just use the $user variable.
<!-- Stored in resources/views/layouts/app.blade.php -->
<html>
<head>
<title>App Name - #yield('title')</title>
</head>
<body>
<header>
<div>
#if(auth()->user())
{{ auth()->user()->name }}
#else
<button>login</button>
#endif
<div>
</header>
<div class="container">
#yield('content')
</div>
</body>
EDIT :
{{ auth()->user->name }} corrected -> {{ auth()->user()->name }}

Show secured images with Laravel 5 and Blade

I don't want that users can access images from simply using a URL like http://laravel.dev/123.jpg. Therefore I store all images in the storage directory, instead of storing them in the public folder.
With a controller like this
public function show($id) {
$img = storage_path('my_images/123.jpg');
return response()->download($img, null, [], null);
}
the image is correctly displayed by Laravel 5, although it is stored outside from the public folder.
Great up to this point ... but I want to use Blade and surround the image with some more details. Therefore my controller looks like this
public function show($id) {
$picture = Picture::find($id);
$img = storage_path('my_images/123.jpg');
return view('pictures.show', array('picture' => $picture, 'img' => $img));
}
and the view like this
<!DOCTYPE html>
<html>
<head>
<title>Picture {{ $picture->id }}</title>
</head>
<body>
<h1>Picture {{ $picture->id }}</h1>
<ul>
<li>Name: {{ $picture->name }}</li>
<li>Description: {{ $picture->description }}</li>
</ul>
<img src="{{ $image }}">
</body>
</html>
which obviously does not work, because the location of the image is not publicly accessible (which ist the intention).
What do I have to use instead of <img src="{{ $image }}"> to make this work?
Make the src attribute to call the URL of your first controller, this will work for you.
In other words, let's say, you have a route called image.show with that code.
public function show($id) {
$img = storage_path('my_images/123.jpg');
return response()->download($img, null, [], null);
}
So in your blade:
<img src={{route("image.show",$img_object)}}">

Using multidimensional array input names with Laravel 4.2 Form facade throws error on postback

I'm having an issue in Laravel 4.2 with the Form facade when using input names that represent multidimensional arrays. The form will load, display, and post data correctly unless there are values set in Input::old() (because of failed validation, etc.).
Here is a simple example that shows the problem:
routes.php:
Route::get('input-test', function() {
return View::make('input_test.index');
});
Route::post('input-test', function() {
return Redirect::back()->withInput(Input::all());
});
input_test/index.blade.php:
<!doctype html>
<html>
<head>
<title>Input Array Test</title>
</head>
<body>
{{ Form::open(array('url' => 'input-test')) }}
{{ Form::label('customer[some_customer_field][]', 'Customer Field:') }} <br>
{{ Form::text('customer[some_customer_field][]', null) }}
{{ Form::submit('Submit') }}
{{ Form::close() }}
</body>
</html>
Submitting this form will throw an error:
htmlentities() expects parameter 1 to be string, array given
Is there a way to get inputs with these types of names to work on postback?
That way is not the proper one.
Following one is it
{{ Form::label('customer[0][field_1], 'Customer Field:') }} <br>
{{ Form::text('customer[0][field_2]', null) }}
After that, if you want to duplicate it, you must use
{{ Form::label('customer[1][field_1], 'Customer Field:') }} <br>
{{ Form::text('customer[1][field_2]', null) }}
But if you want just get a simple array, you must use
{{ Form::label('customer[field_1], 'Customer Field:') }} <br>
{{ Form::text('customer[field_2]', null) }}

Resources