laloutre's avatar

Laravel 5 view composers

What are your solutions to register View Composers in Laravel 5 (I have to confess that I used route.php in L4 for that...)?

Mine is to create a app/Http/viewcomposer.php file, and to load it in RouteServiceProvider like that:

public function map(Router $router)
{
    require app_path('Http/viewcomposers.php');
}

Is there a better way?

0 likes
9 replies
thepsion5's avatar

Realistically, the RouteServiceProvider shouldn't be dealing with View Composers. It seems like it'd be pretty easy to create a ViewServiceProvider and register your view composers there. But I think for most projects you could get away with just using it with your Route service provider.

martinbean's avatar

I used a view composer recently. I had a cart package, and I wanted to show the user’s cart total throughout the site. In Laravel 4, this is where I would have used a view composer and attach it to my master layout template.

In my Laravel 5 application, I registered the view composer in my CartServerProvider class, which looks like this:

<?php namespace Vendor\Cart;

use Illuminate\Support\ServiceProvider;

class CartServiceProvider extends ServiceProvider {

  /**
   * Register the service provider.
   *
   * @return void
   */
  public function register()
  {
    $this->app->make('view')->composer('layouts.master', 'Vendor\Cart\Http\ViewComposers\CartComposer');
  }

}

The CartComposer class looks like this:

<?php namespace Vendor\Cart\Http\ViewComposers;

use Illuminate\Contracts\View\View;

class CartComposer {

  /**
   * Cart manager instance.
   *
   * @var \Vendor\Cart\StoreInterface
   */
  protected $cart;

  /**
   * Create a new CartComposer instance.
   */
  public function __construct()
  {
    $this->cart = app()->make('cart.store');
  }

  /**
   * Compose the view.
   *
   * @return void
   */
  public function compose(View $view)
  {
    $view->with('cart', $this->cart);
  }

}

cart.store is a custom cart implementation I injected into the container, but the above should be enough to show you how to register a simple view composer.

4 likes
FroimsonM's avatar

Guys, I tried the example in the docs and the example above and both didn't work for me. In the docs (http://laravel.com/docs/master/views) we have a "boot" method and no "register", so I got an error that I have an abstract method in my ViewComposerServiceProvider.

In martinbean's case my app cannot instantiate "view" class (Class view does not exist), I tried "view" instead and then got "Call to undefined method Illuminate\Support\Facades\View::composer()"

pmall's avatar

@FroimsonM he doesn't instantiate a new view class he gets it from the IoC container

usman's avatar

Hi @FroimsonM, try this provider:

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider {

    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->app['view']->composer('index',function($view){
            $view->title = 'Laracasts';
        });
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

}

I hope this helps, Regards!

buzzwoo's avatar

The ServiceProvider approach looks clean and perfect for this task except that the official documentations says:

Within the register method, you should only bind things into the service container. You should never attempt to register any event listeners, routes, or any other piece of functionality within the register method.

http://laravel.com/docs/5.1/providers

So my question is: Is a view composer considered as an event listener or not? (the view composer method is fired when the view is composed, so in a way it is an event as far as I understand)

andy's avatar

hmmm ... shouldn't you use the boot methond within the ServiceProvider?

So, what if we need to register a view composer within our service provider? This should be done within the boot method. This method is called after all other service providers have been registered, meaning you have access to all other services that have been registered by the framework:

Looks I need to double check some of my providers to make sure I've been doing this correctly ...

Please or to participate in this conversation.