Sharing a common set of data across many views sounds like an easy task but is easy to do this the wrong way.  Using Laravel Composers allows you to have clean code without duplicating any of the data.  Though there are many different ways of doing this, the way in this guide is, in my opinion, the correct way of doing it using Laravel Composers.

When I talk about needing to use a common set of data in many views, this can mean something like, a sidebar with links. These links will be available on multiple views and they are the same for each view. It could also be something where your sidebar or nav links change depending on if a user is logged in or not.

View

Lets set up a view we will use for the next few options

[html] <html>
<head>
<title>Some View</title>
</head>

<body>
<div class="sidebar">
<h2>Sidebar</h2>
@foreach($links as $link)
<a href="#">{{ $link }}</a>
@endforeach
</div>

<div class="content">
@yield(‘content’)
</div>
</body>
</html>
[/html]

The quick and dirty way.

Many people will say, why not just do a View::make('home')->withSomething(['hello','world!']) ?   Well lets look at it this way.  If you have a controller with multiple views being returned and you need that something for each view, you are going to repeat the data.

[php] class HomeController
{
public function home()
{
return View::make(‘home’)->withLinks([‘hello’,’world!’]);
}

public function contact()
{
return View::make(‘contact’)->withLinks([‘hello’,’world!’]);
}
}
[/php]

As you can see with this, we have to include the ->withLinks() on every view we need it in. This is a bad thing in many ways. One big reason, if you need to update something in the variable, you have to remember every place you defined it. Another reason is it causes very dirty code.

Lets clean that up a little bit

[php] class HomeController
{
protected $links;

public function construct()
{
$this->links = [‘hello’,’world!’];
}

public function home()
{
return View::make(‘home’)->withLinks($this->links);
}

public function contact()
{
return View::make(‘contact’)->withLinks($this->links);
}
}
[/php]

Better, but not there yet. This options means that you only need to update your links in one place, for this controller, but what happens now if you do not include withLinks for a view? Your code breaks!

Lets look at how to use Laravel Composers to make this a much better solution.

Laravel Composers

This will start out looking a little confusing, however stick with me and I will explain it in detail to you on how to set this up. The first thing we should do is clean up our view a little bit. If we are going to target our sidebar as something we need a composer for, we should extract that code out into its own blade template and include it into our master view.

Master View

[html] <html>
<head>
<title>Some View</title>
</head>

<body>
@include(‘sidebar’)

<div class="content">
@yield(‘content’)
</div>
</body>
</html>
[/html]

sidebar.blade.php

[html] <div class="sidebar">
<h2>Sidebar</h2>
@foreach($links as $link)
<a href="#">{{ $link }}</a>
@endforeach
</div>
[/html]

Now that we have our sidebar out on its own, we can target it with our composer. There is no correct place to put the following code, however, I find myself creating a composers.php file in the app directory. After I create the composers.php file, Laravel does not know where it is or autoload it, so in /app/start/global.php place a line at the bottom to require that file.

[php] View::composer(‘sidebar’, function($view) {
$view->with(‘links’, [‘hello’,’world!’]);
});
[/php]

Now, anytime the sidebar.blade.php view is hit, this composer will fire and provide the view with the links variable.

See the magic of Laravel Composers?

There are a few more steps that can be done for cleaning the code up more. You could move the anonymous function for the composer into its own class, create a repository for your links you want to pass and much more. For these steps, instead of reinventing the wheel, I will direct you to a great video on the laracasts.com webpage where Jeffrey Way teaches you in a video lesson what was said here as well as some more in depth looks at it. Please support the Laravel Community and buy a subscription to laracasts.com.

Resources