samedi 24 octobre 2015

Bind data to specific blade templates in Laravel 5.1 (issue with view composer being called twice on nested template)

I am trying to implement themes in a site so that certain pages have a different look and feel (and features) to other pages.

I have master.blade which contains the full HTML structure and has @section and @yield to get the content:

<html>
<body>

    @section('master-template')
    <?php
        view()->share('masterTemplate', 'general');
        $masterTemplate = "general"; 
    ?>
    @stop

    <header>
        @section('nav-1')
            @include('layout.navs.house-links')
        @show

        @section('nav-2')
            @include ('layout.navs.contact-links')
        @show

        @section('nav-3')
            @include('layout.navs.product-links')
        @show

        @section('nav-4')

        @show
    </header>
    @yield('content')
</body>
</html>

I then have ford.blade which extends master, and overwrites some things:

@extends('templates.master')

@section('master-template')
    <?php
        view()->share('masterTemplate', 'ford');
        $masterTemplate = "ford"; 
    ?>
@overwrite

@section('nav-1')
    @include('layout.navs.house-links')
@overwrite

@section('nav-2')
    @include ('layout.navs.contact-links')
@overwrite

@section('nav-3')
    @include('layout.navs.product-links')
@overwrite

Then a regular page on the website will extend the master.blade, and anything that requires the Ford navigation bar and colour scheme will extend the ford.blade template.

I then bound a view composer to layout.navs.product-links which gets the $masterTemplate variable from the view data and checks if it is one of our themes (like "ford"). If it is a regular page, it will bind vehicle ranges for all manufacturers to the view, and if it is a ford page, it will only bind the ford ranges to the page. The psuedo-code of the view composer is below:

public function compose(View $view)
{
    // Get the view data
    $viewData = $view->getData();

    // Check for $masterTemplate view variable
    if (isset($viewData['masterTemplate'])) {
        $template = $viewData['masterTemplate'];

        if ($template == "ford") {
            $ranges = $this->getRangesForManufacturer($template);
        }else {
            $ranges = $this->getRangesForAllManufacturers();
        }

        $view->with('ranges', $ranges);
    }
}

The problem is, because ford.blade extends master.blade, BOTH views get rendered behind the scenes. So the above view composer logic is useless because it runs twice on the "ford" page, once for master.blade and then again for ford.blade.

I proved this by checking the queries that are running using Laravel DebugBar.

1) How can I bind a variable $masterTemplate for use in all views (and partials) to check logic inside a view whether it is a "ford" or "general" page? I did it with @section and @overwrite in ford.blade but this seems to not work everywhere.

2) How can I use a view composer to bind data to a partial view that is @include by ford.blade and master.blade, because ford.blade extends master.blade and so the view composer gets executed twice.



from Newest questions tagged laravel-5 - Stack Overflow http://ift.tt/1OO1g4y
via IFTTT

Aucun commentaire:

Enregistrer un commentaire