Русская документация Symfony2 на SymfonyGuru
Дата последнего обновления: 2012-05-20.
Дата последнего обновления: 2012-05-20.
Прочитав первую часть, вы решили что Symfony2 заслуживает ещё 10 минут. Хорошо. Во второй части вы узнаете больше о движке шаблонов Twig в Symfony2. Twig это гибкий, быстрый и безопасный шаблонизатор для PHP. Он делает шаблоны удобочитаемыми и выразительными, а также более дружественными для web дизайнеров.
Примечание
Вместо Twig, можете использовать для шаблонов PHP. Оба шаблонных движка поддерживаются Symfony2 и имееют одинаковую степень поддержки.
Совет
Если хотите изучить Twig, мы настоятельно рекомендуем прочесть эту официальную документацию. Этот раздел лишь кратко описывает основные концепты.
Шаблон Twig это текстовый файл, который может генерировать любой формат, основанный на тексте (HTML, XML, CSV, LaTeX, ...). Twig устанавливает два вида разделителей:
Ниже приведён минимальный шаблон, иллюстрирующий несколько основных правил:
<!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-ов и таблиц стилей? 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?