In this tutorial we will learn how to use View Composers in Laravel 10. View composer in Laravel is a class or callback which is executed when we render a specific view. Here we will deal with it in detail to understand it with the given example here.
Suppose you are running a blog website with a couple of pages specifically two like these:
- Landing Page where the recent posts are featured
- Posts Page where the recent posts are featured
We have shown it in the image below to make it more understandable how it would be actually working at the backend.
Here, we have defined two routes for each of the pages:
Home Page: /
Post Page: /posts
You should understand that the above two routes are connected with appropriate controller methods using routes/web.php file as shown below:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('home');
});
Route::get('/posts', function () {
return view('post');
});
For each routes we have corresponding views:
<html>
<head>
<title>@yield('title')</title>
</head>
<body>
@yield('content')
</body>
</html>
Now in home.blade.php:
@extends('layout.base')
@section('title', 'Home Page')
@section('content')
@include('post.list')
@endsection
Let’s move to post.blade.php
@extends('layout.base')
@section('title', 'Post Page')
@section('content')
@include('post.list')
@endsection
Finally here we will open post/list.blade.php
@foreach($posts as $post)
<h1>{{ $post->title }}
@endforeach
You should consider the above codes and read below how we have dealt everything:
You’d notice that we have used the same view for each of the pages.
Suppose post.list view uses $posts variable to demonstrate posts list and later uses html to create blogs list. We would pass that $posts variable like we have shown below. We can pass $posts variable using our home/postroute/controller and would use it in the post.list view. What would be the course of action if the view has already been used on more other pages. Can we pass it that way if it has already been used? We would use a view composer for such conditions where the same code has been used in different routes.
How to Use Laravel View Composer?
We need to understand in situations where different routes/controllers share the same views we would use a view composer in Laravel 10. So when a condition arises post.list view being used in different pages a callback/class would be used which helps us collect data we have to pass into post.list view.
In this perspective we don’t have to pass the data that our view is served through various controllers. Have a look at this image which shows details:
So when do all that, here is what the scenario is:
#1 As we load the home or any post page we see post.lists view included
#2 Call view composer is called when post.list view gets rendered
#3 AS the view composer gets called the post model is also called and gets all the posts
sending $posts variable to the called view such as post.list.
Create ViewServiceProvider
We will use our view composer We have to create view composer for that we have to create a service provider which will be used to organize
view composers in a single place. We will use the following command:
# when we are not using shell
php artisan make:provider ViewServiceProvider
# when we are using laravel shell
./vendor/bin/sail artisan make:provider ViewServiceProvider
We have to create our demo that has a Post model and title column. We have to suppose these:
#1 We have posts table with ID Title Column
#2 We have created migration for post in Laravel 10
#3 We have also defined post model
Once it generates ViewServiceProvider open created file and add following code:
<?php
namespace App\Providers;
use App\Models\Post;
use App\View\Composers\PostComposer;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ViewServiceProvider extends ServiceProvider
{
public function boot()
{
// For creating a class we use this code
// Based on our view composer or else use callback
View::composer('post.list', PostComposer::class);
// For callbacks we use this code
// Based view composer instead of class based view composer
View::composer('post.list', function ($view) {
// then this code creates the $posts variable that we could use
// in our post.list view we may create other variables if we have to
$view->with('posts', Post::orderByDesc('created_at')->paginate());
});
}
}
You should understand that we can also use class based view composer for creating a new class called PostComposer under app\View\Composers:
<?php
namespace App\View\Composers;
use App\Models\Post;
use Illuminate\View\View;
class PostComposer
{
public function compose(View $view)
{
$view->with('posts', Post::orderByDesc('created_at')->paginate());
}
}
When we have used this code, now we have to inform Laravel 10 to load our service provider we created. For that we have to go to config/app.php add into it our ViewServiceProvider as we see added in the following list:
<?php
// some other code
'providers' => [
// Some other providers may be added here
// Add View Composer Provider
App\Providers\ViewServiceProvider::class
]
Once we have done all this, and you have followed all the steps in detail then go to the browser and open http://localhost/posts in it. It will show us the posts list.