Русская документация Symfony2 на SymfonyGuru

Дата последнего обновления: 2012-05-20.

Вид

Прочитав первую часть, вы решили что Symfony2 заслуживает ещё 10 минут. Хорошо. Во второй части вы узнаете больше о движке шаблонов Twig в Symfony2. Twig это гибкий, быстрый и безопасный шаблонизатор для PHP. Он делает шаблоны удобочитаемыми и выразительными, а также более дружественными для web дизайнеров.

Примечание

Вместо Twig, можете использовать для шаблонов PHP. Оба шаблонных движка поддерживаются Symfony2 и имееют одинаковую степень поддержки.

Twig, краткий обзор

Совет

Если хотите изучить Twig, мы настоятельно рекомендуем прочесть эту официальную документацию. Этот раздел лишь кратко описывает основные концепты.

Шаблон Twig это текстовый файл, который может генерировать любой формат, основанный на тексте (HTML, XML, CSV, LaTeX, ...). Twig устанавливает два вида разделителей:

  • {{ ... }}: Выводит переменную или результат выражения в шаблон;
  • {% ... %}: Тег, управляющий логикой шаблона; например, используется для выполнения for циклов или if условий.

Ниже приведён минимальный шаблон, иллюстрирующий несколько основных правил:

<!DOCTYPE html>
<html>
    <head>
        <title>My Webpage</title>
    </head>
    <body>
        <h1>{{ page_title }}</h1>

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

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

{# array('name' => 'Fabien') #}
{{ name }}

{# array('user' => array('name' => 'Fabien')) #}
{{ user.name }}

{# force array lookup #}
{{ user['name'] }}

{# array('user' => new User('Fabien')) #}
{{ user.name }}
{{ user.getName }}

{# force method name lookup #}
{{ user.name() }}
{{ user.getName() }}

{# pass arguments to a method #}
{{ user.date('Y-m-d') }}

Примечание

Важно знать что фигурные скобки это не часть переменной, а оператор печати. Если вы используете переменные внутри тегов, не ставьте скобки вокруг них.

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

Часто шаблоны в проекте разделяют общие элементы, такие как всем известные header и footer. В Symfony2, мы смотрим на эту проблему иначе: один шаблон может быть декорирован другим. Это похоже на классы в PHP: наследование шаблона позволяет создать его базовый “макет”, содержащий общие элементы вашего сайта и устанавливающий “блоки”, которые могут быть переопределены дочерними шаблонами.

Шаблон index.twig.html наследуется от layout.twig.html, спасибо тегу extends:

{# src/Application/HelloBundle/Resources/views/Hello/index.twig.html #}
{% extends "HelloBundle::layout.twig.html" %}

{% block content %}
    Hello {{ name }}!
{% endblock %}

Обозначение HelloBundle::layout.twig.html выглядит знакомо, не так ли? Обозначается так же как ссылка на обычный шаблон. Эта часть :: всего лишь обозначает что контроллер не указан, т. о. соотвествующий файл хранится прямо в views/.

Рассмотрим файл layout.twig.html:

{% extends "::base.twig.html" %}

{% block body %}
    <h1>Hello Application</h1>

    {% block content %}{% endblock %}
{% endblock %}

Тег {% block %} устанавливает два блока (body и content), которые дочерние шаблоны смогут заполнить. Всё что делает этот тег, это сообщает движку шаблонов, что дочерний шаблон может переопределить эти участки. Шаблон index.twig.html переопределяет блок content, который указан в базовом макете, как если бы наш макет сам по себе был декорирован оным. Когда бандл в имени шаблона не указан (::base.twig.html), то виды ищутся в папке app/views/. Эта папка хранит глобальные виды для всего проекта:

{# app/views/base.twig.html #}
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>{% block title %}Hello Application{% endblock %}</title>
    </head>
    <body>
        {% block body '' %}
    </body>
</html>

Теги, фильтры и функции

Одна из лучших особенностей Twig его расширяемость через теги, фильтры и функции; Многие из них поставляется вместе с Symfony2, облегчая работу web дизайнера.

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

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

Создайте шаблон hello.twig.html:

{# src/Application/HelloBundle/Resources/views/Hello/hello.twig.html #}
Hello {{ name }}

Измените шаблон index.twig.html таким образом, чтобы подключить его:

{# src/Application/HelloBundle/Resources/views/Hello/index.twig.html #}
{% extends "HelloBundle::layout.twig.html" %}

{# override the body block from index.twig.html #}
{% block body %}
    {% include "HelloBundle:Hello:hello.twig.html" %}
{% endblock %}

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

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

Если вы создали действие fancy и хотите включить его в шаблон index, используйте тег render:

{# src/Application/HelloBundle/Resources/views/Hello/index.twig.html #}
{% render "HelloBundle:Hello:fancy" with { 'name': name, 'color': 'green' } %}

Имеем строку HelloBundle:Hello:fancy, обращающуюся к действию fancy контроллера Hello и аргумент, используемый для имитирования запроса для заданного пути:

// src/Application/HelloBundle/Controller/HelloController.php

class HelloController extends Controller
{
    public function fancyAction($name, $color)
    {
        // create some object, based on the $color variable
        $object = ...;

        return $this->render('HelloBundle:Hello:fancy.twig.html', array('name' => $name, 'object' => $object));
    }

    // ...
}

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

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

<a href="{{ path('hello', { 'name': 'Thomas' }) }}">Greet Thomas!</a>

Функция path использует имя маршрута и массив параметров как аргументы. Имя маршрута это основа, в соотвествии с которой выбираются маршруты, а параметры это значения заполнителей, объявленных в паттерне маршрута:

# src/Application/HelloBundle/Resources/config/routing.yml
hello: # The route name
    pattern:  /hello/{name}
    defaults: { _controller: HelloBundle:Hello:index }

Совет

Функция url создает абсолютные URL-ы: {{ url('hello', { 'name': 'Thomas' }) }}.

Подключение активов: изображений, JavaScript-ов и таблиц стилей

Как выглядел бы интернет без изображений, JavaScript-ов и таблиц стилей? Symfony2 предлагает функцию asset для работы с ними:

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

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

Основная цель функции asset сделать приложение более переносимым. Благодаря ей, можно переместить корневую папку приложения куда угодно внутри вашей корневой web директории без изменения шаблона.

Экранирование вывода

Изначально Twig настроен экранировать весь вывод. Прочтите Twig documentation чтобы узнать больше об экранировании и расширении Escaper.

Заключительное слово

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

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

Я немного поспешил. Во-первых, вы должны узнать больше о контроллере, именно он станет темой следующей части учебника. Готовы к следующим 10 минутам с Symfony2?