developer blog

451 degrees Fahrenheit

Как создать отимизированую версию сайта под iPhone в Symfony 1.1

June 11th, 2008 by pilot |


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, представлять совой сайт в разных форматах нет ничего проще, достаточно добавить шаблон для нового формата.

Оригинал статьи.

top of hotblogs.org.ua

Раздел Symfony

12 Responses

  1. Обмен ссылками Says:

    Спасибо за материал

  2. pilot Says:

    Все самое интересное, что будет появляться по теме symfony на англоязычных сайтах, будет здесь появляться.

  3. 451 degrees Fahrenheit » Blog Archive » Wordle - красивое облако тегов Says:

    [...] А вот и примерчик облака для поста Как создать отимизированую версию сайта под iPhone в Symfony … [...]

  4. 451 degrees Fahrenheit » Blog Archive » Архитектура symfony 1.1 Says:

    [...] расказали о новой архитектуре symfony 1.1. Кроме уже существующих новых возможностей, новая версия - это год сложной [...]

  5. 451 degrees Fahrenheit » Blog Archive » Вот он долгожданный релиз symfony 1.1 Says:

    [...] Система обработки форматов позволяет вашему приложению вести себя по разному в зависимости от запроса с iPhone, от поисквого бота, или от браузера, [...]

  6. Архитектура symfony 1.1 Says:

    [...] расказали о новой архитектуре symfony 1.1. Кроме уже существующих новых возможностей, новая версия - это год сложной [...]

  7. Serg Says:

    Эксперементы показали что для всех форматов, по умолчанию, layout отключен.
    Это я к тому что определил новый формат wap и он загружается без шаблона страницы.
    Практически вручную пришлось в actions писать $this->setLayout(’layout’);
    Как через конфиги указать использование шаблона страницы?

  8. pilot Says:

    Ты можешь сразу в модуле задать config/view.yml и в нем задать использовать layout, тогда дополнительно не нужно будет его задать в дейсвии.

    Если что-то не так понял, заведи тему в форуме http://www.symfony.org.ua, обязательно обсудим и найдем решение.

  9. Serg Says:

    есть я там на форуме, тут просто вроде как по теме.
    В общем view.yml у меня задан layout. так же созданны два файла
    layout.php и layout.wap.php
    Так вот это layout.wap.php не используется пока не напишу $this->setLayout(’layout’).

  10. pilot Says:

    т.е он у тебя вообще даже обычный layout не хавает?

  11. Serg Says:

    угу. как будто бы has_layout: off
    Вот и приходится вручную включать. По логике это в принципе правильно. Разве нужен layout для rss или xml формата…. А вот для wap нужен.

  12. Serg Says:

    перенес обсуждение в форум
    http://forum.symfony.org.ua/viewtopic.php?pid=126

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.