Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reuse a blade partial in a template

I would like to be able to repeat a partial a number of times within a view, with different content in each repetition.

The partial is a simple panel, with a heading, and some content. The content within each panel can vary in complexity, so I would like to be able to use the @section('content') method of passing data.

The set up I have is as follows:

panel.blade.php - The partial to be repeated.

<div class="panel">
    <header>
        @yield('heading')
    </header>
    <div class="inner">
        @yield('inner')
    </div>
</div>

view.blade.php - The view in which the partial is repeated

@extends('default')

@section('content')

    {{-- First Panel --}}
    @section('heading')
        Welcome, {{ $user->name }}
    @stop
    @section('inner')
        <p>Welcome to the site.</p>
    @stop
    @include('panel')

    {{-- Second Panel --}}
    @section('heading')
        Your Friends
    @stop
    @section('inner')
        <ul>
        @foreach($user->friends as $friend)
            <li>{{ $friend->name }}</li>
        @endforeach
        </ul>
    @stop
    @include('panel')

@stop

I am running into the same issue as this: http://forums.laravel.io/viewtopic.php?id=3497

The first panel is displayed as intended, but the second is simply a repeat of the first.

How can I correct this? If this is a poor method of getting this done, what would be a better way?

like image 319
tahlo Avatar asked Sep 17 '13 03:09

tahlo


1 Answers

For Laravel 5.4, Components & Slots may be useful for you. The following solution is for Laravel 4.x, and likely <= 5.3 as well.


In my opinion, this is a silly use case for the @include syntax. The amount of HTML retyping you're saving is negligible, especially since the only potentially-complicated part of it is the inner content. Keep in mind, the more parsing that needs to be done, the more overhead your application has, also.

Also, I don't know the inner workings of the @yield & @section features, so I can't say how "proper" it is to work your includes this way. Includes typically utilize a key => value pair passed as a parameter in the include call:

@include('panel', ['heading' => 'Welcome', 'inner' => '<p>Some stuff here.</p>'])

Not the most ideal place to pack a bunch of HTML, but that's the "designed" way (as far as I know, at least).

That said...

Use the @section ... @overwrite syntax mentioned in the "Other Control Structures" part of the template docs page.

@extends('default')

@section('content')

    {{-- First Panel --}}
    @section('heading')
        Welcome, {{ $user->name }}
    @overwrite
    @section('inner')
        <p>Welcome to the site.</p>
    @overwrite
    @include('panel')

    {{-- Second Panel --}}
    @section('heading')
        Your Friends
    @overwrite
    @section('inner')
        <ul>
        @foreach($user->friends as $friend)
            <li>{{ $friend->name }}</li>
        @endforeach
        </ul>
    @overwrite
    @include('panel')

@stop
like image 100
Aken Roberts Avatar answered Sep 20 '22 22:09

Aken Roberts