Laravel Blade - Цепочка/Вставка нескольких макетов

В моих любимых фреймворках шаблонов они, как правило, имеют возможность размещать макеты. Возможно ли это в Blade?

Например...

master.blade.php

<html>
  <head><!-- stuff --></head>
  <body>
    @yield('content')
  </body>
</html>

nav.blade.php

@extend('master')
<nav>
    <!-- nav content -->
</nav>
@yeild('content')

breadcrumb.blade.php

@extend('nav')
<breadcrumb>
    <!-- breadcrumb content -->
</breadcrumb>
@yield('content')

home.blade.php

@extend('nav')
@section('content')
    <home>
        <!-- content -->
    </home>
@endsection

about.blade.php

@extend('breadcrumb')
@section('content')
    <about>
        <!-- content -->
    </about>
@endsection

Причина, по которой мне нравится этот формат, заключается в том, что он чрезвычайно элегантен (IMO), чтобы иметь возможность выбирать точку инъекции!

  • У вас есть одна целевая страница... reference master
  • Для главной страницы... ссылка nav
  • Для любых подстраниц (about/nav/product) ссылка breadcrumb

Каскад макетов и 'content' восстанавливается с помощью скомпилированного html по мере его продвижения по дереву.

Возможно ли это? Я надеюсь избежать использования @include в макетах, поскольку я лично считаю их громоздкими и немного озорными, особенно когда вы получаете элементы, которые повторяются часто, но не везде (панировочные сухари).

EDIT: на основе ответов.

В идеале 'content' будет перестроен и пройден цепочку вложенных макетов. Если у вас есть домашняя страница, которая ссылается на nav.blade.php, содержимое главной страницы добавляется в макет и компилируется. Затем, так как расположение макета навигации master.blade.php, скомпилированный макет будет передан до master и снова создан. Нет дублирования какого-либо контента.

Ответ 1

Вы забыли использовать @parent. Вот пример:


master.blade.php

<html>
  <head>
    {{-- Stuff --}}
  </head>
  <body>
    @yield('content')
  </body>
</html>

nav.blade.php

Вам нужно поместить nav внутрь section, чтобы сообщить макет master, что это содержимое. Если вы этого не сделаете, nav будет в верхней части макета master (да, вне html).

@extends('master')

@section('content')
  <nav>
    <p>nav content</p>
  </nav>
@endsection

home.blade.php

В этом примере раздел content использует директиву @parent для добавления (а не перезаписи) содержимого на боковую панель макета. Директива @parent будет заменена содержимым макета при визуализации представления.

@extends('nav')

@section('content')
  {{-- You can control where @parent should be rendered --}}
  @parent

  <home>
    <p>home content</p>
  </home>

  {{-- You can put your @parent here, give it a try --}}
@endsection

breadcrumb.blade.php

@extends('nav')

@section('content')
  {{-- You can control where @parent should be rendered --}}
  @parent

  <breadcrumb>
    <p>breadcrumb content</p>
  </breadcrumb>

  {{-- You can put your @parent here, give it a try --}}
@endsection

about.blade.php

@extends('breadcrumb')

@section('content')
  {{-- You can control where @parent should be rendered --}}
  @parent

  <about>
    <p>about content</p>
  </about>

  {{-- You can put your @parent here, give it a try --}}
@endsection

Рендеринг:

home.blade.php

<html>
<head>
</head>
<body>
  <nav>
    <p>nav content</p>
  </nav>
  <home>
    <p>home content</p>
  </home>
</body>
</html>

about.blade.php

<html>
<head>
</head>
<body>
  <nav>
    <p>nav content</p>
  </nav>
  <breadcrumb>
    <p>breadcrumb content</p>
  </breadcrumb>
  <about>
    <p>about content</p>
  </about>
</body>
</html>

Ответ 2

Я не уверен, что понимаю, что ты здесь. Например, в home.blade.php вы расширяете "nav", что, в свою очередь, расширяет "master", но оба "master" и "nav" дают content, поэтому контент <home> будет отображаться дважды.

Итак, каков ваш ожидаемый результат? Я не уверен, что "домашний" или "о" должен действительно extend "nav" или "breadcrumb". Я думаю об этих двух как о структурных компоновках компоновки, поэтому для меня имеет смысл include их в макете макета. В "nav" вы можете определить раздел для расширения, когда вашему представлению нужна сводка.

Например:

master.blade.php

<html>
<head><!-- stuff --></head>
  <body>
    @include('nav')        
    @yield('content')
  </body>
</html>

nav.blade.php

<nav>
  <!-- nav content -->
  @yield('breadcrumb')
</nav>

home.blade.php

@extend('master')

@section('content')
  <home>
    <!-- content -->
  </home>
@endsection

about.blade.php

@extend('master')

@section('breadcrumb')
  <breadcrumb>
    <!-- breadcrumb content -->
  </breadcrumb>
@endsection

@section('content')
  <about>
    <!-- content -->
  </about>
@endsection