
Symfony 1.1 предлагает поддержку различных форматов и mime-types. Это означает что одна и таже связка модель и контроллер могут иметь различные шаблоны опираясь на формат запроса. Формат по умолчанию это HTML, но symfony поддерживает ряд дургих форматов представления, все они определены в factories.yml:
request:
class: sfWebRequest
param:
formats:
txt: text/plain
js: [application/javascript, application/x-javascript, text/javascript]
css: text/css
json: [application/json, application/x-json]
xml: [text/xml, application/xml, application/x-xml]
rdf: application/rdf+xml
atom: application/atom+xml
Каждый фомарт соспостовялется с одим или несколькими mime-types. Эти mime-types используются для автоматического определения формата запроса, путем парсинга принятого HTTP заголовка (Accept HTTP header). Это очень удобно, если вы хотите сделать доступными ваши данные через браузер. Для изменения формата ответа (response format), клиенту Вашего веб сайта нужно только сменить принимаемый заголовок (Accept header) как показно ниже:
$ curl -H “Accept: application/xml” http://ws.example.com/api/article # to get a XML representation of the data
$ curl -H “Accept: application/json” http://ws.example.com/api/article # to get a JSON representation of the data
Поддерживать разные форматы данных так же легко как создавать разные шаблонов. Допустим наше приложение расположено в api/article. Ниже показан список шаблонов, который нужно создать в apps/frontend/modules/api/templates для поддержки форматов HTML, XML, и JSON:
articleSuccess.php
articleSuccess.xml.php
articleSuccess.json.php
По умолчанию, symfony изменит Content-Type в выводе согласно формату, и все не-HTML форматы, в макетах будут отключены. Даже partials (части) и макеты могут быть разные относительно формата запроса. К примеру, если вы подключите несколько партиалов в шаблоне, то подключаемый имя подключаемого партиала будет зависеть от текущего формата:
_list.php
_list.xml.php
_list.json.php
Разберем другой пример. Вы хотите “на лету” создать какой либо файл стилей (stylesheets) или JavaScript. Так как мы не можем всегда рассчитывать на Accept HTTP заголовок браузера для этих целей, мы можем переназначить формат с помощью специальной переменной sf_format в наших правилах роутинга (routing ruls). Ниже как создать роутинг для динамическогих стилей (stylesheet):
css1:
url: /css/dynamic1.css
param: { module: css, action: dynamic, sf_format: css }
Так же можно использовать переменную sf_format в шаблоне URL разрешая несколько форматов для одного действия (action):
api_article:
url: /api/article:.sf_format
param: { module: api, action: article }
requirements:
sf_format: (?:html|xml|json)
Большую часть времени нам не нужно менять одиночные строки в действии (action) для поддержки нового формата, но если нам действительно нужно выполнить что-то особенное для формата, можно вызвать $request->getRequestFormat(), получить текущий формат и действовать соответствующе.
Так, а теперь создадим оптимизированную версию нашего сайта под iPhone. Форамата для iphone нет в сборке по умолчанию, но добавить его очень просто. Первое, нам нужно определить что запрос пришел с iPhone. Если заголовок User-Agent содержит слова Mobile и Safari, мы можем быть уверенными что этот браузер в iPhone. Добавляем эту логику в ProjectConfiguration класс и определяем прослушивать события request.filter_parameters:
// config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
// ...
$this->dispatcher->connect('request.filter_parameters', array($this, 'filterRequestParameters'));
}
public function filterRequestParameters(sfEvent $event, $parameters)
{
$request = $event->getSubject();
if (preg_match('#Mobile/.+Safari#i', $request->getHttpHeader('User-Agent')))
{
$request->setRequestFormat('iphone');
}
return $parameters;
}
}
Теперь каждый раз при запросе вызывается метод filterParameters() и если браузер в iPhone, формат запроса (request format) изменяется под iphone.
Вот и все! Теперь, любой запрос с iPhone будет использовать шаблон *Success.iphone.php вместо шаблона *Success.php.
Если вы используете особые стили (stylesheets) или JavaScript для поддержки iPhone (к примеру если вы используете iui библиотеку), вы так жу можете сконфигурировать view для прослушивания view.configure_format:
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
// ...
$this->dispatcher->connect('view.configure_format', array($this, 'configureIPhoneFormat'));
}
public function configureIPhoneFormat(sfEvent $event)
{
if ('iphone' == $event['format'])
{
// add some CSS, stylesheet, or whatever you want
}
}
}
Вчера, Apple представила новый iPhone 3G. В честь такого события Фабьен (разработчик symfony) , представил документацию symfony API с поддержкой iPhone, скриншот в начале поста.
Благодаря новой поддержке форматов в Symfony 1.1, представлять совой сайт в разных форматах нет ничего проще, достаточно добавить шаблон для нового формата.
Оригинал статьи.