Caution: You are browsing the legacy symfony 1.x part of this website.
SymfonyWorld Online 2020
100% online
30+ talks + workshops
Live + Replay watch talks later

Come creare una versione del tuo sito ottimizzata per iPhone

1.1
Symfony version
1.2
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.