Два основных преимущества использования Blade — наследование шаблонов и секции. Поскольку многие веб-приложения используют один общий макет для разных страниц, удобно определить этот макет как один layout-шаблон.
В реальных проектах шаблоны состоят из частей, что упрощает процесс разработки. К примеру, представьте что существует страница проекта:
<!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
, которая тоже включает представления, но перед этим проверяет файлы на существование. Если файлов нет, то включения представления не произойдёт. Но запрос будет выполнен без ошибок.