Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Макет и ссылки в шаблонах

У всех страниц сайта общие части: заголовок документа, меню, подвал. Чтобы не повторять их в каждом шаблоне, общую разметку выносят в макет (layout) — базовый шаблон с «окнами», которые заполняют отдельные страницы.

Макет

Создайте файл templates/layout.twig:

{# templates/layout.twig #}
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <title>{% block title %}Блог{% endblock %}</title>
</head>
<body>
    <main>{% block content %}{% endblock %}</main>
</body>
</html>

block — именованное окно. У блока title есть содержимое по умолчанию, блок content пуст.

Страница на основе макета

Перепишите шаблон главной страницы:

{# templates/home.twig #}
{% extends 'layout.twig' %}
 
{% block title %}{{ title }}{% endblock %}
 
{% block content %}
    <h1>{{ title }}</h1>
    <p>Сайт работает на Slim.</p>
{% endblock %}

Строка extends сообщает, какой макет взять, а блоки заполняют его окна. Действие менять не нужно: оно по-прежнему выводит home.twig. Откройте главную страницу и посмотрите её исходный код — в нём появилась полная разметка документа.

Ссылки по именам маршрутов

Пакет slim/twig-view добавляет в шаблоны функцию url_for() — она строит адрес по имени маршрута, как urlFor() в коде. Добавьте в макет меню перед тегом main:

{# templates/layout.twig #}
<nav>
    <a href="{{ url_for('home') }}">Главная</a>
    <a href="{{ url_for('posts.index') }}">Статьи</a>
</nav>

Меню появится на всех страницах, которые наследуют макет. Параметры адреса передают вторым аргументом:

{# templates/posts/index.twig #}
{% extends 'layout.twig' %}
 
{% block content %}
    <h1>Статьи</h1>
 
    {% for post in posts %}
        <p><a href="{{ url_for('posts.show', {id: post.id}) }}">{{ post.title }}</a></p>
    {% endfor %}
{% endblock %}

Каждый заголовок станет ссылкой вида /posts/1.

ФункцияЧто возвращает
url_for('posts.show', {id: 5})Адрес по имени маршрута
full_url_for('posts.show', {id: 5})То же с именем сайта
current_url()Адрес текущей страницы
is_current_url('posts.index')Совпадает ли текущий адрес с маршрутом

Общие данные

Значение, нужное во всех шаблонах, например имя сайта из настроек, добавляют один раз — там, где создаётся Twig:

// config/container.php
use Psr\Container\ContainerInterface;
use Slim\Views\Twig;
 
Twig::class => function (ContainerInterface $c) {
    $twig = Twig::create(__DIR__ . '/../templates', ['cache' => false]);
 
    $twig->getEnvironment()->addGlobal('site_name', $c->get('settings')['site_name']);
 
    return $twig;
},

Теперь в любом шаблоне доступна переменная site_name: замените слово «Блог» в блоке title макета на {{ site_name }}.

Шаблоны на PHP

Если отдельный язык шаблонов не нужен, есть пакет slim/php-view: шаблоны в нём — обычные файлы PHP. Обезвреживать вывод там приходится вручную функцией htmlspecialchars(), поэтому в курсе используется Twig.

Частая ошибка

В шаблоне с extends всё, что написано вне блоков, вызывает ошибку Twig: дочерний шаблон может только заполнять блоки макета. Если страница пустая или падает после добавления extends, проверьте, что вся разметка находится внутри block content.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.