in Профессиональное

Symfony 2.0 – быстрый тур – вид/the view (часть 2)

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

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

Очень часто, шаблоны в проектах используют общие элементы, например всем известные хидер (header) и футер (footer). В Symfony мы имеем по этому поводу свое мнение: шаблон может быть декорирован другим шаблоном. Давайте посмотрим на файл layout.php:

# src/Application/HelloBundle/Resources/views/layout.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  </head>
  <body>
    <?php $view->slots->output('_content') ?>
  </body>
</html>

Шаблон index декорируется шаблоном layout.php (спасибо extend()):

# src/Application/HelloBundle/Resources/views/Hello/index.php
<?php $view->extend('HelloBundle::layout') ?>

Hello <?php echo $name ?>!

Нотация HelloBundle::layout звучит знакомо, не так ли? Это та же самая нотация для привязки шаблона. Часть “::” означает что контроллер пуст (не указан) и следовательно соответствующий файл хранится напрямую во views/.

Строка $view->slots->output(‘_content’) заменяется контентом дочернего шаблона, index.php (про него подробнее в следующей секции).

Как вы можете видеть, Symfony предоставляет метод загадочного объекта $view. В шаблоне, $view это специальный объект, который предоставляет пачку методов и свойств, которые заставляют движок шаблонов “тикать как часы”.

Symfony также поддерживает множественные уровни декорации (multiple decoration levels): один layout может быть декорирован другим. Эта техника будет полезна для больших проектов и она становится еще более могущественной в комбинации со слотами (slots).

Слоты.

Что есть слот? Слот – это кусочек кода, определенный в шаблоне, который может быть использован в любом макете (layout), декорирующем шаблон. Определим слот title в шаблоне index:

# src/Application/HelloBundle/Resources/views/Hello/index.php
<?php $view->extend('HelloBundle::layout') ?>

<?php $view->slots->set('title', 'Hello World app') ?>

Hello <?php echo $name ?>!

И изменим макет таким образом, чтобы title выводился в заголовке:

# src/Application/HelloBundle/Resources/views/layout.php
<html>
  <head>
    <title><?php $view->slots->output('title', 'Default Title') ?></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  </head>
  <body>
    <?php $view->slots->output('_content') ?>
  </body>
</html>

Метод output() вставляет содержимое слота и опционально принимает значение по умолчанию, если слот не установлен. Также, _content является специализированным слотом, который содержит отрендереный шаблон дочернего шаблона.

Для больших слотов также есть расширенный синтаксис:

<?php $view->slots->start('title') ?>
  Some large amount of HTML
<?php $view->slots->stop() ?>

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

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

Создадим шаблон hello.php:

# src/Application/HelloBundle/Resources/views/Hello/hello.php
Hello <?php echo $name ?>!

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

# src/Application/HelloBundle/Resources/views/Hello/index.php
<?php $view->extend('HelloBundle::layout') ?>

<?php echo $view->render('HelloBundle:Hello:hello', array('name' => $name)) ?>

Метод render() вычисляет и возвращает содержимое другого шаблона (это точно такой же метод, который используется в контроллере).

Встраивание других действий

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

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

# src/Application/HelloBundle/Resources/views/Hello/index.php
<?php $view->actions->output('HelloBundle:Hello:fancy', array('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', array('name' => $name, 'object' => $object));
  }

  // ...
}

Вы также должны иметь в виду, что эта техника очень мощная, но в то же время медленная, так как она порождает внутренний подзапрос (sub-request). Таким образом, везде где возможно – применяйте более быструю альтернативу.

Но где же определено свойство $view->actions? Как и $view->slots, оно вызывает хелпер шаблона и в следующей секции в узнаете об этом чуть больше!

Хэлперы шаблонов

Система шаблонов Symfony может быстро и просто быть расширена через хелперы. Хелперы это PHP объекты, которые предоставляют функционал, который требуется в шаблонах. actions и slots это лишь два, встроенных в Symfony, хелперов.

Линки(связи) между страницами

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

<a href="<?php echo $view->router->generate('hello', array('name' => 'Thomas')) ?>">
  Greet Thomas!
</a>

Метод generate() принимает имя маршрута и массив аргументов. Имя маршрута это основной ключ, по которому маршрут можно найти и аргументы как минимум должны покрывать метки-плейсхолдеры в описании маршрута.

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

Использование ассетов (картинки, стили, скрипты)

Каким бы был интернет без картинок, скриптов и стилей? Symfony предлагает три хелпера для упрощения работы с ними: assets, javaScripts и stylesheets.

<link href="<?php echo $view->assets->getUrl('css/blog.css') ?>" rel="stylesheet" type="text/css" />

<img src="<?php echo $view->assets->getUrl('images/logo.png') ?>" />

Назначение хелпера assets – сделать ваше приложение более переносимым (portable). Благодаря ему, вы можете переносить корень приложения куда вам угодно в рамках directory root без изменений в коде ваших шаблонов.

Таким же образом вы можете управлять стилями и яваскриптами при помощи хелперов stylesheets и javaScripts:

<?php $view->javascripts->add('js/product.js') ?>
<?php $view->stylesheets->add('css/product.css') ?>

Метод add() определяет зависимости. Для вывода ассетов вам нужно добавить следующий код в основной шаблон (layout):

<?php echo $view->javascripts ?>
<?php echo $view->stylesheets ?>

Последний рывок

Система шаблонов Symfony простая, но очень эффективная. Благодаря layot’ам, slot’ам, шаблонам и включению действий очень легко можно организовать ваши шаблоны логично и гибко. Позднее вы узнаете как конфигурировать поведение по умолчанию для шаблонизатора и как расширять ее, добавляя новые хелперы.

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

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

Оригинал взят тут: http://symfony-reloaded.org/quick-tour-part-2

Write a Comment

Comment

*

  1. Цитата: Symfony также поддерживает множественные уровни декорации (multiple decoration levels): один layout может быть декорирован другим. Эта техника будет полезна для больших проектов и она становится еще более могущественной в комбинации со слотами (slots).
    Как это реализуется на практике?

    • Это лучше спросить у Фабиена и сотоварищи ) Я пока только разбираюсь. А в продакшн Symfony 2 можно будет пробовать видимо после нового года.

  2. Классные статьи, спасибо.

    Убедительная просьба. У вас верстка сломана немного. Код обрезается по ширине. Посмотрите что можно сделать с этим. И парсер посъедал слеши кое где.