How to Use View Composers in Laravel 10

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.