Создание и использование шаблонов¶
Как уже было написано в предыдущей статьe, контроллеры отвечают за обработку каждого запроса, который поступает в приложение Symfony, и обычно заканчивают отображением шаблона для генерирования содержимого ответа
На самом деле, контроллер передает большую часть трудоемких операций другим частям фреймворка, чтобы код можно было тестировать и повторно использовать. Когда контроллеру необходимо создать HTML, CSS или любой другой контент, он передает эту работу шаблонизатору.
В этой статье вы научитесь писать мощные шаблоны, которые можно использовать для возвращения контента пользователю, создания тела имейлов и многого другого. Также вы научитесь использовать шорткаты, узнаете хитрые способы наследования шаблонов и повторного использования кода шаблона.
Шаблоны¶
Шаблон - это обычный текстовый файл, который может генерировать любой формат, который основывается на тексте (HTML, XML, CSV, LaTeX и др.). Самый известный тип шаблона это PHP шаблон - текстовый файл, который обрабатывается PHP и содержит как текст, так и PHP-код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!DOCTYPE html>
<html>
<head>
<title>Welcome to Symfony!</title>
</head>
<body>
<h1><?php echo $page_title ?></h1>
<ul id="navigation">
<?php foreach ($navigation as $item): ?>
<li>
<a href="<?php echo $item->getHref() ?>">
<?php echo $item->getCaption() ?>
</a>
</li>
<?php endforeach ?>
</ul>
</body>
</html>
|
Преимущество Symfony в том, что в ёё состав входит еще более мощный язык шаблонов, который называется Twig. С помощью Twig вы можете писать лаконичные и читабельные шаблоны, которые удобнее в использовании для веб-дизайнеров, не говоря уже о том, что этот шаблон во многих случаях функциональнее чем PHP шаблоны:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!DOCTYPE html>
<html>
<head>
<title>Welcome to Symfony!</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 содержит три типа специальных синтаксических конструкций:
{{ ... }}
- “Что-то сказать”: печатает переменную или результат какого-то выражения в шаблоне.
{% ... %}
- “Что-то выполнить”: тег (tag), который контролирует логику шаблона; используется для выполнения таких выражений, как например, циклы for-loops.
{# ... #}
- “Что-то прокомментировать”: это эквивалент синтаксису PHP
/* comment */
. Этот синтаксис используется для добавления одно- или многострочных комментариев. Содержимое комментария не включается в отображаемые страницы.
Twig также содержит фильтры, которые изменяют контент перед тем, как его
отобразить. Следующий фильтр позволяет перевести переменную title
в верхний
регистр перед тем, как отобразить ее:
1 | {{ title|upper }}
|
Twig по умолчанию содержит много тегов (tags), фильтров (filters) и функций (functions), которые доступны по умолчанию. Вы даже можете добавлять свои собственные расширения в Twig с помощью Расширения Twig.
Код Twig будет выглядеть схоже с PHP-кодом, с некоторыми маленькими, но приятными
различиями. Следующий пример использует стандартный тег for
и функцию cycle()
для отображения десяти тегов div с переменными классами odd
и even
:
1 2 3 4 5 | {% for i in 1..10 %}
<div class="{{ cycle(['even', 'odd'], i) }}">
<!-- some HTML here -->
</div>
{% endfor %}
|
На протяжении этой статьи, примеры шаблонов будут показаны как в Twig так и на PHP.
Кеширование шаблонов в Twig¶
Twig быстр, так как каждый шаблон компилируется в обычный PHP класс, который отображается во время выполнения. Но не волнуйтесь: это происходит автоматически, и*вам* не нужно ничего для этого делать. И в то время, как вы будете программировать, Twig настолько умен, что он будет рекмопилировать ваши шаблоны после любого внесенного изменения. Это значит, что Twig быстр в производстве, но легок в использовании при программировании.
Наследование шаблонов и макетов страницы (layouts)¶
Зачастую у шаблонов в проекте есть общие элементы, такие как “заголовок” (header), “подвал” (footer), боковые панели (sidebar) и т.п. В Symfony эта задача решается по-другому: шаблон может быть оформлен с помощью другого шаблона. Принцип работы здесь точно такой же, как с PHP-классами: наследование шаблонов позволяет вам выстроить базовый шаблон “макета страницы” (layout template), который содержит все необходимые вам общие элементы сайта, которые еще называют блоками (аналогично с “PHP-классом с базовыми методами”). Дочерний шаблон можно расширить по сравнению с базовым, а также можно переопределять любые его блоки (аналогично с “дочерним PHP-классом, который переопределяет некоторые методы родительского класса”).
Для начала создайте файл базового макета страницы:
- Twig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
{# app/Resources/views/base.html.twig #} <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{% block title %}Test Application{% endblock %}</title> </head> <body> <div id="sidebar"> {% block sidebar %} <ul> <li><a href="/">Home</a></li> <li><a href="/blog">Blog</a></li> </ul> {% endblock %} </div> <div id="content"> {% block body %}{% endblock %} </div> </body> </html>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
<!-- app/Resources/views/base.html.php --> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title><?php $view['slots']->output('title', 'Test Application') ?></title> </head> <body> <div id="sidebar"> <?php if ($view['slots']->has('sidebar')): ?> <?php $view['slots']->output('sidebar') ?> <?php else: ?> <ul> <li><a href="/">Home</a></li> <li><a href="/blog">Blog</a></li> </ul> <?php endif ?> </div> <div id="content"> <?php $view['slots']->output('body') ?> </div> </body> </html>
Note
Несмотря на то, что обсуждение наследования шаблонов будет вестись применительно к Twig, в Twig и PHP-шаблонах используется одна и та же философия.
Этот шаблон определяет базовый костяк HTML-документа для простой страницы с двумя колонками.
В данном примере определены три области {% block %}
(title
, sidebar
и body
).
Каждый блок может быть переопределен дочерним шаблоном или оставлен с реализацией по умолчанию.
Также этот шаблон можно отобразить напрямую. В таком случае блоки title
, sidebar
и
body
просто сохранят свои значения по умолчанию, использованные в этом шаблоне.
Дочерний шаблон может выглядеть, например, так:
- Twig
1 2 3 4 5 6 7 8 9 10 11
{# app/Resources/views/blog/index.html.twig #} {% extends 'base.html.twig' %} {% block title %}My cool blog posts{% endblock %} {% block body %} {% for entry in blog_entries %} <h2>{{ entry.title }}</h2> <p>{{ entry.body }}</p> {% endfor %} {% endblock %}
- PHP
1 2 3 4 5 6 7 8 9 10 11
<!-- app/Resources/views/blog/index.html.php --> <?php $view->extend('base.html.php') ?> <?php $view['slots']->set('title', 'My cool blog posts') ?> <?php $view['slots']->start('body') ?> <?php foreach ($blog_entries as $entry): ?> <h2><?php echo $entry->getTitle() ?></h2> <p><?php echo $entry->getBody() ?></p> <?php endforeach ?> <?php $view['slots']->stop() ?>
Note
Родительский шаблон определяется благодаря специальному синтаксису строковой
последовательности (base.html.twig
). Этот путь относится к каталогу
проекта``app/Resources/views``. Вы также можете использовать эквивалент
логического имени ::base.html.twig
. Такое соглашение о присвоении имен
полностью объясняется в разделе Правила именования и расположения шаблонов template-naming-locations.
Ключ к наследованию шаблонов - это тег {% extends %}
. Он сообщает движку
шаблонизатора, что сначала необходимо выполнить базовый шаблон, который настроит
общую разметку и определит несколько блоков. После этого начинает отображаться
дочерний шаблон, при этом блоки родителя``title`` и body
замещаются аналогичными
блоками потомка. В зависимости от значения переменной blog_entries
, результат может
выглядеть так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My cool blog posts</title>
</head>
<body>
<div id="sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</div>
<div id="content">
<h2>My first post</h2>
<p>The body of the first post.</p>
<h2>Another post</h2>
<p>The body of the second post.</p>
</div>
</body>
</html>
|
Обратите внимание, что дочерний шаблон не определяет блок sidebar
, вместо
этого используется значение из родительского шаблона. Содержимое тега {% block %}
в родительском шаблоне всегда используется по умолчанию.
Tip
Вы можете использовать столько уровней наследования, сколько вам потребуется. См. Наследование шаблонов для более детальной информации.
Когда вы работаете с наследованием шаблона нужно следовать нескольким правилам:
Если вы используете в шаблоне тег
{% extends %}
, он должен быть первым тегом в этом шаблоне;Чем больше тегов
{% block %}
в вашем базовом шаблоне, тем лучше. Запомните, дочерний шаблон не обязательно реализовывает все блоки родительского шаблона, так что создавайте необходимое количество блоков в вашем базовом шаблоне и указывайте для них разумный контент по умолчанию. Чем больше блоков будет в вашем базовом шаблоне, тем гибче будет макет вашей страницы;Если вы обнаружите повторяющийся контент в нескольких шаблонах, скорее всего это значит, что вам нужно переместить этот контент в тег
{% block %}
родительского шаблона. В некоторых случаях лучшим решением будет переместить содержимое на новый шаблон иinclude
его (см. Подключение других шаблонов including-templates );Если вам нужно содержимое блока из родительского шаблона, вы можете использовать функцию
{{ parent() }}
. Это удобно, если вам надо добавить что-то к содержанию родительского блока, а не полностью заменить его:1 2 3 4 5 6 7
{% block sidebar %} <h3>Table of Contents</h3> {# ... #} {{ parent() }} {% endblock %}
Правила именования и расположения шаблонов¶
По умолчанию, шаблоны могут располагаться в двух различных местах:
app/Resources/views/
- Каталог приложения
views
может содержать общие для всего приложения шаблоны (например, макет страницы вашего приложения и шаблоны пакета приложения), также как и шаблоны, которые переопределяют сторонние шаблоны пакетов (см.Переопределение шаблонов пакетов
). vendor/path/to/CoolBundle/Resources/views/
- Каждый сторонний пакет содержит свои шаблоны в каталоге
Resources/views/
(и ее подкаталогах). Когда вы захотите поделиться (share) своим пакетом, вам стоит расположить шаблоны внутри пакета, а не в каталогеapp/
.
Большинство шаблонов, которые вы будете использовать, располагаются в каталоге a
app/Resources/views/
. Путь, который вы будете использовать, будет родственным
этому каталогу. Для примера, чтобы отобразить/наследовать app/Resources/views/base.html.twig
,
вам нужно будет использовать путь base.html.twig
. А чтобы отобразить/наследовать
app/Resources/views/blog/index.html.twig
, вам нужно будет использовать путь
blog/index.html.twig
.
Отсылка к шаблонам внутри пакета¶
Если вам нужно сослаться на шаблон, который находится в пакете, Symfony использует специальный синтаксис строковой последовательности bundle:directory:filename. Это предусматривает несколько типов шаблонов, каждый из которых расположен в определенном месте:
AcmeBlogBundle:Blog:index.html.twig
: Эта форма записи для того, чтобы определить шаблон для конкретной страницы. Три части синтаксиса, каждая из которых отделяется двоеточием (:
), означают следующее:AcmeBlogBundle
: (пакет) шаблон расположен внутри пакета AcmeBlogBundle (например,src/Acme/BlogBundle
);Blog
: (каталог) указывает, что шаблон расположен внутри подкаталогаBlog
каталогаResources/views
;index.html.twig
: (имя файла) собственно имя файла этоindex.html.twig
.
При условии, что AcmeBlogBundle расположен в
src/Acme/BlogBundle
, полный путь к макету страницы будетsrc/Acme/BlogBundle/Resources/views/Blog/index.html.twig
.AcmeBlogBundle::layout.html.twig
: Этот синтаксис отсылает нас к базовому шаблону для определенного пакета AcmeBlogBundle. Поскольку в середине отсутствует наименование “каталога” (например,Blog
), шаблон находится в каталогеResources/views/layout.html.twig
пакета AcmeBlogBundle. Да, вам не показалось - внутри синтаксиса два двоеточия, как раз в том месте, где отсутствует подкаталог “контроллер”.
В разделе Переопределение шаблонов пакетов
вы узнаете,
как любой шаблон, который, для примера, находится в пакете AcmeBlogBundle, можно
переопределить путем размещения шаблона с тем же именем в каталоге
app/Resources/AcmeBlogBundle/views/
. Это дает возможность переопределять шаблоны
из любого стороннего пакета.
Tip
Надеемся, что синтаксис именования шаблонов оказался вам знаком - такое же соглашение об именовании используется и для контроллеров (см. Шаблон именования контроллера controller-string-syntax).
Суффиксы шаблонов¶
У каждого имени шаблона есть два расширения, которые указывают на формат и тип дивжок (engine) для этого шаблона.
Имя файла | Формат | Движок |
---|---|---|
blog/index.html.twig |
HTML | Twig |
blog/index.html.php |
HTML | PHP |
blog/index.css.twig |
CSS | Twig |
По умолчанию любой шаблон в Symfony может быть написан либо на Twig, либо на PHP.
Последняя часть расширения (например, .twig
или .php
) указывает, какой из
этих двух движков будет использован. Первая часть расширения (например, .html
,
.css
, и т.д.) это конечный формат, который будет генерировать шаблон. В отличие
от типа шаблонизатора, который определяет, как Symfony будет анализировать шаблон,
указание формата это всего лишь способ организации шаблонов, на тот случай, если один
и тот же ресурс можно отобразить и как HTML (index.html.twig
), и как XML
(index.xml.twig
) и в любом другом формате. Дополнительная информация содержится
в разделе Форматы шаблонов.
Теги и Помощники¶
Вы уже разбираетесь в основах создания шаблонов, способах именования и наследования шаблонов. Самое сложное уже позади. В этом разделе вы узнаете о множестве инструментов, которые помогают выполнить типичные задачи при работе с шаблонами, например, такие как подключение других шаблонов, создание ссылок на страницу и вставка изображений.
Symfony содержит несколько специализированных тегов и функций Twig, которые упрощают работу дизайнера шаблонов. В PHP шаблонизатор предоставляет расширяемую систему помощников, которая предоставляет полезные функции в контексте шаблонов.
Вы уже видели несколько встроенных в Twig тегов ({% block %}
и {% extends %}
),
а также пример PHP-хелпера ($view['slots']
). Теперь вы узнаете и о некоторых других.
Подключение других шаблонов¶
У вас часто будет возникать потребность подключить один и тот же шаблон или фрагмент кода для нескольких страниц. Например, в приложении с «новыми статьями», код шаблона, отображающий статью, может быть использован на странице детальной информации о статье, на странице, отображающей наиболее популярные статьи или же на странице со списком последних статей.
Когда вам необходимо использовать некую часть PHP-кода повторно, вы переносите этот код в новый PHP-класс или в функцию. То же верно и для шаблонов. Переместив повторно используемый код шаблона в собственный шаблон, он впоследствии может быть подключен к любому другому шаблону. Сначала создайте шаблон, который хотите использовать многократно.
- Twig
1 2 3 4 5 6 7
{# app/Resources/views/article/article_details.html.twig #} <h2>{{ article.title }}</h2> <h3 class="byline">by {{ article.authorName }}</h3> <p> {{ article.body }} </p>
- PHP
1 2 3 4 5 6 7
<!-- app/Resources/views/article/article_details.html.php --> <h2><?php echo $article->getTitle() ?></h2> <h3 class="byline">by <?php echo $article->getAuthorName() ?></h3> <p> <?php echo $article->getBody() ?> </p>
Подключить этот шаблон к любому другому несложно:
- Twig
1 2 3 4 5 6 7 8 9 10
{# app/Resources/views/article/list.html.twig #} {% extends 'layout.html.twig' %} {% block body %} <h1>Recent Articles<h1> {% for article in articles %} {{ include('article/article_details.html.twig', { 'article': article }) }} {% endfor %} {% endblock %}
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13
<!-- app/Resources/article/list.html.php --> <?php $view->extend('layout.html.php') ?> <?php $view['slots']->start('body') ?> <h1>Recent Articles</h1> <?php foreach ($articles as $article): ?> <?php echo $view->render( 'Article/article_details.html.php', array('article' => $article) ) ?> <?php endforeach ?> <?php $view['slots']->stop() ?>
Шаблон подключается при помощи функции {{ include() }}
. Обратите внимание,
что имя шаблона следует типовым конвенциям об именовании. Шаблон
article_details.html.twig
использует переменную article
, которую вы
передаете в него. В этом случае, вы можете полностью избежать этого, так как все
переменные, доступные в list.html.twig
также доступны в article_details.html.twig
(если только вы не установили with_context в значение false).
Tip
Синтаксис {'article': article}
- это стандартный синтаксис для хэшей
(т.е. массивов с названными ключами) в Twig. Если вам нужно передать много
элементов, массив будет выглядеть следующим образом: {'foo': foo, 'bar': bar}
.
Ссылки на страницы¶
Создание ссылок на другие страницы в вашем приложении - это одна из типичных
операций в шаблоне. Вместо того, чтобы хардкодить URL в шаблоне, используйте Twig-функцию
path
(в PHP-помощьник router
) для создания URL, основанных на конфигурации
маршрутизатора. Потом, если вы захотите изменить URL конкретной страницы, вам
всего лишь потребуется изменить конфигурацию маршрутизатора. Шаблоны автоматически
сгенерируют новый URL.
Сначала создайте ссылку на страницу "welcome", которая определяется следующей конфигураций маршрутизатора:
- Annotations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/AppBundle/Controller/WelcomeController.php // ... use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; class WelcomeController extends Controller { /** * @Route("/", name="welcome") */ public function indexAction() { // ... } }
- YAML
1 2 3 4
# app/config/routing.yml welcome: path: / defaults: { _controller: AppBundle:Welcome:index }
- XML
1 2 3 4 5 6 7 8 9 10 11
<!-- app/config/routing.yml --> <?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="http://symfony.com/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> <route id="welcome" path="/"> <default key="_controller">AppBundle:Welcome:index</default> </route> </routes>
- PHP
1 2 3 4 5 6 7 8 9 10
// app/config/routing.php use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; $collection = new RouteCollection(); $collection->add('welcome', new Route('/', array( '_controller' => 'AppBundle:Welcome:index', ))); return $collection;
Для создания ссылки на страницу просто используйте функцию path()
и сошлитесь на маршрут:
- Twig
1
<a href="{{ path('welcome') }}">Home</a>
- PHP
1
<a href="<?php echo $view['router']->path('welcome') ?>">Home</a>
Как и ожидалось, это сгенерирует URL /
. Давайте теперь посмотрим, как это
работает для более сложных маршрутов:
- Annotations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/AppBundle/Controller/ArticleController.php // ... use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; class ArticleController extends Controller { /** * @Route("/article/{slug}", name="article_show") */ public function showAction($slug) { // ... } }
- YAML
1 2 3 4
# app/config/routing.yml article_show: path: /article/{slug} defaults: { _controller: AppBundle:Article:show }
- XML
1 2 3 4 5 6 7 8 9 10 11
<!-- app/config/routing.xml --> <?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="http://symfony.com/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd"> <route id="article_show" path="/article/{slug}"> <default key="_controller">AppBundle:Article:show</default> </route> </routes>
- PHP
1 2 3 4 5 6 7 8 9 10
// app/config/routing.php use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; $collection = new RouteCollection(); $collection->add('article_show', new Route('/article/{slug}', array( '_controller' => 'AppBundle:Article:show', ))); return $collection;
В этом случае, вам нужно указать как имя маршрута (article_show
), так и
значение параметра {slug}
. Используя этот маршрут, вернитесь к шаблону
recent_list.html.twig
из предыдущего раздела, и создайте ссылку на статью
правильно:
- Twig
1 2 3 4 5 6
{# app/Resources/views/article/recent_list.html.twig #} {% for article in articles %} <a href="{{ path('article_show', {'slug': article.slug}) }}"> {{ article.title }} </a> {% endfor %}
- PHP
1 2 3 4 5 6 7 8
<!-- app/Resources/views/Article/recent_list.html.php --> <?php foreach ($articles as $article): ?> <a href="<?php echo $view['router']->path('article_show', array( 'slug' => $article->getSlug(), )) ?>"> <?php echo $article->getTitle() ?> </a> <?php endforeach ?>
Tip
Вы также можете созадть абсолютный URL, использовав функцию Twig url()
:
- Twig
1 <a href="{{ url('welcome') }}">Home</a>- PHP
1 2 3 4 <a href="<?php echo $view['router']->url( 'welcome', array() ) ?>">Home</a>
Ссылки на ресурсы (assets)¶
Шаблоны также часто ссылаются на картинки, JacaScript, страницы стилей и
прочие ресурсы (здесь и далее вместо asset будет использован термин ресурс).
Конечно, вы можете хардкодить пути к ресурсам (например, /images/logo.png
),
но Symfony предлагает использовать более динамичную функцию Twig asset()
:
- Twig
1 2 3
<img src="{{ asset('images/logo.png') }}" alt="Symfony!" /> <link href="{{ asset('css/blog.css') }}" rel="stylesheet" />
- PHP
1 2 3
<img src="<?php echo $view['assets']->getUrl('images/logo.png') ?>" alt="Symfony!" /> <link href="<?php echo $view['assets']->getUrl('css/blog.css') ?>" rel="stylesheet" />
Главная задача функции asset()
- сделать ваше приложение более мобильным. Если
ваше приложение находится в корне хоста (например, http://example.com
), тогда
отображенный путь будет /images/logo.png
. Но, если ваше приложение находится
в подкаталоге (наприер, http://example.com/my_app
), каждый путь к ресурсу должен
отображаться с этим подкаталогом (например, /my_app/images/logo.png
). Функция
asset()
берёт на себя заботу по определению того, как именно ваше приложение
используется и генерирует соответствующие пути.
В дополнение к этому, если вы используете функцию asset()
, Symfony сможет
автоматически добавлять строку запроса к вашему ресурсу, чтобы гарантировать,
что обновленные статичные ресурсы не будут загружены из кэша после выгрузки.
Например, /images/logo.png
может выглядеть как /images/logo.png?v2
.
Подробнее об этом смотрите версию опций конфигурации reference-framework-assets-version.
Если для ресурсов вам нужны абсолютные URL, используйте функцию Twig
absolute_url()
следующим образом:
1 | <img src="{{ absolute_url(asset('images/logo.png')) }}" alt="Symfony!" />
|
Подключение CSS (таблиц стилей) и Javascript в Twig¶
Ни один современный сайт не может обойтись без подключения CSS и Javascript файлов. В Symfony, подключение этих ресурсов элегантно обрабатывается, опираясь на возможности наследования шаблонов.
Tip
В этом разделе вы узнаете философию подключения CSS и Javascript ресурсов
в Symfony. Symfony также совместим с другой библиотекой, Assetic, которая
следует той же философии, но позволяет вам выполнять намного более интересные
операций над этими ресурсами. Дополнительную информацию можно получить в
Как использовать Assetic для управления ресурсами
.
Начните с добавления двух блоков к вашему базовому шаблону, который будет содержать
ваши ресурсы: один назовите stylesheets
, внутри HTML-тега head
, другой -
javascripts
, перед закрывающим HTML-тегом body
. Эти блоки будут содержать все
таблицы стилей и скрипты, которые вам требуются для сайта:
- Twig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
{# app/Resources/views/base.html.twig #} <html> <head> {# ... #} {% block stylesheets %} <link href="{{ asset('css/main.css') }}" rel="stylesheet" /> {% endblock %} </head> <body> {# ... #} {% block javascripts %} <script src="{{ asset('js/main.js') }}"></script> {% endblock %} </body> </html>
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// app/Resources/views/base.html.php <html> <head> <?php ... ?> <?php $view['slots']->start('stylesheets') ?> <link href="<?php echo $view['assets']->getUrl('css/main.css') ?>" rel="stylesheet" /> <?php $view['slots']->stop() ?> </head> <body> <?php ... ?> <?php $view['slots']->start('javascripts') ?> <script src="<?php echo $view['assets']->getUrl('js/main.js') ?>"></script> <?php $view['slots']->stop() ?> </body> </html>
Проще некуда! Но что, если вам потребуется включить дополнительную таблицу
стилей или скрипт в дочернем шаблоне? Например, предположим, что у вас есть
страница контактов и вам нужно подключить файл стилей contact.css
только на
одной этой странице. Внутри шаблона страницы contact необходимо выполнить следующее:
- Twig
1 2 3 4 5 6 7 8 9 10
{# app/Resources/views/contact/contact.html.twig #} {% extends 'base.html.twig' %} {% block stylesheets %} {{ parent() }} <link href="{{ asset('css/contact.css') }}" rel="stylesheet" /> {% endblock %} {# ... #}
- PHP
1 2 3 4 5 6
// app/Resources/views/contact/contact.html.twig <?php $view->extend('base.html.php') ?> <?php $view['slots']->start('stylesheets') ?> <link href="<?php echo $view['assets']->getUrl('css/contact.css') ?>" rel="stylesheet" /> <?php $view['slots']->stop() ?>
В дочернем шаблоне вы просто переопределяете блок stylesheets
и размещаете
новый тег стиля внутри этого блока. Конечно же, поскольку вам нужно добавить
стиль к блоку родительского контента, а не заменить его, вы должны использовать
функцию Twig parent()
, чтобы включить все стили из блока stylesheets базового
шаблона.
Вы также можете включать ресурсы, расположенные в папке пакетов Resources/public
.
Вам нужно будет выполнить команду php php bin/console assets:install target [--symlink]
,
которая скопирует (или создаст символическую ссылку) файлы в нужное место
(target по умолчанию имеет значение "web".
1 | <link href="{{ asset('bundles/acmedemo/css/contact.css') }}" rel="stylesheet" />
|
Конечным результатом является страница, которая включает как main.js
, так и contact.css
.
Отсылка к запросу, пользователю или сессии¶
Symfony также предоставляет вам глобальную переменную Twig app
? которая может
быть использована для доступа к текущему пользователю, запросу и др.
См. Переменная app для большей информации.
Экранирование¶
Twig выполняет автоматическое "экранирование" во время отображения какого-либо содержимого для того, чтобы защитить вас от атак Cross Site Scripting (XSS).
Представьте, что description
равняется I <3 this product
:
1 2 3 4 5 | <!-- output escaping is on automatically -->
{{ description }} <!-- I <3 this product -->
<!-- disable output escaping with the raw filter -->
{{ description|raw }} <!-- I <3 this product -->
|
Caution
PHP-шаблоны не экранируют контент автоматически.
Для того, чтобы узнать больше, см Экранирование.
Заключение¶
Шаблонизатор - это всего-лишь один из многих инструментов Symfony. И его работа проста: дать нам возможность отображать динамичный и сложный HTML-результат так, чтобы он в конечном счете возвращался к пользователю, отправлял email или делал что-то еще.
Продолжайте!¶
Перед тем, как снова нырнуть в мир Symfony, посмотрите Систему конфигурации.
Узнать больше¶
- How to Use PHP instead of Twig for Templates
- Как использовать PHP для шаблонов вместо Twig
- How to Access the User, Request, Session & more in Twig via the
app
Variable - Как получить доступ к пользователю, запросу, сессии и др. в Twig через переменную
app
- How to Dump Debug Information in Twig Templates
- Как сбросить информацию об отладке в шаблонах Twig
- How to Embed Controllers in a Template
- Как встраивать контроллеры в шаблон
- How to Escape Output in Templates
- Как экранировать вывод в шаблонах
- How to Work with Different Output Formats in Templates
- Как работать с разными форматами вывода в шаблонах
- How to Inject Variables into all Templates (i.e. global Variables)
- Как внедрять переменные во все шаблоны (т.е. глобальные переменные)
- How to Embed Asynchronous Content with hinclude.js
- Как встроить асинхронное содержание с помощью hinclude.js
- How to Organize Your Twig Templates Using Inheritance
- Как упорядочить ваши шаблоны Twig, используя наследование
- How to Use and Register Namespaced Twig Paths
- Как использовать и регистрировать пути Twig с пространством имён
- Как переопределять шаблоны из сторонних пакетов
- How to Render a Template without a custom Controller
- Как отобразить шаблон без пользовательского контроллера
- How to Check the Syntax of Your Twig Templates
- Как проверить синтаксис ваших шаблонов Twig
- How to Write a custom Twig Extension
- Как написать пользовательское расширение Twig
Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.