Caution: You are browsing the legacy symfony 1.x part of this website.

Come creare una versione del tuo sito ottimizzata per iPhone

1.2
Symfony version
1.1
Language

symfony 1.1 introduce il support nativo a differenti formati e mime-yptes. Questo significa che gli stessi model e controller possono avere template differenti in base al formato della richiesta. Il formato di default è comunque HTML, ma symfony supporta nativamente molti formati come è definito nel file 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

Ogni formato è associato con uno o più mime-type. Questi mime-type sono utilizzati per determinare automaticamente il formato della richiesta effettuando il parsing dell' Accept HTTP header. Tutto questo è veramente comodo se vuoi rendere i tuoi dati disponibili via browser ed esporli come un Web Service. Per cambiare il formato della risposta, un client Web Service deve solo cambiare l'Accept header come mostrato qua sotto:

$ curl -H "Accept: application/xml"  http://ws.example.com/api/article # per ricevere la rappresentazione XML dei dati
$ curl -H "Accept: application/json" http://ws.example.com/api/article # per ricevere la rappresentazione JSON dei dati

Supportare differenti formati è facile quanto creare templates differenti. Perciò, diremo che i web service sono gestiti da un api/article azione. Ecco una lista dei template che devi creare in apps/frontend/modules/api/templates per supportare i formarti HTML, XML, e JSON:

  • articleSuccess.php
  • articleSuccess.xml.php
  • articleSuccess.json.php

Di default, symfony cambierà la risposta Content-Type coerentemente con il formato, e per tutti i formati non HTML, i layout verranno disabilitati. Perfino i partials e i layouts possono essere differenti in base al formato della richiesta. Per esempio, se includi un list partial in un template, il partial caricato dipende dal formato corrente: * _list.php * _list.xml.php * _list.json.php

Facciamo un' altro esempio. Vuoi creare qualche foglio di stile o javascript al volo. Dato che non puoi sempre fidarti dell'Accept HTTP header fornito dal browser in questi casi, puoi forzare il formato usando una speciale variabile chiamata sf_format nelle tue regole di routing for those cases. Ecco come creare un route per un foglio di stile dinamico:

css1:
  url:   /css/dynamic1.css
  param: { module: css, action: dynamic, sf_format: css }

Puoi anche usare la variabile sf_format nel pattern URL per permettere diversi formati per una singola azione:

api_article:
  url:   /api/article.:sf_format
  param: { module: api, action: article }
  requirements:
    sf_format: (?:html|xml|json)

La maggior parte delle volte, non devi mai modificare una solo riga nelle tue actions per supportare nuovi formati; ma se hai la necessità di fare qualcosa di particolare con i formati, puoi chiamare la $request->getRequestFormat() per ricevere il formato corrente e comportarti di conseguenza.

Ok, ora la parte divertente! Mettiamo che tu voglia creare una versione ottimizzata del tuo sito per iPhone. Il formato iphone non esiste di default ma è veramente facile configurarlo. Prima di tutto abbiamo bisogno di una modo di determinare che una richiesta proviene da un iPhone. Se l'header User-Agent contiene le parole Mobile e Safari, possiamo tranquillamente affermare che al richiesta proviene da un iPhone. Possiamo mettere questa logica nella classe ProjectConfiguration registrando un listener per l'evento 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;
  }
}

Ora, ogni volta che riceviamo una richiesta, il metodo filterParameters() sarà chiamato e se il browser è un iPhone, il formato della richiesta sarà cambiato in iphone.

E' tutto! Ora, ogni richiesta proveniente da un iPhone userà il template *Success.iphone.php invece del template *Success.php.

Se utilizzi qualche foglio di stile o javascript speciale per supportare iPhone (per esempio se utilizzi la iui library), puoi anche configurare la view per interrogare 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'])
    {
      // aggiungi qualche CSS,javascript, o quello che vuoi
    }
  }
}

Grazie al nuovo supporto ai formati presente in symfony 1.1, sviluppare siti web che supportano Web Services, API o iPhone non è mai stato così facile. Supportare un nuovo formato non è facile come creare un nuovo set di template.