scottevans93
scottevans93

Reputation: 1079

Laravel 5.2 'Master Layout' Variable passing

So here is what I'm trying to achieve. I have a default blade template default.blade.php which is extended by all of my child views.

Within my default.blade.php i have a foreach loop which expresses some 'global' options to the user, and example of which is below.

@foreach ($projects as $p)
    <li><a href='$p->project_uid'>{{ $p->project_name }}</a></li>
@endforeach

So to achieve this I'm having to pass the $projects variable via the view('viewname', $data) or via View::share('projects', $projects); in my Controller __construct()

Is there a better way for me to do this on a global sense so that the above calls don't need to be made?

One option i am aware of is calling a Model function from within my view, but this defies the concept of MVC so is not ideal.

Any guidance on the subject would be appreciated, Thanks.

Edit 1

So i tried the ViewComposer solution but ran into a couple of problems. Below is my Composer & the Service Provider Register.

Config/app.php

App\Providers\ComposerServiceProvider::class,

ComposerServiceProvider

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class ComposerServiceProvider extends ServiceProvider {
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function boot() {
        // Using class based composers...
        view ()->composer ( 'default', 'App\Http\ViewComposers\MasterComposer' );
    }

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register() {
        //
    }
}

MasterComposer

<?php

namespace App\Http\ViewComposers;

use Illuminate\View\View;
use App\Repositories\UserRepository;
use Sentinel;
use ProjectUsers;

class MasterComposer
{

    protected $users;

    public function __construct(ProjectUsers $users)
    {
        $uid = Sentinel::getUser()->id;
        $this->users = ProjectUsers::where("user_id", '=', $uid)->get();
    }

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

Am i missing something obvious as it doesn't seem like the Composer is being loaded at all.

Edit 2

Fixed it myself. Realised that within the ComposerServiceProvider i need to specify a full path to my view like so.

view ()->composer ( 'admin/layouts/default', 'App\Http\ViewComposers\MasterComposer' );

Now it Works :D

Upvotes: 2

Views: 1074

Answers (1)

Alexey Mezenin
Alexey Mezenin

Reputation: 163758

Yes, you do this with View Composer.

View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location.

Bind that data to defualt.blade.php view, like:

public function compose(View $view)
{
    $data = .... // Get data here.
    $view->with('projects', $data);
}

Upvotes: 5

Related Questions