Laravel View Composer | Binding Data to Views Using View Composer

In this tutorial i will discuss about laravel view composer tutorial. Using view composer, we can define global variable, and we can access it globally. Laravel view composer tutorial is the todays topic.

Sometimes we need to get data many page, that time we can not get data from controller. That time we can use view composer. In this tutorial we will see how can we pass data to all controller that mean laravel 7 global variable for all controller.

Using view composer we can easily solve this global variable issue. So let's see how we can add laravel 7global variable in view.

Let’s say you have a sidebar on every page, which is defined in a partial named partials.sidebar (resources/views/partials/sidebar.blade.php) and then included on every page.

laravel-global-variable-view-composer

This sidebar shows a list of the last seven posts that were published on your site. If it’s on every page, every route definition would normally have to grab that list and pass it in, like below code

Route::get('home', function () {
  return view('home')
  ->with('posts', Post::recent());
});

Route::get('about', function () {
  return view('about')
  ->with('posts', Post::recent());
});

That could get annoying quickly. Instead, we’re going to use view composers to “share” that variable with a prescribed set of views.

We can do this a few ways, so let’s start simple and move up.

Read Also : Laravel Auth : Multi Authentication System Using Guard

Sharing a variable globally in Laravel
First, the simplest option: just globally “share” a variable with every view in your application like below code

// Some service provider
public function boot()
{
  view()->share('posts', Post::recent());
}

If you want to use view()->share(), the best place would be the boot() method of a service provider so that the binding runs on every page load.

You can create a custom ViewComposerServiceProvider, but for now just put it in App\Providers\AppServiceProvider in the boot() method.

Using view()->share() makes the variable accessible to every view in the entire application, however, so it might be overkill.

Closure-based view composers

The next option is to use a closure-based view composer to share variables with a single view, like below example

view()->composer('partials.sidebar', function ($view) {
  $view->with('posts', Post::recent()); //Where recent is static method which comes from your Post model
});

As you can see, we’ve defined the name of the view we want it shared with in the first parameter (partials.sidebar).

And then passed a closure to the second parameter in the closure, we’ve used $view->with() to share a variable, but now only with a specific view.

View composers for multiple views

Anywhere a view composer is binding to a particular view, you can pass an array of view names instead to bind to multiple views.

You can also use an asterisk in the view path, as in partials.*, tasks.*, or just *:

view()->composer(['partials.header', 'partials.footer'], function () {
  $view->with('posts', Post::recent());
});

view()->composer('partials.*', function () {
  $view->with('posts', Post::recent());
});

Class-based view composers

Finally, the most flexible but also most complex option is to create a dedicated class for your view composer. First, let’s create the view composer class.

There’s no formally defined place for view composers to live, but the docs recommend App\Http\ViewComposers.

So, let’s create App\Http\ViewComposers\RecentPostsComposer like below example

namespace App\Http\ViewComposers;

use App\Post;
use Illuminate\Contracts\View\View;

class RecentPostsComposer
{
  private $posts;

  public function __construct(Post $posts) {
    $this->posts = $posts;
  }

  public function compose(View $view) {
    $view->with('posts', $this->posts->recent());
  }

}

As you can see, we’re injecting the Post model (typehinted constructor parameters of view composers will be automatically injected. 

Note that we could skip the private $posts and the constructor injection and just use Post::recent() in the compose() method if we wanted.

Then, when this composer is called, it runs the compose() method, in which we bind the posts variable to the result of running the recent() method.

Like the other methods of sharing variables, this view composer needs to have a binding somewhere.

Again, you’d likely create a custom ViewComposerServiceProvider, but for now, we’ll just put it in the boot() method of App \Providers\AppServiceProvider.

Registering a view composer in AppServiceProvider

// AppServiceProvider
public function boot(){
  view()->composer('partials.sidebar', \App\Http\ViewComposers\RecentPostsComposer::class);
}

Note that this binding is the same as a closure-based view composer, but instead of passing a closure, we’re passing the class name of our view composer.

Now, every time Blade renders the partials.sidebar view, it’ll automatically run our provider and pass the view a posts variable set to the results of the recent() method on our Post model.

Hope you've enjoyed this lesson.

A web enthusiastic, self-motivated Full-Stack Web Developer from Dhaka, Bangladesh with experience in developing applications using JavaScript, Laravel & Wordpress specifically. Facebook Github Website