<!DOCTYPE html>
<html>
<head>
<title>Заголовок страницы</title>
</head>
<body>
<header>
Шапка сайта
</header>
<sidebar>
Боковое меню
</sidebar>
<content>
Контент сайта
</content>
<footer>
Подвал сайта
</footer>
</body>
</html>
В таком шаблоне можно сразу выделить три части: шапку, подвал, боковое меню и контент. Из них только контентная часть "контент" (и иногда боковое меню) будет отличаться для разных страниц сайта. Шапка и подвал для большинства страниц сайта будут неизменными. Поэтому логично выделить контент и боковое меню в отдельные файлы. Делается это с помощью механизма наследования шаблонов с помощью директив @section и @yield.Директива @section определяет участок кода, куда будет выводиться содержимое. Благодаря чему дочерняя страница, которая наследуюет макет, сможет сама выбирать что делать с содержимым области (об этом рассказывается далее с директивой @parent).
А @yield указывает на точное место, куда будет вставлена информация.
Попробуем сделать пример макета, который можно унаследовать:
<!DOCTYPE html>
<html>
<head>
<title>@yield('title')</title>
</head>
<body>
@section('sidebar')
Боковое меню
@show
<content>
@yield('content')
</content>
</body>
</html>
Этот код поместим в файл resources/views/layouts/app.blade.php
. И сделаем дочерний макет, который унаследует его. Для этого создадим файл resources/views/child.blade.php
и внутри него первой строкой напишем директиву @extends('layouts.app')
, которая указывает на наследуемый макет:
@extends('layouts.app')
@section('title', 'Заголовок страницы')
@section('sidebar')
@parent
<div>
Содержание бокового меню раздела
</div>
@show
@section('content')
<div>
Содержание страницы
</div>
@show
Обратите внимание на директиву @parent. Благодаря ей можно не польностью перезаписать существующее содержание секции, а добавить к нему содержимое. То есть @parent будет заменена содержимым макета при отрисовке представления.Подобные дочерние представления могут быть вызваны из маршрутов с помощью функции view, которой в аргумент нужно передать название представления. В нашем случае получится так:
<?php
Route::get('/', function () {
return view('child');
});
?>
Включение подшаблонов
Директива @include позволяет включить представление в другое представление. При этом все переменные из родительского становятся доступны дочернему.<!DOCTYPE html>
<html>
<head>
<title>@include('title')</title>
</head>
<body>
@include('view.name')
@section('sidebar')
Боковое меню
@show
<content>
@yield('content')
</content>
</body>
</html>
Из родительского представления можно передать дополнительные данные в дочерний. Делается это в виде массива, который передаётся вторым аргументом директиве @include:
@include('view.name', ['key' => 'value'])
Если сделать @include представления, которого не существует, то Laravel выдаст ошибку. Чтобы этого не происходило используйте директиву @includeIf, которая тоже включает представления, но перед этим проверяет файлы на существование. Если файлов нет, то включения представления не произойдёт. Но запрос будет выполнен без ошибок.