Development

Documentation/it_IT/book/forms/01-Form-Creation (diff)

You must first sign up to be able to contribute.

Changes from Version 1 of Documentation/it_IT/book/forms/01-Form-Creation

Show
Ignore:
Author:
garak (IP: 85.18.214.242)
Timestamp:
10/28/08 12:35:40 (9 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/it_IT/book/forms/01-Form-Creation

    v0 v1  
     1{{{ 
     2#!WikiMarkdown  
     3 
     4Capitolo 1 - Creazione di form 
     5============================== 
     6 
     7Una form è composta da campi, che possono essere nascosti, di testo, di selezione e di spunta. Questo capitolo introduce la creazione di form e la gestione di campi di form usando il framework per le form di symfony. 
     8 
     9È richiesto symfony 1.1 per seguire questo libro. Avrai anche bisogno di creare un progetto ed un'applicazione `frontend` per andare avanti. Fai riferimento all'introduzione per maggiori informazioni sulla creazione di un progetto symfony. 
     10 
     11Prima di iniziare 
     12----------------- 
     13 
     14Inizieremo aggiungendo una form di contatto ad un'applicazione symfony. 
     15 
     16La Figura 1-1 mostra la form di contatto come viene vista dagli utenti che vogliono inviare un messaggio. 
     17 
     18Figura 1-1 - Form di contatto 
     19 
     20![Form di contatto](http://www.symfony-project.org/images/forms_book/en/01_01.png "Form di contatto") 
     21 
     22Creeremo tre campi per questa form: il nome dell'utente, l'email dell'utente, e il messaggio che l'utente vuole inviare. Mostreremo semplicemente le informazioni inviate nella form per lo scopo di questo esercizio, come mostrato in Figura 1-2. 
     23 
     24Figura 1-2 - Pagina di ringraziamento 
     25 
     26![Pagina di ringraziamento](http://www.symfony-project.org/images/forms_book/en/01_02.png "Pagina di ringraziamento") 
     27 
     28Figura 1-3 - Interazione tra l'applicazione e l'utente 
     29 
     30![Interazione tra l'applicazione e l'utente](http://www.symfony-project.org/images/forms_book/en/01_03.png "Interazione tra l'applicazione e l'utente") 
     31 
     32Widget 
     33------ 
     34 
     35### Le classi sfForm e sfWidget 
     36 
     37Gli utenti inseriscono le informazioni nei campi che compongono le form. In symfony, una form è un oggetto che eredita dalla calsse `sfForm`. Nel nostro esempio, creeremo una classe `ContactForm` che eredita dalla classe `sfForm`. 
     38 
     39>**NOTE** 
     40>`sfForm` è la classe base di tutte le form e rende facile gestire la configurazione ed il ciclo di vita delle tue form. 
     41 
     42Puoi iniziare a configurare la tua form aggiungendo '''widget''' usando il metodo `configure()`. 
     43 
     44Un '''widget''' rappresenta un campo di una form. Per il nostro esempio, abbiamo bisogno di tre widget che rappresentano i nostri tre campi: `name`, `email`, e `message`. Il Listato 1-1 mostra la prima implementazione della classe `ContactForm`. 
     45 
     46Listato 1-1 - Classe `ContactForm` con tre campi 
     47 
     48    [php] 
     49    // lib/form/ContactForm.class.php 
     50    class ContactForm extends sfForm 
     51    { 
     52      public function configure() 
     53      { 
     54        $this->setWidgets(array( 
     55          'name'    => new sfWidgetFormInput(), 
     56          'email'   => new sfWidgetFormInput(), 
     57          'message' => new sfWidgetFormTextarea(), 
     58        )); 
     59      } 
     60    } 
     61 
     62I widget sono definiti nel metodo `configure()`. Questo metodo viene chiamato automaticamente dal costruttore della classe `sfForm`. 
     63 
     64Il metodo `setWidgets()` è usato dai widget nella form. Il metodo `setWidgets()` accetta un'array associativa in cui le chiavi sono i nomi dei campi ed i valori sono gli oggetti widget. Ciascuna widget è un oggetto che eredita dalla classe `sfWidget`. Per questo esempio abbiamo usato due tipi di widget: 
     65 
     66  * `sfWidgetFormInput` :  Questo widget rappresenta il campo di testo `input` 
     67  * `sfWidgetFormTextarea`: Questo widget rappresenta l'area di testo `textarea` 
     68 
     69>**NOTE** 
     70>Per convenzione, salviamo le classi delle form nella cartella `lib/form/`. Puoi salvarle in qualsiasi cartella gestita dal meccanismo di autoloading di symfony ma come vedremo dopo, symfony usa la cartella `lib/form/` per generare le form dagli oggetti modello. 
     71 
     72### Mostrare la form 
     73 
     74La nostra form è ora pronta per essere usata. Possiamo creare un modulo symfony per mostrare la form: 
     75 
     76    [php] 
     77    $ cd ~/PATH/TO/THE/PROJECT 
     78    $ php symfony generate:module frontend contact 
     79 
     80Nel modulo `contact`, modifichiamo l'azione index per passare un'istanza della form al template, come mostrato nel Listato 1-2. 
     81 
     82Listato 1-2 - Classe `Actions` del modulo `contact` 
     83 
     84    [php] 
     85    // apps/frontend/modules/contact/actions/actions.class.php 
     86    class contactActions extends sfActions 
     87    { 
     88      public function executeIndex() 
     89      { 
     90        $this->form = new ContactForm(); 
     91      } 
     92    } 
     93  
     94Quando si crea una form, il metodo `configure()`, definito prima, sarà chiamato automaticamente. 
     95 
     96Ora abbiamo solo bisogno di creare un template per mostrare la form, come mostrato nel Listato 1-3. 
     97 
     98Listato 1-3 - Template che mostra la form 
     99 
     100    // apps/frontend/modules/contact/templates/indexSuccess.php 
     101    <form action="<?php echo url_for('contact/submit') ?>" method="post"> 
     102      <table> 
     103        <?php echo $form ?> 
     104        <tr> 
     105          <td colspan="2"> 
     106            <input type="submit" /> 
     107          </td> 
     108        </tr> 
     109      </table> 
     110    </form> 
     111 
     112Una form symfony gestisce solo i widget che mostrano informazioni agli utenti. Nel template `indexSuccess`, la riga `<?php echo $form ?>` mostra solo tre campi. Gli altri elementi come il tag `form` ed il bottone `submit` devono essere aggiunti dallo sviluppatore. Questo potrebbe non sembrare ovvio inizialmente, ma vedremo più avanti quanto sia utile e facile sia inserire le form. 
     113 
     114Usare la costruzione `<?php echo $form ?>` è molto utile quando si creano e tipizzano le form. Consente allo sviluppatore di concentrarsi sulla logica del modello senza preoccuparsi degli aspetti visuali. Il Capitolo tre spiegherà come personalizzare il template e la visualizzazione della form. 
     115 
     116>**NOTE** 
     117>Quando si mostra un oggetto usando `<?php echo $form ?>`, il motore PHP in realtà mostrerà la rappresentazione testuale dell'oggetto `$form`. Per convertire l'oggetto in una stringa, PHP cerca di eseguire il metodo magico `__toString()`. Ciascun widget implementa tale metodo magico per convertire l'oggetto in codice HTML. Richiamare `<?php echo $form ?>` è equivalente a chiamare `<?php echo $form->__toString() ?>`. 
     118 
     119Possiamo ora vedere la form in un browser (Figura 1-4) e verificare il risultato inserendo l'indirizzo dell'azione `contact/index` (`/frontend_dev.php/contact`). 
     120 
     121Figura 1-4 - Form di contatto generata 
     122 
     123![Form di contatto generata](http://www.symfony-project.org/images/forms_book/en/01_04.png "Form di contatto generata") 
     124 
     125Il Listato 1-4 mostra il codice generato dal template. 
     126 
     127Listato 1-4 - Codice generato dal template 
     128 
     129    <form action="/frontend_dev.php/contact/submit" method="POST"> 
     130      <table> 
     131      
     132        <!-- Inizio del codice generato da <?php echo $form ?> 
     133     --> 
     134        <tr> 
     135          <th><label for="name">Nome</label></th> 
     136          <td><input type="text" name="name" id="name" /></td> 
     137        </tr> 
     138        <tr> 
     139          <th><label for="email">Email</label></th> 
     140          <td><input type="text" name="email" id="email" /></td> 
     141        </tr> 
     142        <tr> 
     143          <th><label for="message">Messaggio</label></th> 
     144          <td><textarea rows="4" cols="30" name="message" id="message"></textarea></td> 
     145        </tr> 
     146        <!-- Fine del codice generato da <?php echo $form ?> 
     147     --> 
     148      
     149        <tr> 
     150          <td colspan="2"> 
     151            <input type="submit" /> 
     152          </td> 
     153        </tr> 
     154      </table> 
     155    </form> 
     156  
     157Possiamo vedere che la form viene mostrata con tre righe `<tr>` di una tabella HTML. Per questo abbiamo dovuto racchiuderla in un tag `<table>`. Ogni riga comprende un tag `<label>` ed un tag `<input>` o `<textarea>`. 
     158 
     159### Label 
     160 
     161Le etichette (`label`) di ogni campo sono generate automaticamente. Per default, le label sono una trasformazione del nome del campo seguendo due regole: una lettere maiuscola iniziale ed un trattino basso sono sostituiti da spazi. Esempio: 
     162 
     163    [php] 
     164    $this->setWidgets(array( 
     165      'first_name' => new sfWidgetFormInput(), // label generata: "First name" 
     166      'last_name'  => new sfWidgetFormInput(), // label generata: "Last name" 
     167    )); 
     168 
     169Anche se la generazione automatica delle label è molto utile, il framework consente di definire label personalizzate col metodo `setLabels()`: 
     170 
     171    [php] 
     172    $this->widgetSchema->setLabels(array( 
     173      'name'    => 'Il tuo nome', 
     174      'email'   => 'La tua email', 
     175      'message' => 'Il tuo messaggio', 
     176    )); 
     177 
     178Puoi anche modificare solo una singola label usando il metodo `setLabel()`: 
     179 
     180    [php] 
     181    $this->widgetSchema->setLabel('email', 'La tua email'); 
     182 
     183Infine, vedremo nel Capitolo tre che si possono estendere le label dal template per personalizzare ulteriormente la form. 
     184 
     185>**SIDEBAR** 
     186>Widget schema 
     187>Quando usiamo il metodo `setWidgets()`, symfony crea un oggetto `sfWidgetFormSchema`. Questo oggetto è un widget che consente di rappresentare un insieme di widget. Nella nostra form `ContactForm`, abbiamo chiamato il metodo `setWidgets()`. Ciò è equivalente al seguente codice: 
     188> 
     189>    $this->setWidgetSchema(new sfWidgetFormSchema(array( 
     190>      'name'    => new sfWidgetFormInput(), 
     191>      'email'   => new sfWidgetFormInput(), 
     192>      'message' => new sfWidgetFormTextarea(), 
     193>    ))); 
     194> 
     195>    // quasi equivalente a : 
     196>      
     197>    $this->widgetSchema = new sfWidgetFormSchema(array( 
     198>      'name'    => new sfWidgetFormInput(), 
     199>      'email'   => new sfWidgetFormInput(), 
     200>      'message' => new sfWidgetFormTextarea(), 
     201>    )); 
     202> 
     203>Il metodo `setLabels()` è applicato ad un insieme di widget inclusi nell'oggetto `widgetSchema`. 
     204> 
     205>Vedremo nel Capitolo 5 che la nozione di "schema widget" rende più facile gestire form innestate. 
     206 
     207### Oltre le tabelle generate 
     208 
     209Anche se la visualizzazione della form per default è una tabella HTML, il formato della visualizzazione può essere modificato. Questi diversi tipi di formati di visualizzazione sono definiti in classi che ereditano da `sfWidgetFormSchemaFormatter`. Per default, una form usa il formato della tabella definito nella classe `sfWidgetFormSchemaFormatterTable`. Puoi anche usare il formato lista: 
     210 
     211    [php] 
     212    class ContactForm extends sfForm 
     213    { 
     214      public function configure() 
     215      { 
     216        $this->setWidgets(array( 
     217          'name'    => new sfWidgetFormInput(), 
     218          'email'   => new sfWidgetFormInput(), 
     219          'message' => new sfWidgetFormTextarea(), 
     220        )); 
     221      
     222        $this->widgetSchema->setFormFormatterName('list'); 
     223      } 
     224    } 
     225 
     226Questi due formati sono di default e vedremo nel Capitolo 5 come creare le proprie classi per altri formati. Ora che sappiamo come visualizzare una form, vediamo come gestire l'invio. 
     227 
     228### Inviare la Form 
     229 
     230Quando abbiamo creato un template per mostrare la form, abbiamo usato la URL interna `contact/submit` nel tag form per inviare la form. Ora abbiamo bisogno di aggiungere l'azione `submit` nel modulo `contact`. Il Listato 1-5 mostra come un'azione può ottenere l'informazione dall'utente e redirigere alla pagina di ringraziamento dove mostriamo questa informazione all'utente. 
     231 
     232Listato 1-5 - Uso dell'azione `submit` nel modulo `contact` 
     233 
     234    [php] 
     235    public function executeSubmit($request) 
     236    { 
     237      $this->forward404Unless($request->isMethod('post')); 
     238      
     239      $params = array( 
     240        'name'    => $request->getParameter('name'), 
     241        'email'   => $request->getParameter('email'), 
     242        'message' => $request->getParameter('message'), 
     243      ); 
     244      
     245      $this->redirect('contact/thankyou?'.http_build_query($params)); 
     246    } 
     247      
     248    public function executeThankyou() 
     249    { 
     250    } 
     251      
     252    // apps/frontend/modules/contact/templates/thankyouSuccess.php 
     253    <ul> 
     254      <li>Name:    <?php echo $sf_params->get('name') ?></li> 
     255      <li>Email:   <?php echo $sf_params->get('email') ?></li> 
     256      <li>Message: <?php echo $sf_params->get('message') ?></li> 
     257    </ul> 
     258  
     259>**NOTE** 
     260>`http_build_query` è una funzione di libreria di PHP che genera una query string URL-encoded da un'array di parametri. 
     261 
     262Il metodo `executeSubmit()` esegue tre azioni: 
     263 
     264  * Per ragioni di sicurezza, verifichiamo che la pagina sia stata inviata usando il metodo HTTP `POST`. Se non è stata inviata col metodo `POST`, l'utente è rediretto ad una pagina 404. Nel template `indexSuccess`, dichiariamo il metodo di invio come `POST` (`<form ... method="post">`): 
     265 
     266      [php] 
     267      $this->forward404Unless($request->isMethod('post')); 
     268  * Poi prendiamo i valori inviati dall'utente per salvarli nella tabella dei parametri: 
     269   
     270      [php] 
     271      $params = array( 
     272        'name'    => $request->getParameter('name'), 
     273        'email'   => $request->getParameter('email'), 
     274        'message' => $request->getParameter('message'), 
     275      ); 
     276  * Infine, redirigiamo l'utente ad una pagina di ringraziamenti (`contact/thankyou`) per mostrare le sue informazioni: 
     277 
     278      [php] 
     279      $this->redirect('contact/thankyou?'.http_build_query($params)); 
     280 
     281Invece di redirigere l'utente ad un'altra pagina, potremmo creare un template `submitSuccess.php`. Sebbene sia possibile, è una pratica migliore redirigere sempre l'utente dopo una richiesta con metodo `POST`: 
     282 
     283  * Questo previene il reinvio della form, se l'utente ricarica la pagina 
     284  * L'utente può anche cliccare sul bottone "indietro" senza vedere l'avviso che gli chiede di inviare nuovamente la form. 
     285   
     286>**TIP** 
     287>Forse hai notato che `executeSubmit()` è diverso da `executeIndex()`. Quando chiama questi metodi, symfony passa l'oggetto `sfRequest` corrente come primo argomento ai metodi `executeXXX()`. Con PHP, non devi raccogliere tutti i parametri, perciò non abbiamo definito la variabile di `$request` in `executeIndex()`, perché non ne abbiamo bisogno. 
     288 
     289La Figura 1-5 mostra il flusso dei metodi quando interagiscono con l'utente. 
     290 
     291Figura 1-5 - Flusso dei metodi 
     292 
     293![Flusso dei metodi](http://www.symfony-project.org/images/forms_book/en/01_05.png "Flusso dei metodi") 
     294 
     295>**NOTE** 
     296>Quando si mostra di nuovo i dati immessi dall'utente nel template, corriamo il rischio di un attacco XSS (Cross-Site Scripting). Puoi trovare ulteriori informazioni su come prevenire il rischio di XSS implementando una strategia di escaping nel capitolo [wiki:Documentation/it_IT/book/1.1/07-Inside-the-View-Layer All'interno del Layer Vista] della guida. 
     297 
     298Dopo aver inviato la form dovresti vedere la pagina in Figura 1-6. 
     299 
     300Figura 1-6 - Pagina visualizzata dopo l'invio della form 
     301 
     302![Pagina visualizzata dopo l'invio della form](http://www.symfony-project.org/images/forms_book/en/01_06.png "Pagina visualizzata dopo l'invio della form") 
     303 
     304Invece di creare l'array dei parametri, sarebbe più facile ottenere le informazioni dall'utente direttamente in un'array. Il Listato 1-6 modifica l'attributo HTML `name` nei widget, per memorizzare i valori dei campi nell'array `contact`. 
     305 
     306Listato 1-6 - Modifica dell'attributo HTML `name` nei widget 
     307 
     308    [php] 
     309    class ContactForm extends sfForm 
     310    { 
     311      public function configure() 
     312      { 
     313        $this->setWidgets(array( 
     314          'name'    => new sfWidgetFormInput(), 
     315          'email'   => new sfWidgetFormInput(), 
     316          'message' => new sfWidgetFormTextarea(), 
     317        )); 
     318      
     319        $this->widgetSchema->setNameFormat('contact[%s]'); 
     320      } 
     321    } 
     322 
     323Chiamare `setNameFormat()` ci consente di modificare l'attributo HTML `name` per tutti i widget. `%s` verrà sostituito automaticamente dal nome del campo durante la generazione della form. Per esempio, l'attributo `name` per il campo `email` sarà `contact[email]`. PHP crea automaticamente un'array con i valori di una richiesta che include il formato `contact[email]`. In questo modo i campi saranno disponibili nell'array `contact`. 
     324 
     325Ora possiamo prendere direttamente l'array `contact` dall'oggetto richiesta, come mostrato nel Listato 1-7. 
     326 
     327Listato 1-7 - Nuovo formato degli attributi `name` nei widget dell'azione 
     328 
     329    [php] 
     330    public function executeSubmit($request) 
     331    { 
     332      $this->forward404Unless($request->isMethod('post')); 
     333      
     334      $this->redirect('contact/thankyou?'.http_build_query($request->getParameter('contact'))); 
     335    } 
     336 
     337Quando si visualizza il sorgente HTML della form, puoi vedere che symfony ha generato un attributo `name` che dipende non solo dal nome e dal formato del campo, ma anche dall'attributo `id`. L'attributo `id` viene creato automaticamente dal nome sostituendo i caratteri non consentiti con dei trattini bassi (_): 
     338 
     339------------------------------------------------- 
     340|Nome    | Attributo `name`  | Attributo `id`   | 
     341---------+-------------------+------------------- 
     342|name    |contact[name]            | contact_name     | 
     343|email   |contact[email]           | contact_email    | 
     344|message |      contact[message] |      contact_message | 
     345------------------------------------------------- 
     346 
     347### Un'altra soluzione 
     348 
     349In questo esmepio, abbiamo usato due azioni per gestire la form: `index` per la visualizzazione, `submit` per l'invio. Poiché la form è visualizzata tramite il metodo `GET` e l'invio tramite il metodo `POST`, possiamo anche fondere i due metodi nel metodo `index`, come mostrato nel Listato 1-8. 
     350 
     351Listato 1-8 - Fondere le due azioni usate nella form 
     352 
     353    [php] 
     354    class contactActions extends sfActions 
     355    { 
     356      public function executeIndex($request) 
     357      { 
     358        $this->form = new ContactForm(); 
     359      
     360        if ($request->isMethod('post')) 
     361        { 
     362          $this->redirect('contact/thankyou?'.http_build_query($request->getParameter('contact'))); 
     363        } 
     364      } 
     365    } 
     366  
     367Puoi anche aver bisogno di cambiare l'attributo `action` della form nel template `indexSuccess.php`: 
     368 
     369    <form action="<?php echo url_for('contact/index') ?>" method="post"> 
     370 
     371Come vedremo più avanti, preferiamo usare questa sintassi perché è più corta e rende il codice più coerente e comprensibile. 
     372 
     373Configurare i Widget 
     374-------------------- 
     375 
     376### Opzioni dei widget 
     377 
     378Se un sito è gestito da diversi webmaster, ci piacerebbe certamente aggiungere un menù a tendina con i temi, per poter redirigere il messaggio a seconda di quanto viene richiesto (Figura 1-7). Il Listato 1-9 aggiunge un campo `subject` con un menù a tendina che usa il widget `sfWidgetFormSelect`. 
     379 
     380Figura 1-7 - Aggiungere un campo `subject` alla form 
     381 
     382![Aggiungere un campo `subject` alla form](http://www.symfony-project.org/images/forms_book/en/01_07.png "Aggiungere un campo `subject` alla form") 
     383 
     384Listato 1-9 - Aggiungere un campo `subject` alla form 
     385 
     386    [php] 
     387    class ContactForm extends sfForm 
     388    { 
     389      protected static $subjects = array('Subject A', 'Subject B', 'Subject C'); 
     390      
     391      public function configure() 
     392      { 
     393        $this->setWidgets(array( 
     394          'name'    => new sfWidgetFormInput(), 
     395          'email'   => new sfWidgetFormInput(), 
     396          'subject' => new sfWidgetFormSelect(array('choices' => self::$subjects)), 
     397          'message' => new sfWidgetFormTextarea(), 
     398        )); 
     399      
     400        $this->widgetSchema->setNameFormat('contact[%s]'); 
     401      } 
     402    } 
     403  
     404>**SIDEBAR** 
     405>The choices option of the sfWidgetFormSelect Widget 
     406> 
     407> PHP non fa alcuna distinzione tra array semplici e associative, quindi l'array che abbiamo usato per la lista dei `subject` è identica al codice sequente: 
     408> 
     409>    $subjects = array(0 => 'Subject A', 1 => 'Subject B', 2 => 'Subject C'); 
     410> 
     411> Il widget generato prende la chiave dell'array come valore dell'attributo del tag `option`, e il relativo valore come contenuto del tag: 
     412> 
     413> 
     414>    <select name="contact[subject]" id="contact_subject"> 
     415>      <option value="0">Subject A</option> 
     416>      <option value="1">Subject B</option> 
     417>      <option value="2">Subject C</option> 
     418>    </select> 
     419> 
     420> 
     421> Per poter cambiare gli attributi `value`, dobbiamo definire le chiavi dell'array: 
     422> 
     423>    $subjects = array('A' => 'Subject A', 'B' => 'Subject B', 'C' => 'Subject C'); 
     424> 
     425> Che genere il template HTML: 
     426> 
     427>    <select name="contact[subject]" id="contact_subject"> 
     428>      <option value="A">Subject A</option> 
     429>      <option value="B">Subject B</option> 
     430>      <option value="C">Subject C</option> 
     431>    </select> 
     432      
     433Il widget `sfWidgetFormSelect`, come tutti i widget, prende una lista di opzioni come primo argomento. Un'opzione può essere obbligatoria od opzionale. `sfWidgetFormSelectwidget` ha un'opzione obbligatoria, `choiches`. Ecco le opzioni disponibili per i widget che abbiamo già usato: 
     434 
     435------------------------------------------------------------------------------ 
     436| Widget               | Opzioni obbligatorie | Opzioni addizionali          | 
     437-----------------------+----------------------+------------------------------- 
     438| sfWidgetFormInput    | -                    | type (default to text)       | 
     439-----------------------+----------------------+------------------------------- 
     440|                      |                      | is_hidden (default to false) | 
     441-----------------------+----------------------+------------------------------- 
     442| sfWidgetFormSelect   | choices              | multiple (default to false)  | 
     443-----------------------+----------------------+------------------------------- 
     444| sfWidgetFormTextarea | -                    | -                            | 
     445------------------------------------------------------------------------------ 
     446 
     447>**TIP** 
     448>Se vuoi conoscere tutte le opzioni per un widget, puoi fare riferimento alla documentazioni completa delle API disponibile online su http://www.symfony-project.org/api/1_1/. Tutte le opzioni hanno una spiegazione, sia quelle addizionali che quelle di default. Per esempio, tutte le opzioni per `sfWidgetFormSelect` sono disponibili qui: http://www.symfony-project.org/api/1_1/sfWidgetFormSelect. 
     449 
     450### Gli attributi HTML dei widget 
     451 
     452Ogni widget accetta come secondo argomento opzionale una lista di attributi HTML. Questo è molto utile per definire degli attributi di default per i tag della form generati. Il Listato 1-10 mostra come aggiungere un attributo `class` al campo `email`. 
     453 
     454Listato 1-10 - Definire attributi per un widget 
     455 
     456    [php] 
     457    $emailWidget = new sfWidgetFormInput(array(), array('class' => 'email')); 
     458      
     459    // HTML generato 
     460    <input type="text" name="contact[email]" class="email" id="contact_email" /> 
     461  
     462Gli attributi HTML permettono anche di sovrascrivere l'identificatore generato automaticamente, come mostrato nel Listato 1-11. 
     463 
     464Listato 1-11 - Sovrascrivere l'attributo `id` 
     465 
     466    [php] 
     467    $emailWidget = new sfWidgetFormInput(array(), array('class' => 'email', 'id' => 'email')); 
     468      
     469    // HTML generato 
     470    <input type="text" name="contact[email]" class="email" id="email" /> 
     471 
     472È anche possibile impostare dei valori predefiniti usando l'attributo `value`, come mostra il Listato 1-12. 
     473 
     474Listato 1-12 - Valori predefiniti per i widget usando gli attributi HTML 
     475 
     476    [php] 
     477    $emailWidget = new sfWidgetFormInput(array(), array('value' => 'Your Email Here')); 
     478      
     479    // HTML generato 
     480    <input type="text" name="contact[email]" value="Your Email Here" id="contact_email" /> 
     481 
     482Questa opzione funziona per i widget `input`, ma è difficile da utilizzare con i widget `checkbox` o `radio`, e addirittura impossibile con un widget `textarea` La classe `sfForm` offre dei metodi specifici per definire dei valori predefiniti per ogni campo in un modo uniforme per tutti i tipi di widget. 
     483 
     484>**NOTE** 
     485>Raccomandiamo di definire gli atttributi HTML dentro al template e non nella form stesa (anche se è possibile) per preservare i livelli di separazione, come vedremo nel Capitolo tre. 
     486 
     487## Definire dei valori predefiniti per i campi 
     488 
     489Spesso è utile definire dei valori di default per ogni campo. Per esempio, quando mostriamo un messaggio di aiuto nel campo, che scompare quando l'utente fa click sul campo stesso. Il Listato 1-13 mostra come definire dei valori predefiniti usando i metodi `setDefault()` e `setDefaults()`. 
     490 
     491Listato 1-13 - Valori predefiniti dei widget usando i metodi `setDefault()` e `setDefaults()` 
     492 
     493    [php] 
     494    class ContactForm extends sfForm 
     495    { 
     496      public function configure() 
     497      { 
     498        // ... 
     499      
     500        $this->setDefault('email', 'Your Email Here'); 
     501      
     502        $this->setDefaults(array('email' => 'La tua email', 'name' => 'Il tuo nome')); 
     503      } 
     504    } 
     505 
     506I metodi `setDefault()` e `setDefaults()` sono molto utili per ogni istanza della stessa classe di form. Se vogliamo modificare un oggetto esistente che usa una form, i valori predefiniti dipenderanno dall'istanza, quindi devono essere dinamici. Il Listato 1-14 mostra che il costruttore `sfForm` ha un primo argomento che imposta i valori predefiniti dinamicamente. 
     507 
     508Listato 1-14 - Valori predefiniti dei widget usando il costruttore di `sfForm` 
     509 
     510    [php] 
     511    public function executeIndex($request) 
     512    { 
     513      $this->form = new ContactForm(array('email' => 'Your Email Here', 'name' => 'Your Name Here')); 
     514      
     515      // ... 
     516    } 
     517 
     518>**SIDEBAR** 
     519>Protezione dagliXSS (Cross-Site Scripting) 
     520> 
     521>Quando si impostano gli attributi HTML per i widget, o si definiscono dei valori predefiniti, la classe `sfForm` protegge automaticamente questi valori dagli attacchi XSS durante la generazione del codice HTML. Tale protezione non dipende dalla configurazione di `escaping_strategy` nel file `settings.yml`. Se un contenuto è già stato protetto da un altro metodo, la protezione non si applicherà ulteriormente. 
     522> 
     523>Protegge anche i caratteri ' e ", che possono invalidare il codice HTML generato. 
     524> 
     525>Ecco un esempio di tale protezione: 
     526> 
     527>    [php] 
     528>    $emailWidget = new sfWidgetFormInput(array(), array( 
     529>      'value' => 'Hello "World!"', 
     530>      'class' => '<script>alert("foo")</script>', 
     531>    )); 
     532>      
     533>    // HTML generato 
     534>    <input 
     535>      value="Hello &quot;World!&quot;" 
     536>      class="&lt;script&gt;alert(&quot;foo&quot;)&lt;/script&gt;" 
     537>      type="text" name="contact[email]" id="contact_email" 
     538>    /> 
     539 
     540}}}