Вид

Вид

После прочтения первой части этого туториала, вы решили, что Symfony стоит еще 10 минут. В этой второй части вы узнаете больше о Twig - быстром, гибком и безопасном шаблонизаторе для PHP-приложений. Twig делает ваши шаблоны более читаемыми и лаконичными; он также делает их более дружественными по отношению к веб-дизайнерам.

Знакомство с Twig

Официальная документация Twig - это лучший источник для изучения всего об этом шаблонизаторе. Этот раздел только даст вам быстрое понимание его главных концептов.

Щаблон Twig - это текстовый файл, который может создать любой вид содержания (HTML, CSS, JavaScript, XML, CSV, LaTeX, и т.д.). Элементы Twig отделяются от остального содержания шаблона посредоством использования этих разграничителей:

{{ ... }}
Печатает содержание переменной или результат оценки выражения;
{% ... %}
Контролирует логику шаблона; используется, например, для выполнения циклов for и выражений if.
{# ... #}
Позволяет включать комментарии в шаблонах. В отличие от HTML-комментариев, они не включены в отображенном шаблоне.

Ниже находится минимальный шаблой, который иллюстрирует некоторые базовые принципы, используя две переменные page_title и navigation, которые будут переданы в шаблон:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
    <head>
        <title>{{ page_title }}</title>
    </head>
    <body>
        <h1>{{ page_title }}</h1>

        <ul id="navigation">
            {% for item in navigation %}
                <li><a href="{{ item.url }}">{{ item.label }}</a></li>
            {% endfor %}
        </ul>
    </body>
</html>

Чтобы отобразить шаблон в Symfony, используйте метод render() из контроллера. Если шаблон требует переменных для генерирования его содержания, передайте их как массив, используя второй необязательный аргумент:

1
2
3
$this->render('default/index.html.twig', array(
    'variable_name' => 'variable_value',
));

Переменные, которые передаются в шаблон, могут быть строками, массивами или даже объектами. Twig асбтрагируется от разницы между ними и позволяет вам получить доступ к "атрибутам" переменной с помощью нотации точки (.). Следующий листинг кода показывает, как отображать содержание переменной, переданной контроллером, в зависимости от ее типа:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{# 1. Simple variables #}
{# $this->render('template.html.twig', array(
       'name' => 'Fabien')
   ) #}
{{ name }}

{# 2. Arrays #}
{# $this->render('template.html.twig', array(
       'user' => array('name' => 'Fabien'))
   ) #}
{{ user.name }}

{# alternative syntax for arrays #}
{{ user['name'] }}

{# 3. Objects #}
{# $this->render('template.html.twig', array(
       'user' => new User('Fabien'))
   ) #}
{{ user.name }}
{{ user.getName }}

{# alternative syntax for objects #}
{{ user.name() }}
{{ user.getName() }}

Украшение шаблонов

Обычно шаблоны в проекте имеют общие элементы, например известные заголовок и нижний колонтитул. Twig решает эту проблему элегантно, используя концепт под названием "наследование шаблонов". Это свойство позволяет вам построить базовый шаблон, содержащий все общие элементы вашего сайта, и определяет "блоки" содержания, которые дочерние шаблоны могут переопределять.

Шаблон index.html.twig использует тег extends, чтобы обозначить, что он наследует из шаблона base.html.twig:

1
2
3
4
5
6
{# app/Resources/views/default/index.html.twig #}
{% extends 'base.html.twig' %}

{% block body %}
    <h1>Welcome to Symfony!</h1>
{% endblock %}

Откройте файл app/Resources/views/base.html.twig, который соответствует шаблону base.html.twig, и вы найдете следующий код Twig:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>{% block title %}Welcome!{% endblock %}</title>
        {% block stylesheets %}{% endblock %}
        <link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}" />
    </head>
    <body>
        {% block body %}{% endblock %}
        {% block javascripts %}{% endblock %}
    </body>
</html>

Теги {% block %} говорят ядру шаблона, что дочерний шаблон может переопределить эти части шаблона. В этом примере, шаблон index.html.twig переопределяет блок body, но не блок, который будет отображать содержание по умолчанию, определенное в шаблоне base.html.twig.

Использование тегов, фильтров и функций

Одна из лучших особенностей Twig - это его расширяемость с помощью тегов, фильтров и функций. Посмотрите на следующий шаблон-пример, который активно использует фильтры, чтобы изменить информацию перед тем, как показать ее пользователю:

1
2
3
4
5
6
7
<h1>{{ article.title|capitalize }}</h1>

<p>{{ article.content|striptags|slice(0, 255) }} ...</p>

<p>Tags: {{ article.tags|sort|join(", ") }}</p>

<p>Activate your account before {{ 'next Monday'|date('M j, Y') }}</p>

Не забудьте посмотреть официальную `документацию Twig`_, чтобы узнать все о фильтрах, функциях и тегах.

Включение других шаблонов

Лучший способ сделать кусочек кода общим для нескольких шаблонов - это создать новый фрагмент шаблона, который потом можно включать из других шаблонов.

Представьте, что мы хотим отобразить рекламу на некоторых страницах нашего приложения. Для начала, создайте шаблон banner.html.twig:

1
2
3
4
{# app/Resources/views/ads/banner.html.twig #}
<div id="ad-banner">
    ...
</div>

Чтобы отобразить рекламу на любой странице, включите шаблон banner.html.twig, используя функцию include():

1
2
3
4
5
6
7
8
{# app/Resources/views/default/index.html.twig #}
{% extends 'base.html.twig' %}

{% block body %}
    <h1>Welcome to Symfony!</h1>

    {{ include('ads/banner.html.twig') }}
{% endblock %}

Внедрение других контроллеров

А что, если вы хотите внедрить результат другого контроллера в шаблон? Это очень удобно при работе с Ajax, или когда внедренный шаблон требует какую-либо переменную, недоступную в основном шаблоне.

Допустим, вы создали метод контроллера topArticlesAction() для отображения самых популярных статей вашего сайта. Если вы хотите "отобразить" результат этого метода (обычно некое HTML-содержание) внутри шаблона index, используйте функцию render():

1
2
{# app/Resources/views/index.html.twig #}
{{ render(controller('AppBundle:Default:topArticles')) }}

Здесь, функции render() и controller() используют специальный синтаксис для того, чтобы ссылаться на действие topArticlesAction() контроллера Default (часть AppBundle будет разъясняться позже):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// src/AppBundle/Controller/DefaultController.php
class DefaultController extends Controller
{
    public function topArticlesAction()
    {
        // искать наиболее популярные статьи в базе данных
        $articles = ...;

        return $this->render('default/top_articles.html.twig', array(
            'articles' => $articles,
        ));
    }

    // ...
}

Создание ссылок между страницами

Создание страниц между страницами обязательно для веб-приложений. Вместо того, чтобы жестко кодировать URL в шаблонах, функция path() знает, как сгенерировать URL на основании конфигурации маршрутизации. Таким образом, все ваши URL могут быть с легкостью обновлены посредством изменения конфигурации:

1
<a href="{{ path('homepage') }}">Return to homepage</a>

Функция path() берет имя маршрута в качестве первого аргумента и вы можете по желанию передать массив параметров маршрута в качестве второго аргумента.

Tip

Функция url() очень похожа на функцию path(), но она создает абсолютные URL, что очень удобно при отображении адресов почты и RSS-файлов: <a href="{{ url('homepage') }}">Посетите наш сайтe</a>.

Включение ресурса: изображения, Java-скрипты и таблицы стилей

Чем был бы интернет без изображений, Java-скриптов и таблиц стилей? Symfony предоставляет функцию asset() для того, чтобы легко с ними справиться:

1
2
3
<link href="{{ asset('css/blog.css') }}" rel="stylesheet" type="text/css" />

<img src="{{ asset('images/logo.png') }}" />

Функция asset() ищет веб-ресурсы внутри каталога web/. Если вы храните их в другом каталоге, читайте эту статью, чтобы узнать, как управлять веб-ресурсами.

С использованием функции asset(), ваше приложение становится более мобильным. Причиной этого является то, что вы можете переносить корневой каталог приложения в любое место под вашим корневым веб-каталогом, не изменяя ничего в вашем коде шаблона.

Заключение

Twig простой, но очень мощный. Блягодаря включение макетов, блоков, шаблонов и действий, очень просто распределить ваши шаблоны в логическом и расширяемом виде.

Вы работали с Symfony всего около 20 минут, но вы уже можете делать достаточно крутые штуки в ней. В этом заключается сила Symfony. Изучение основ легко, и вы скоро узнаете, что эта простота прячется под очень гибкой архитектурой.

Но я забегаю наперед. Для начала, вам нужно узнать больше о контроллере, и именно это является темой следующей части этого туториала. Готовы еще к 10 минутам Symfony?

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.