Development

Documentation/pt_BR/forms_in_action/1.1/01-Criacao-de-Formulario (diff)

You must first sign up to be able to contribute.

Changes from Version 1 of Documentation/pt_BR/forms_in_action/1.1/01-Criacao-de-Formulario

Show
Ignore:
Author:
raphox (IP: 189.59.119.175)
Timestamp:
02/09/09 14:21:49 (9 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/pt_BR/forms_in_action/1.1/01-Criacao-de-Formulario

    v0 v1  
     1{{{ 
     2#!WikiMarkdown 
     3 
     4Capítulo 1 - Criação do Form 
     5============================ 
     6 
     7Um form é feitos de campos como inputs hidden, inputs text, combos e checkboxes. Esse capítulo ensina a você a criação e manipulação de campos de formulário usando o framework de forms symfony. 
     8 
     9É necessário o Symfony 1.1 para seguir os passos desse capítulo do livro. Você também ira precisar criar um projeto e um aplicativo chamado `frontend` para continuar. Por favor, olhe a introdução para mais informações sobre a criação de um projeto symfony. 
     10 
     11Antes de Iniciar 
     12---------------- 
     13 
     14Vamos começar adicionando um formulário de contato em uma aplicação symfony 
     15 
     16Figura 1-1 Mostra o formulário de contato como visto pelos usuário que querem enviar uma mensagem. 
     17 
     18Figura 1-1 - Formulário de contato 
     19 
     20![Formulário de contato](/images/forms_book/en/01_01.png "Formulário de contato") 
     21 
     22Nós vamos criar 3 campos para este formulário: o nome do usuário, o email do usuário e a mensagem que o usuário quer enviar. Vamos simplesmente mostrar a informação submetida no formulário para o propósito deste exercício como mostrado na figura 1-2. 
     23 
     24Figura 1-2 - Página de Agradecimento 
     25 
     26![Página de Agradecimento](/images/forms_book/en/01_02.png "Página de Agradecimento") 
     27 
     28Figura 1-3 - Interação entre a aplicação e o usuário 
     29 
     30![Interação entre a aplicação e o usuário](/images/forms_book/en/01_03.png "Interação entre a aplicação e o usuário") 
     31 
     32Widgets 
     33------- 
     34 
     35### Classes `sfForm` e `sfWidget`  
     36 
     37O usuário digita informação nos campos que compõe os formulários. No symfony um form é uma herança de objeto da classe `sfForm`. No nosso exemplo, nós vamos criar uma classe `ContactForm` que herda a classe `sfForm`. 
     38 
     39>**Nota** 
     40>`sfForm` é a classe base de todos os formulários e torna facil gerenciar a configuração e vida dos seus formulários. 
     41 
     42Você pode iniciar a configuração de seu formulário adicionando **widgets** com o método `configura()` 
     43 
     44Um **widget** representa um campo do formulário. Para nosso formulário de exemplo, nós precisamos adicionar 3 widgets que representam nossos três campos: `name`, `email`, e `message`. Listagem 1-1 mostra a primeira implementação da classe `ContactForm` 
     45 
     46Listagem 1-1 - Classe `ContactForm` com três campos 
     47 
     48    [php] 
     49    // lib/form/ContactForm.class.php 
     50    class ContactForm extends sfForm 
     51    { 
     52      public function configura() 
     53      { 
     54        $this->setWidgets(array( 
     55          'name'    => new sfWidgetFormInput(), 
     56          'email'   => new sfWidgetFormInput(), 
     57          'message' => new sfWidgetFormTextarea(), 
     58        )); 
     59      } 
     60    } 
     61 
     62Os widgets são definidos no método `configura()`. Esse método é automaticamente chamado pelo construtor da classe `sfForm` 
     63 
     64O método `setWidgets()` é usado para definir os widgets usados no form. O método `setWidgets()` aceita um array associativo onde as chaves são os nomes do campos e os valores são classes widget. Cada widget é um objeto que herda a classe `sfWidget`. Para esse exemplo nós usamos dois tipos de widgets: 
     65 
     66  * `sfWidgetFormInput`  : Esse widget representa um campo `input`. 
     67  * `sfWidgetFormTextarea`: Esse widget representa um campo`textarea`. 
     68 
     69>**Nota** 
     70> Como convenção, nós guardamos as classes de form no diretório `lib/form`. Você pode guardar elas em qualquer diretório gerenciado pelo mecanismo de autoloading do symfony, mas como vamos ver mais tarde, o symfony usa o diretório `lib/form` para gerar formulários baseados em objetos de modelo(ORM) 
     71 
     72### Mostrando o Formulário 
     73 
     74Nosso formulário agora esta pronto para ser usado. Nós agora podemos criar um módulo symfony para mostrar o formulário: 
     75 
     76    $ cd ~/CAMINHO/PARA/O/PROJETO 
     77    $ php symfony generate:module frontend contact 
     78 
     79No módulo `contact`, vamos modificar a action `index` para passar uma instancia do formulário para o template, conforme a Listagem 1-2. 
     80 
     81Listagem 1-2 - Classe Actions do módulo `contact` 
     82 
     83    [php] 
     84    // apps/frontend/modules/contact/actions/actions.class.php 
     85    class contactActions extends sfActions 
     86    { 
     87      public function executeIndex() 
     88      { 
     89        $this->form = new ContactForm(); 
     90      } 
     91    } 
     92 
     93Quando criando um formulário, o método `configura()`, definido anteriormente, vai ser chamado automaticamente. 
     94 
     95Agora nós só precisamos criar um template para mostrar o formulário, como mostrado na Listagem 1-3. 
     96 
     97Listagem 1-3 - Template mostrando o formulário 
     98 
     99    [php] 
     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 
     112Um formulário do symfony somente gerencia os widgets mostrando informações ao usuário. No template `indexSuccess`, a linha `<?php echo $form ?>` mostra apenas três campos. Os outros elementos, como a tag `form` e o botão de submit precisam ser adicionados pelo desenvolvedor. Isso não parece óbvio no inicio, mas como vamos depois como é fácil injetar formulários. 
     113 
     114Usar essa construção `<?php echo $form ?>` é muito bom para criação de protótipos e definindo os formulários. Isso permite que os desenvolvedores se concentrem nas regras de negócio sem se preocupar com aspectos visuais. O capitulo três vai explicar como personalizaro template e o layout do formulário. 
     115 
     116>**Nota** 
     117Ao mostrar um objeto usando `<?php echo $form ?>`, a engine PHP vai realmente mostrar a representação textual do objeto `$form`. Para converter um objeto em uma string, o PHP tenta executar o metódo mágico `__toString()`. Cada widget implementa este método mágico para converter o objeto em código HTML. Chamando `<?php echo $form ?>` é o mesmo que chamar `<?php echo $form->__toString() ?>`. 
     118 
     119Agora nós podemos ver o formulário em um navegador (Figura 1-4) e verificar o resultado digitando o endereço da ação `contact/index` (`/frontend_dev.php/contact`). 
     120 
     121Figura 1-4 - Formulário de Contato(Contact) Gerado 
     122 
     123![Formulário de Contato(Contact) Gerado](/images/forms_book/en/01_04.png "Formulário de Contato(Contact) Gerado") 
     124 
     125Listagem 1-4 Mostra o código gerado no template. 
     126 
     127    [html] 
     128    <form action="/frontend_dev.php/contact/submit" method="POST"> 
     129      <table> 
     130         
     131        <!-- Beginning of generated code by <?php echo $form ?> --> 
     132        <tr> 
     133          <th><label for="name">Name</label></th> 
     134          <td><input type="text" name="name" id="name" /></td> 
     135        </tr> 
     136        <tr> 
     137          <th><label for="email">Email</label></th> 
     138          <td><input type="text" name="email" id="email" /></td> 
     139        </tr> 
     140        <tr> 
     141          <th><label for="message">Message</label></th> 
     142          <td><textarea rows="4" cols="30" name="message" id="message"></textarea></td> 
     143        </tr> 
     144        <!-- End of generated code by <?php echo $form ?> --> 
     145 
     146        <tr> 
     147          <td colspan="2"> 
     148            <input type="submit" /> 
     149          </td> 
     150        </tr> 
     151      </table> 
     152    </form> 
     153 
     154Podemos ver que o formulário é exibido com três linhas `<tr>` de uma tabela HTML. Esse é o motivo de termos que fechar a tag `<table>`. Cada linha inclui uma tag `<label>` e uma tag de formulário (`<input>` ou `<textarea>`). 
     155 
     156### Rótulos(Labels) 
     157 
     158Os rótulos de cada campo são gerados automaticamente. Por padrão, rótulos são a transformação do nome do campo seguindo as seguintes regras: Capitalizar a primeira letra e traço é trocado para espaço. 
     159 
     160Exemplo: 
     161 
     162    [php] 
     163    $this->setWidgets(array( 
     164      'first_name' => new sfWidgetFormInput(), // rótulo gerado: "First name" 
     165      'last_name'  => new sfWidgetFormInput(), // rótulo gerado: "Last name" 
     166    )); 
     167  
     168Mesmo se a geração automática de rótulos é útil, o framework permite que você defina rótulos personalizados com o método `setLabels()`: 
     169 
     170Como definir: 
     171 
     172    [php] 
     173    $this->widgetSchema->setLabels(array( 
     174      'name'    => 'Your name', 
     175      'email'   => 'Your email address', 
     176      'message' => 'Your message', 
     177    )); 
     178 
     179Você pode também modificar somente um único rótulo com o método `setLabel()`; 
     180 
     181    [php] 
     182    $this->widgetSchema->setLabel('email', 'Your email address'); 
     183 
     184Finalmente, iremos ver no capítulo três que você pode extender os rótulos no template para personalizar o form. 
     185 
     186>**Sidebar** 
     187>Widget Schema 
     188> 
     189> Quando usamos o método `setWidgets()`, o symfony cria um objeto `sfWidgetFormSchema`. Esse objeto é um widget que permite que você represente um grupo de widgets. Em nosso formulário de contato, nós chamamos o método `setWidgets()`. Isso é equivalente ao código a seguir: 
     190> 
     191>     [php] 
     192>     $this->setWidgetSchema(new sfWidgetFormSchema(array( 
     193>       'name'    => new sfWidgetFormInput(), 
     194>       'email'   => new sfWidgetFormInput(), 
     195>       'message' => new sfWidgetFormTextarea(), 
     196>     ))); 
     197> 
     198>     // também equivalente há: 
     199> 
     200>     $this->widgetSchema = new sfWidgetFormSchema(array( 
     201>       'name'    => new sfWidgetFormInput(), 
     202>       'email'   => new sfWidgetFormInput(), 
     203>       'message' => new sfWidgetFormTextarea(), 
     204>     )); 
     205> 
     206>O método `setLabels()` é aplicado a coleção de widgets incluídos no objeto `widgetSchema`. 
     207> 
     208>Vamos ver no capítulo 5 que a noção de "schema widget" faz o gerenciamento de formulários agrupados bem mais simples. 
     209 
     210### Indo além das tabelas geradas 
     211 
     212Mesmo o formulário sendo mostrado por padrão como uma tabela HTML, o formato do layout pode ser modificado. Esse diferentes tipos de layout são definidos em classes que herdam a classe `sfWidgetFormSchemaFormatter`. Por padrão, um formulário o formato `table` como definido na classe `sfWidgetFormSchemaFormatterTable`. Você pode também usar o formato `list`: 
     213 
     214    [php] 
     215    class ContactForm extends sfForm 
     216    { 
     217      public function configura() 
     218      { 
     219        $this->setWidgets(array( 
     220          'name'    => new sfWidgetFormInput(), 
     221          'email'   => new sfWidgetFormInput(), 
     222          'message' => new sfWidgetFormTextarea(), 
     223        )); 
     224 
     225        $this->widgetSchema->setFormFormatterName('list'); 
     226      } 
     227    } 
     228 
     229Esses dois formatos vem por padrão, no capítulo 5 vamos ver como criar nossos próprios classes de formato. Agora que sabemos como mostrar um formulário, vamos ver como controlar a submissão. 
     230 
     231### Submetendo o formulário 
     232 
     233Quando criamos um template para mostrar um formulário, usamos a URL interna `contact/submit` na tag `form` para enviar o form. Agora precisamos criar a action `submit` no módulo `contact`. A Listagem 1-5 mostra como a ação pode pegar a informação do usuário e redirecionar para uma pagina de agradecimento onde apenas mostramos as informações novamente pro usuário. 
     234 
     235Listagem 1-5 - Uso da action `submit` no módulo `contact` 
     236 
     237    [php] 
     238    public function executeSubmit($request) 
     239    { 
     240      $this->forward404Unless($request->isMethod('post')); 
     241 
     242      $params = array( 
     243        'name'    => $request->getParameter('name'), 
     244        'email'   => $request->getParameter('email'), 
     245        'message' => $request->getParameter('message'), 
     246      ); 
     247 
     248      $this->redirect('contact/thankyou?'.http_build_query($params)); 
     249    } 
     250 
     251    public function executeThankyou() 
     252    { 
     253    } 
     254 
     255    // apps/frontend/modules/contact/templates/thankyouSuccess.php 
     256    <ul> 
     257      <li>Name:    <?php echo $sf_params->get('name') ?></li> 
     258      <li>Email:   <?php echo $sf_params->get('email') ?></li> 
     259      <li>Message: <?php echo $sf_params->get('message') ?></li> 
     260    </ul> 
     261 
     262>**Nota** 
     263>`http_build_query` é uma função nativa do PHP que gera uma string codificada como URL a partir de um array de paramêtros. 
     264 
     265o método `executeSubmit()` executa três ações: 
     266 
     267  * Por razões de segurança, checamos se a página foi submetida usando o método HTTP `POST`. Se não foi usado este método, o usuário é redirecionado para uma pagina de erro 404. No template `indexSuccess`, declaramos o método de envio como `POST` (`<form ... method="POST">`): 
     268 
     269        [php] 
     270        $this->forward404Unless($request->isMethod('post')); 
     271 
     272  * A seguir pegamos os valores digitados pelo usuário e guardamos na tabela `params`: 
     273 
     274        [php] 
     275        $params = array( 
     276          'name'    => $request->getParameter('name'), 
     277          'email'   => $request->getParameter('email'), 
     278          'message' => $request->getParameter('message'), 
     279        ); 
     280 
     281  * Por fim, redirecionamos o usuário para a página de agradecimento(`contact/thankyou`) para mostrar as informações dele: 
     282 
     283        [php] 
     284        $this->redirect('contact/thankyou?'.http_build_query($params)); 
     285 
     286Ao invés de redirecionar o usuário para outra página, poderiamos ter criado um template `submitSuccess.php`. Mesmo sendo isso possível, é uma boa prática sempre redirecionar o usuário após uma requisição do método `POST`: 
     287 
     288  * Isso previne a dupla requisição caso o usuário recarrege a página de agradecimento. 
     289 
     290  * O usuário pode clicar no botão de Voltar sem precisar ficar clicando na pop-up de aviso de reenvio de informações de formulário. 
     291 
     292>**Dica** 
     293>Voçê deve ter notado que o método `executeSubmit()` é diferente do `executeIndex()`. Ao chamar esses métodos o symfony passa o objeto `sfRequest` atual como primeiro argumento dos métodos `executeXXX()`. Em PHP, você não precisa coletar todos os parametrôs, por isso que você não define a variavel `request` no método `executeIndex()` ja que você não precisa dela. 
     294 
     295Figura 1-5 mostra o fluxo dos métodos ao interagir com o usuário. 
     296 
     297Figura 1-5 - Fluxo dos métodos 
     298 
     299![Fluxo dos métodos](/images/forms_book/en/01_05.png "Fluxo dos métodos") 
     300 
     301>**Nota** 
     302> Ao mostrar novamente as informações que o usuário digitou no template, você corre o risco de um ataque XSS(Cross-Site Scripting). Você pode achar maiores informações sobre como previnir esses tipos de ataque implementando uma estratégia de escape no capítulo [Inside the View Layer](http://www.symfony-project.org/book/1_1/07-Inside-the-View-Layer#Output%20Escaping) do livro "The Definitive Guide to symfony". 
     303 
     304Após submeter o formulário, você deve ver agora a pagina conforme a Figura 1-6. 
     305 
     306Figura 1-6 - Página mostrada após enviar o formulário 
     307 
     308![Página mostrada após enviar o formulário](/images/forms_book/en/01_06.png "Página mostrada após enviar o formulário") 
     309 
     310Invés de criar o array `params`, é mais fácil pegar a informação vinda do usuário diretamente em um array. 
     311Listagem1-6 modifica o atributo HTML `name` dos widgets para armazenar os valores dos campos no array `contact`. 
     312 
     313Listagem1-6 - Modifica o atributo HTML `name` dos widgets 
     314 
     315    [php] 
     316    class ContactForm extends sfForm 
     317    { 
     318      public function configura() 
     319      { 
     320        $this->setWidgets(array( 
     321          'name'    => new sfWidgetFormInput(), 
     322          'email'   => new sfWidgetFormInput(), 
     323          'message' => new sfWidgetFormTextarea(), 
     324        )); 
     325 
     326        $this->widgetSchema->setNameFormat('contact[%s]'); 
     327      } 
     328    } 
     329 
     330Chamando `setNameFormat()` nos permite modificar o atributo HTML `name` de todos os widgets. `%s` vai ser automaticamente trocado pelo nome do campo durante a geração do formulário. Por exemplo, o atributo `name` sera `contact[email]` para o campo `email`. O PHP automaticamente cria um array com os valores do request incluindo um no formato `contact[email]`. Dessa forma os valores dos campo estarão disponíves no array `contact`. 
     331 
     332Nós agora podemos acessar diretamente o array `contact` do objeto `request` como mostrado na Listagem 1-7 
     333 
     334Listagem 1-7 - Novo formato dos atributos `name` na action 
     335 
     336    [php] 
     337    public function executeSubmit($request) 
     338    { 
     339      $this->forward404Unless($request->isMethod('post')); 
     340 
     341      $this->redirect('contact/thankyou?'.http_build_query($request->getParameter('contact'))); 
     342    } 
     343 
     344Ao olhar o fonte HTML do formulário, você podera ver que o symfony gerou o atributo `name` dependendo não apenas do nome do campo e do formato, mas também do atributo `id`. O atributo `id` é automaticamente criado a partir do atributo `name` trocando os caracteres invalidos por traços (`_`): 
     345 
     346  | **Nome**  | **Atributo `name`**  | **Atributo  `id`**  | 
     347  | --------- | -------------------- | ------------------- | 
     348  | name      | contact[name]        | contact_name        | 
     349  | email     | contact[email]       | contact_email       | 
     350  | message   | contact[message]     | contact_message     | 
     351 
     352### Outra solução 
     353 
     354Neste exemplo, usamos duas actions para controlar o formulário: `index` para mostra-lo, `submit` para enviar-lo. Sendo o formulário mostrado com o método `GET` e enviado com o método `POST`, podemos mesclar esses dois métodos no `index`, como mostrado na Listagem 1-8. 
     355 
     356Listagem 1-8 - Mesclagem de duas actions usadas no formulário 
     357 
     358    [php] 
     359    class contactActions extends sfActions 
     360    { 
     361      public function executeIndex($request) 
     362      { 
     363        $this->form = new ContactForm(); 
     364 
     365        if ($request->isMethod('post')) 
     366        { 
     367          $this->redirect('contact/thankyou?'.http_build_query($request->getParameter('contact'))); 
     368        } 
     369      } 
     370    } 
     371 
     372Você também precisa mudar o atributo `action` do formulário no template `indexSuccess.php`: 
     373 
     374    [php] 
     375    <form action="<?php echo url_for('contact/index') ?>" method="POST"> 
     376 
     377Como veremos depois, nós preferimos usar essa forma ja que ela é menor e torna o código mais coerente e legivel. 
     378 
     379configurando os Widgets 
     380----------------------- 
     381 
     382### Opções dos Widgets 
     383 
     384Se website é controlado por varios webmasters, nós com certeza gostariamos de adicionar uma combo com temas para redirecionar a mensagem de acordo com o que é pedido.(Figura 1-7). A Listagem 1-9 adiciona um `subject` com uma combo usando o widget `sfWidgetFormSelect`. 
     385 
     386Figura 1-7 - Adicionado o campo`subject` ao Formulário 
     387 
     388![Adicionado o campo`subject` ao Formulário](/images/forms_book/en/01_07.png "Adicionado o campo`subject` ao Formulário") 
     389 
     390Listagem 1-9 - Adicionado o campo`subject` ao Formulário 
     391 
     392    [php] 
     393    class ContactForm extends sfForm 
     394    { 
     395      protected static $subjects = array('Subject A', 'Subject B', 'Subject C'); 
     396 
     397      public function configura() 
     398      { 
     399        $this->setWidgets(array( 
     400          'name'    => new sfWidgetFormInput(), 
     401          'email'   => new sfWidgetFormInput(), 
     402          'subject' => new sfWidgetFormSelect(array('choices' => self::$subjects)), 
     403          'message' => new sfWidgetFormTextarea(), 
     404        )); 
     405 
     406        $this->widgetSchema->setNameFormat('contact[%s]'); 
     407      } 
     408    } 
     409 
     410>**SIDEBAR** 
     411>A opção `choices` do widget `sfWidgetFormSelect` 
     412> 
     413>O PHP não diferencia um array de um array associativo, então o array que usamos na lista de `subjects` é o mesmo que o código a seguir: 
     414> 
     415>     [php] 
     416>     $subjects = array(0 => 'Subject A', 1 => 'Subject B', 2 => 'Subject C'); 
     417> 
     418>O widget gerado pega a chave do array para o atributo `value` da tag  `option` e o valor como conteudo da tag: 
     419> 
     420>     [php] 
     421>     <select name="contact[subject]" id="contact_subject"> 
     422>       <option value="0">Subject A</option> 
     423>       <option value="1">Subject B</option> 
     424>       <option value="2">Subject C</option> 
     425>     </select> 
     426> 
     427>Para alterar o atributo `value`, só precisamos definir as chaves do array: 
     428> 
     429>     [php] 
     430>     $subjects = array('A' => 'Subject A', 'B' => 'Subject B', 'C' => 'Subject C'); 
     431> 
     432>Que gera o seguinte HTML: 
     433> 
     434>     [php] 
     435>     <select name="contact[subject]" id="contact_subject"> 
     436>       <option value="A">Subject A</option> 
     437>       <option value="B">Subject B</option> 
     438>       <option value="C">Subject C</option> 
     439>     </select> 
     440 
     441O widget `sfWidgetFormSelect', assim como todos os outros, pega uma lista de opções como primeiro argumento. Uma opção pode ser obrigatória ou opcional. O widget `sfWidgetFormSelect` possui uma opção obrigatória, `choices`. Aqui esta as opções disponíveis para todos os widgets que usamos até aqui: 
     442 
     443  | **Widget**             | **Opções Obrigatórias** | **Opções Adicionais**            | 
     444  | ---------------------- | ----------------------- | -------------------------------- | 
     445  | `sfWidgetFormInput`    | -                       | `type` (padrão é `text`)         | 
     446  |                        |                         | `is_hidden` (padrão é `false`)   | 
     447  | `sfWidgetFormSelect`   | `choices`               | `multiple` (padrão é `false`)    | 
     448  | `sfWidgetFormTextarea` | -                       | -                                | 
     449 
     450>**Dica** 
     451> Se você que conhecer todas as opções para um widget, você olhar documentação completa da API disponível online em ([http://www.symfony-project.org/api/1_1/](http://www.symfony-project.org/api/1_1/)). Todas as opções são explicadas, assim como os valores padrões da opções adicionais. Por exemplo, todas as opções do widget `sfWidgetFormSelect` estão aqui: ([http://www.symfony-project.org/api/1_1/sfWidgetFormSelect](http://www.symfony-project.org/api/1_1/sfWidgetFormSelect)). 
     452 
     453### Os atributos HTML dos Widgets 
     454 
     455Cada widget também pega uma lista de atributos HTML como segundo parametro opcional. Isso é extremamente útil para definir valores padrão da tag gerada. A Listagem 1-10 mostra como adicionar o atributo `class` no campo `email` 
     456 
     457Listagem 1-10 - Definindo atributos para um Widget 
     458 
     459    [php] 
     460    $emailWidget = new sfWidgetFormInput(array(), array('class' => 'email')); 
     461 
     462    // Generated HTML 
     463    <input type="text" name="contact[email]" class="email" id="contact_email" /> 
     464 
     465 
     466Atributos HTML permitem também que nós sobrescrevamos o identificador gerado automaticamente, como mostrado na Listagem 1-11. 
     467 
     468Listagem 1-11 - Sobrescrevendo o atributo `id` 
     469 
     470    [php] 
     471    $emailWidget = new sfWidgetFormInput(array(), array('class' => 'email', 'id' => 'email')); 
     472 
     473    // Generated HTML 
     474    <input type="text" name="contact[email]" class="email" id="email" /> 
     475 
     476É possivel ainda colocar valores padrão nos campos usando o atributo `value`, como mostra a Listagem 1-12. 
     477 
     478Listagem 1-12 - Valores Default nos Widgets via atributos HTML 
     479 
     480    [php] 
     481    $emailWidget = new sfWidgetFormInput(array(), array('value' => 'Your Email Here')); 
     482 
     483    // Generated HTML 
     484    <input type="text" name="contact[email]" value="Your Email Here" id="contact_email" /> 
     485 
     486Essa opção funciona para widgets `input`, mas é dificil fazer o mesmo com os widgets `checkbox` ou `radio`, e é impossivel com o widget `textarea`.  A classe `sfForm` tem métodos especificos  para definir valores padrão para cada campo de um forma uniforme para qualquer tipo de widget. 
     487 
     488 
     489>**Nota** 
     490> Recomendamos definir os atributos HTML dentro dos templates e não no formulário(se forpossível) para presevar a separação em camadas, que vamos ver no capítulo três. 
     491 
     492### Definindo valores padrão para os campos 
     493 
     494 
     495Muitas vezes é util definir valores padrão para cada campo. Por exemplo quando vamos mostrar uma mensagem de ajuda em cada campo quando o usuário estiver naquele campo. A Listagem 1-13 mostra como definir valores padão com os métodos` setDefault()` e `setDefaults()`. 
     496 
     497Listagem 1-13 - Valores padrão para Widget via `setDefault()` e `setDefaults()` 
     498 
     499    [php] 
     500    class ContactForm extends sfForm 
     501    { 
     502      public function configura() 
     503      { 
     504        // ... 
     505 
     506        $this->setDefault('email', 'Your Email Here'); 
     507 
     508        $this->setDefaults(array('email' => 'Your Email Here', 'name' => 'Your Name Here')); 
     509      } 
     510    } 
     511 
     512Os métodos `setDefault()` e `setDefaults()` são muitos para definir valores padrão iguais para cada instancia de uma mesma classe de formulário. Se você quer modificar um objeto existente usando um formulário, os valores padrão irão depender dessa instancia, portanto, eles devem ser dinâmicos. A listagem 1-14 mostra que o construtor da classe `sfForm` recebe como primeiro argumento uma lista de valores padrões que seta dinamicamente os valores padrão 
     513 
     514Listagem 1-14 - Valores padrão via construtor da classe `sfForm` 
     515 
     516    [php] 
     517    public function executeIndex($request) 
     518    { 
     519      $this->form = new ContactForm(array('email' => 'Your Email Here', 'name' => 'Your Name Here')); 
     520 
     521      // ... 
     522    } 
     523 
     524>**SIDEBAR** 
     525>Proteção XSS (Cross-Site Scripting) 
     526> 
     527>Ao setr atributos HTML para widgets ou definindo valores padrão, a classe `sfForm` automaticamente protege esses valores contra ataques XSS durante a geração do código HTML. Essa proteção não depende da configuração `escaping_strategy` do arquivo `settings.yml`. Se um valor ja foi protegido por outro método, essa proteção não sera aplicada novamente. 
     528> 
     529>Ele também protege contra os caracteres  `'` and `"`  que podem invalidar o HTML gerado. 
     530> 
     531>Um exemplo dessa proteção: 
     532> 
     533>     [php] 
     534>     $emailWidget = new sfWidgetFormInput(array(), array( 
     535>       'value' => 'Hello "World!"', 
     536>       'class' => '<script>alert("foo")</script>', 
     537>     )); 
     538>      
     539>     // HTML gerado 
     540>     <input 
     541>       value="Hello &quot;World!&quot;" 
     542>       class="&lt;script&gt;alert(&quot;foo&quot;)&lt;/script&gt;" 
     543>       type="text" name="contact[email]" id="contact_email" 
     544>     /> 
     545 
     546}}}