imperium2335
imperium2335

Reputation: 24122

Laravel 5 view composer with multiple variables

Is there a more elegant way of doing:

abstract class Controller extends BaseController
{
    use DispatchesJobs, ValidatesRequests;

    function __construct() {
        view()->composer('includes.topbar', function ($view) {
            $view->with('nav', $this->topNav());
        });
        view()->composer('includes.sidebar', function ($view) {
            $view->with('sidebar', $this->sidebar());
        });
    }
    ...
}

?


Using a view composer:

NavigationComposer

 namespace App\Http\ViewComposers;

use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Auth;

class NavigationComposer
{
    protected $user;

    public function __construct()
    {
        $this->user = Auth::user();
    }

    public function compose(View $view)
    {
        $view->with(['nav' => $this->topNav(), 'sidebar' => $this->sidebar()]);
    }

    public function topNav()
    {
        $nav['Dashboard'] = [
            'route' => 'dashboard'
        ];
        $nav['Sales'] = [
            'route' => 'sales',
            'subitems' => [
                'Enquiries' => 'sales.enquiries',
                'Quotes' => 'sales.quotes',
                'Orders' => 'sales.orders'
            ]
        ];
        $nav['CRM'] = [
            'route' => 'crm',
            'subitems' => [
                'Companies' => 'crm.companies',
                'Conversion report' => 'crm.conversion-report'
            ]
        ];
        return $nav;
    }

    public function sidebar()
    {
        return 'sidebar';
    }
}

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(
            'includes.topbar', 'App\Http\ViewComposers\NavigationComposer'
        );
        view()->composer(
            'includes.sidebar', 'App\Http\ViewComposers\NavigationComposer'
        );
    }
    ...
}

I have split them in two as per advice from @Gal

ComposerServiceProvider

...
public function boot()
    {
        // Using class based composers...
        view()->composer('includes.topbar', 'App\Http\ViewComposers\TopNavigationComposer');
        view()->composer('includes.sidebar', 'App\Http\ViewComposers\SidebarComposer');
    }
...

TopNavigationComposer

...
public function compose(View $view)
    {
        $view->with('nav', $this->topNav());
    }

    public function topNav()
    {
        $nav['Dashboard'] = [
            'route' => 'dashboard'
        ];
        $nav['Sales'] = [
            'route' => 'sales',
            'subitems' => [
                'Enquiries' => 'sales.enquiries',
                'Quotes' => 'sales.quotes',
                'Orders' => 'sales.orders'
            ]
        ];
        $nav['CRM'] = [
            'route' => 'crm',
            'subitems' => [
                'Companies' => 'crm.companies',
                'Conversion report' => 'crm.conversion-report'
            ]
        ];
        return $nav;
    }
...

SidebarComposer

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

    public function sidebar()
    {
        return 'sidebar';
    }
...

Upvotes: 3

Views: 6620

Answers (3)

Lijesh Shakya
Lijesh Shakya

Reputation: 2540

You can use multiple with chain in the view composer function to retrieve the variables.

//For all views
\View::composer('*', function($views){
           $views->with('users', App\User::all())
           ->with('roles', App\Role::all())
           ->with('publishers', Publisher::all());
        });

For more information: Laravel 5.7 View Composer

Upvotes: 3

Abdullah Al Mamun
Abdullah Al Mamun

Reputation: 132

Try this. It's work for me.

public function boot()
    {
        view::composer('layout', function ($sliders){
            $all_sliders = DB::table('sliders')
                ->where('status', 1)
                ->get();
            $sliders->with('sliders', $all_sliders);
        });

        view::composer('layout', function ($categories){
            $all_category = DB::table('categories')
                ->where('status', 1)
                ->get();
            $categories->with('categories', $all_category);
        });

        view::composer('layout', function ($brands){
            $all_brand = DB::table('brands')
                ->where('status', 1)
                ->get();
            $brands->with('brands', $all_brand);
        });
    }

Upvotes: 1

mdamia
mdamia

Reputation: 4557

If you just want to make a partial view accessible in the master layout, you could do something like this .

In your master layout, create a section for your partial view or views :

@section('partial_view_1')
@show
@section('partial_view_2')
@show

In your controller's constructor, do this , make sure you declare $layout

$this -> layout  = view('layouts.master');
$this -> layout -> partial_view_1 = view('includes.top_nav'); 
// -> with($data); if you want to pass data to the top nav. 
$this -> layout -> partial_view_2 = view('includes.side_nav');

public function index(){
    $this -> layout -> main_content = view('contents.main');
    return $this -> layout;
 }

Now if you want to bind data to a view whenever the view is called, you may want to use a View Composer. Hope this help.

Upvotes: 1

Related Questions