2

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

1
  • Nice question-answer here,thank you for it,is there any simpler/easier way to do this ? like maybe view::make view::share ? Commented Aug 20, 2016 at 20:51

1 Answer 1

5

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);
}
Sign up to request clarification or add additional context in comments.

4 Comments

So going off the Docs' example I should register a composer via the services? I don't see the example you gave in the docs.
I think I understand though. I shall try the solution tomorrow
Yes, you should create service provider and add it to the list in config/app.php. Then you should create view composer. Look carefully, there is full example in docs (right after service provider example, you can use search on the page for class ProfileComposer).
I had a go, ran into some issue. Edited my Question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.