Capítulo 4 - Introdução a criação de Páginas
Curiosamente o primeiro tutorial que os programadores utilizam para aprender qualquer linguagem ou framework, é o que mostra na tela "Olá, Mundo" (do inglês Hello, World!). É estranho acreditar que um computador seja capaz de cumprimentar todo mundo, já que todas as tentativas no campo da inteligência artificial resultaram em sistemas de conversação bastante pobres. Mas o Symfony não é tão bobo como os outros programas, e a prova é que se pode criar uma página que mostra a mensagem "Olá, seu nome".
Neste capítulo vamos mostrar como criar um módulo, que é o elemento que agrupa as páginas. Também aprenderemos como criar uma página, que por sua vez se divide em uma ação e um template (modelo), seguindo o padrão MVC. As interações básicas entre as páginas web se realizam mediante links e formulários; Você verá como inseri-los em um template e manipulá-los nas ações.
Criando o esqueleto do módulo
Como visto no capítulo 2, Symfony agrupa as páginas em módulos. Portanto, antes de criar uma página é necessário criar um módulo, que inicialmente não é mais que uma estrutura vazia de diretórios e arquivos que o Symfony pode reconhecer.
A linha de comando do Symfony automatiza a criação dos módulos. Só é necessário chamar a tarefa init-module indicando como argumentos o nome da aplicação e o nome do novo módulo. No capítulo anterior foi criada uma aplicação chamada minhaaplic. Para adicionar o módulo chamado meumodulo é necessário executar os seguintes comandos:
> cd ~/meuprojeto
> symfony init-module minhaaplic meumodulo
>> dir+ ~/meuprojeto/apps/minhaaplic/modules/meumodulo/templates
>> file+ ~/meuprojeto/apps/minhaaplic/modules/meumodulo/templates/indexSuccess.php
>> dir+ ~/meuprojeto/apps/minhaaplic/modules/meumodulo/validate
>> dir+ ~/meuprojeto/apps/minhaaplic/modules/meumodulo/config
>> dir+ ~/meuprojeto/apps/minhaaplic/modules/meumodulo/actions
>> file+ ~/meuprojeto/apps/minhaaplic/modules/meumodulo/actions/actions.class.php
>> dir+ ~/meuprojeto/apps/minhaaplic/modules/meumodulo/lib
>> file+ ~/meuprojeto/test/functional/minhaaplic/meumoduloActionsTest.php
>> tokens ~/meuprojeto/test/functional/minhaaplic/meumoduloActionsTest.php
>> tokens ~/meuprojeto/apps/minhaaplic/modules/meumodulo/templates/indexSuccess.php
>> tokens ~/meuprojeto/apps//modules/meumodulo/actions/actions.class.php
Além dos diretórios (pastas) actions/, config/, lib/, templates/, e validate/, este comando cria 3 arquivos. O arquivo que se encontra no diretório /test tem relação com os testes de unidade, que veremos no capítulo 15. O arquivo actions.class.php (mostrado na lista 4-1) redireciona a ação para a página de bem vindo do módulo por padrão. Por último, o arquivo templates/indexSuccess.php está vazio.
Lista 4-1 - A ação gerada por padrão, em actions/actions.class.php
<?php class meumoduloActions extends sfActions { public function executeIndex() { $this->forward('default', 'module'); } } ?>
NOTA Se você abrir o arquivo
actions.class.phpgerado realmente, seu conteúdo é muito maior que as poucas linhas mostradas anteriormente, incluindo um monte de comentários. Symfony recomenda o uso de comentários PHP para documentar o projeto e por tanto adiciona a cada arquivo de cada classe comentários que são compatíveis com o formato da ferramenta phpDocumentator (http://www.phpdoc.org/).
Em cada novo módulo, Symfony cria uma ação por padrão chamada index. A ação completa é composta do método executeIndex da ação e do arquivo de template chamado de indexSuccess.php. O significado do prefixo execute e do sufixo Sucess serão explicados com detalhes nos capítulos 6 e 7 respectivamente. Por enquanto considere que esta forma de nomear os arquivos e métodos é uma convenção que o Symfony segue. Para visualizar a página gerada (veja a figura 4-1) acesse via navegador a seguinte URL:
http://localhost/minhaaplic_dev.php/meumodulo/index
Neste capítulo não utilizamos a ação index, então, é possível remover o método executeIndex() do arquivo acoes.class.php e também é possível remover o arquivo indexSuccess.php do diretório templates/.
NOTA Symfony permite criar os módulos sem a necessidade de utilizar a linha de comandos. Uma maneira é você criar os diretórios e arquivos manualmente. Em muitos casos, as ações e os templates de um módulo servem para manipular dados de uma tabela do banco de dados. Como o código necessários para criar, obter, atualizar e remover os dados são quase sempre os mesmos, o Symfony incorpora uma técnica chamada
scaffolding(literalmente traduzido como Andaimes) que permitem gerar automaticamente todo o código PHP do módulo. O capítulo 14 contêm todos os detalhes dessa técnica.
Figura 4-1 - A página de índice gerada por padrão
Adicionando uma página
No Symfony, a lógica por de trás das páginas é armazenada em uma ação, e a apresentação está definida nos templates. Páginas que não requerem programação, precisam definir, ainda assim, uma ação vazia.
Adicionando uma Ação
A página "Olá, mundo!" será acessível através de uma ação minhaAcao. Para criá-la, apenas adicione um método executeMinhaAcao para a classe meumoduloAcoes, como mostrado na Listagem 4-2.
Listagem 4-2 - Adicionar uma Ação É Como Adicionar um Método Executar para a Classe Ação
<?php class meumoduloActions extends sfActions { public function executeMinhaAcao() { } } ?>
O nome do método de ação é sempre `executeXxx()`, aonde a segunda parte do nome é o nome da ação com a primeira letra maiuscúla.
Agora, se você requisitar a seguinte URL:
http://localhost/minhaaplic_dev.php/meumodulo/minhaAcao
symfony iŕa reclamar que o template minhaAcaoSuccess.php está faltando. Isto é normal; em symfony, uma página é sempre feita de uma ação e um template.
CUIDADO URLs (e não nomes de domínio) são sensíveis a caixa, e assim é o symfony (mesmo que o nome de métodos sejam insensíveis a caixa em PHP). Isto significa que se você adicionar um método
executeminhaacao(), ou umexecuteMinhaacao(), e então você chamarminhaAcaocom o navegador, symfony irá retornar um erro 404.
BARRA LATERAL URLs fazem parte da resposta
Symfony contém um sistema de roteamento que permite que você tenha uma separação completa entre o nome da ação real e o formato da URL que precisa ser chamada. Isto permite uma formatação personalizada da URL como se ela fosse parte da resposta. Você não é mais limitado pela estrutura de arquivos, nem pelos parâmetros de requisição; a URL para uma ação pode se parecer com a frase que você quiser. Por exemplo, a chamada para ação de índice(index) de um módulo chamado artigo normalmente se parece com isto:
http://localhost/minhaaplic_dev.php/artigo/index?id=123Esta URL recupera um artigo fornecido por um banco de dados. Neste exemplo, ela recupera um artigo (com
id=123) na seção Europa que discute especificamente as finanças na França. Mas a URL pode ser escrita de uma maneira completamente diferente com uma simples modificação no arquivo de configuraçãorouting.yml:http://localhost/artigos/europa/franca/financa.htmlNão apenas a URL resultante é mais amigável para um mecanismo de busca, ela também possui mais significado agregado para o usuário, que pode então usar a barra de endereços como uma pseudo linha de comando para fazer buscas personalizadas, como na URL seguinte:
http://localhost/artigos/marcados/financa+franca+euroSymfony sabe como interpretar e gerar URLs inteligentes para o usuário. O sistema de roteamento automaticamente destrincha os parâmetros de requisição de URL inteligente e as torna disponíveis para a ação. Ele também formata as hiperligações incluídas na resposta para que elas se pareçam "inteligentes." Você irá aprender mais sobre esta característica no capítulo 9.
Sobretudo, isto significa que a maneira que você nomeia as ações de suas aplicações não devem ser influenciadas pela maneira que as URL usadas para fazer chamadas a elas devem parecer, mas sim pelas funções das ações na aplicação. O nome de uma ação explica o que a ação faz realmente, e é frequentemente um verbo no infinitivo (como
show[mostrar],list[listar],edit[editar], e assim por diante). O nome das ações podem se tornar totalmente invisíveis ao usuário final, então não hesite em usar nomes de ações explícitas (comolistarPorNomeoumostrarComComentarios). Você irá economizar comentários no código para explicar as ações de sua função, além do que o código será muito mais fácil de ler.
Adicionando um Template
Uma ação espera um template para ser gerada. Um template é um arquivo localizado no diretório templates/ de um módulo, nomeado pela ação e o término da ação. O término de uma ação normal é um "sucesso", então o arquivo de template a ser criado para a ação minhaAcao deve ser chamado minhaAcaoSuccess.php.
Templates devem, supostamente, conter apenas código de apresentação, então mantenha o mínimo quanto possível de código PHP neles. Na verdade, uma página exibindo "Ola, mundo!" pode ter um template tão simples quanto aquele na Listagem 4-3.
Listagem 4-3 - O Template meumodulo/templates/minhaAcaoSuccess.php
<p>Olá, mundo!</p>
Se você precisar executar algum código em PHP no template, você deveria evitar usar a sintaxe usual do PHP, como exibido na Listagem 4-4. Ao invés disso, escreva seus templates usando a sintaxe alternativa do PHP, como exibido na Listagem 4-5, para manter o código inteligível para programadores que não sabem PHP. Não apenas o código final estará corretamente identado, mas ele também lhe ajudará em que você mantenha o código PHP complexo na ação, por que apenas declarações de controle (if[se], foreach[para todo], while[enquanto], e assim por diante) tem uma sintaxe alternativa.
Listagem 4-4 - A Sintaxe Usual do PHP, Bom para Ações, Mas Ruim para Templates
<p>Olá, mundo!</p> <?php if ($teste) { echo "<p>".time()."</p>"; } ?>
Listagem 4-5 - A Sintaxe Alternativa do PHP, Bom para Templates
<p>Olá, mundo!</p> <?php if ($teste): ?> <p><?php echo time(); ?></p> <?php endif; ?>
DICA Uma boa regra para verificar se a sintaxe do template é legível o suficiente é que arquivo não deve conter código HTML echoado pelo PHP ou chaves. E na maioria do tempo, quando abrir um
<?php, você irá fechá-lo com?>na mesma linha.
Passando Informações a partir da Ação para o Template
O trabalho de uma ação é fazer todo o cálculo complicado, busca de dados, e testes, e definir as variáveis para o template a ser echoado ou testado. Symfony torna os atributos da classe ação (acessados através de $this->nomedaVariavel na ação) acessíveis diretamente ao template no namespace(espaço de nomes) global (através de $nomedaVariavel). As Listagens 4-6 e 4-7 mostram como passar informação a partir da ação para o template.
Listagem 4-6 - Definindo um Atributo da Ação na Ação para Torná-la Disponível no Template
<?php class meumoduloActions extends sfActions { public function executeMinhaAcao() { $hoje = getdate(); $this->hora = $hoje['hours']; } } ?>
Listagem 4-7 - O Template Tem Acesso Direto aos Atributos da Ação
<p>Olá, mundo!</p> <?php if ($hora >= 18): ?> <p>Ou será que eu deveria dizer boa tarde? Já são <?php echo $hora ?>.</p> <?php endif; ?>
NOTA O template já tem acesso a alguns pedaços dos dados sem a necessidade de qualquer definição de variável na ação. Todo template pode chamar métodos dos objetos
$sf_context,$sf_request,$sf_params, e$sf_user. Eles contém dados relacionados ao contexto atual, requisições, parâmetros de requisição, e sessão respectivamente. Você irá em breve aprender como usá-los eficientemente.
Reunindo Informações do Usuário com Formulários
Formulários são uma boa maneira de obter informação a partir do usuário. Escrevendo formulários e elementos de um formulário em HTML pode algumas vezes ser trabalhoso, especialmente quando você quer ser compatível com XHTML. Você poderia incluir elementos do formulário nos templates do symfony da maneira tradicional, como mostrado na Listagem 4-8, mas symfony provê auxiliares que tornam esta tarefa bem mais simples.
Listagem 4-8 - Templates Podem Incluir Código HTML Usual
<p>Olá, mundo!</p> <?php if ($hora >= 18): ?> <p>Ou será que eu deveria dizer boa tarde? Já são <?php echo $hora ?>.</p> <?php endif; ?> <form method="post" target="/minhaaplic_dev.php/meumodulo/outraAcao"> <label for="nome">Qual é o seu nome?</label> <input type="text" name="nome" id="nome" value="" /> <input type="submit" value="Ok" /> </form>
Um auxiliar é uma função em PHP definida pelo symfony que destina-se a ser usada dentro dos templates. Ela produz algum código HTML e é mais rápida de usar do que escrever o verdadeiro código HTML por você mesmo. Usando os auxiliares do symfony, você pode ter o mesmo resultado que na Listagem 4-8 com o código mostrado na Listagem 4-9.
Listagem 4-9 - É Mais Rápido e Fácil de Usar Auxiliares Do Que Usar Marcadores HTML
<p>Olá, mundo!</p> <?php if ($hora >= 18): ?> <p>Ou será que eu deveria dizer boa tarde? Já são <?php echo $hora ?>.</p> <?php endif; ?> <?php echo form_tag('meumodulo/outraAcao') ?> <?php echo label_for('nome', 'Qual é o seu nome?') ?> <?php echo input_tag('nome') ?> <?php echo submit_tag('Ok') ?> </form>
BARRA LATERAL Auxiliares existem para ajudar você
Se, no exemplo da Listagem 4-9, você achou que a versão com auxiliares não é mais rápida de escrever do que a versão com HTML, considere este exemplo:
<?php $lista_cartoes = array( 'VISA' => 'Visa', 'MAST' => 'MasterCard', 'AMEX' => 'American Express', 'DISC' => 'Discover'); echo select_tag('tipo_de_cc', options_for_select($lista_cartoes, 'AMEX')); ?>
Isto gera o seguinte código HTML:
<select name="tipo_de_cc" id="tipo_de_cc"> <option value="VISA">Visa</option> <option value="MAST">MasterCard</option> <option value="AMEX" selected="selected">American Express</option> <option value="DISC">Discover</option> </select>
O benefício dos auxiliares em templates é uma velocidade elevada de implementação, claridade do código, e concisão. O único preço a se pagar é o tempo necessário para aprendê-los, o qual terá acabado assim que você terminar de ler este livro, e o tempo para escrever <?php echo ?>, para o qual você já deve ter um atalho no seu editor de textos favorito. Claro que você poderia não usar os auxiliares do symfony em templates e escrever código em HTML da maneira que você sempre fez, mas isto seria uma grande perca e muito menos divertido.
Note que o uso dos marcadores curtos de abertura (<?=, equivalente à <?php echo) não é recomendado para aplicações web profissionais, já que o interpretador do seu servidor web pode ser capaz de entender mais de uma linguagem de script e consequentemente ficar confuso. Além disso, os marcadores curtos de abertura não funcionam com a configuração padrão do PHP e precisam de um ajuste no servidor para serem ativados. Finalmente, quando você tem que lidar com validação e XML, eles falham completamente por que <? tem um significado especial em XML.
A manipulação de formulários merece um capítulo inteiro e próprio seu, já que o symfony provê várias ferramentas, a maioria auxiliares, para torná-la mais fácil. Você irá aprender mais sobre estes auxiliares no Capítulo 10.
Ligação com Outra Ação
Você já conhece que existe uma separação total entre o nome de uma ação e a URL usada para chamá-la. Então se você criar uma ligação para outraAcao em um template como na Listagem 4-10, ela irá apenas funcionar com o roteamento padrão. Se você decidir mais tarde mudar a maneira que as URLs aparentam, então você irá precisar revisar todos os templates para mudar as hiperligações.
Listagem 4-10 - Hiperligações, A Maneira Clássica
<a href="/minhaaplic_dev.php/meumodulo/outraAcao?nome=anonimo"> Eu nunca digo meu nome </a>
Para evitar esta confusão, você deve sempre usar o auxiliar link_to() para criar hiperligações para as ações de sua aplicação. A Listagem 4-11 demonstra o uso do auxiliar de hiperligação.
Listagem 4-11 - O Auxiliar link_to()
<p>Olá, mundo!</p> <?php if ($hora >= 18): ?> <p>Ou será que eu deveria dizer boa tarde? Já são <?php echo $hora ?>.</p> <?php endif; ?> <?php echo form_tag('meumodulo/outraAcao') ?> <?php echo label_for('nome', 'Qual é o seu nome?') ?> <?php echo input_tag('nome') ?> <?php echo submit_tag('Ok') ?> <?php echo link_to('Eu nunca digo meu nome','meumodulo/outraAcao?nome=anonimo') ?> </form>
O HTML resultante será o mesmo que o anterior, exceto que quando você mudar suas regras de roteamento, todos os templates comportar-se-ão corretamente e reformataram as URLs de acordo.
O auxiliar link_to(), como muitos outros auxiliares, aceita outros argumentos para opções especiais e marcadores de atributos adicionais. A Listagem 4-12 mostra um exemplo de um argumento de opção e o código HTML resultante. O argumento de opção é tanto um vetor associativo ou um simples texto exibindo tuplas chave=valor separadas por espaços.
Listagem 4-12 - A Maioria dos Auxiliares Aceitam um Argumento de Opção
// Argumento de Opção como um vetor associativo <?php echo link_to('Eu nunca digo meu nome', 'meumodulo/outraAcao?nome=anonimo', array( 'class' => 'ligacao_especial', 'confirm' => 'Você tem certeza?', 'absolute' => true )) ?> // Argumento de Opção como um texto <?php echo link_to('Eu nunca digo meu nome', 'meumodulo/outraAcao?nome=anonimo', 'class=ligacao_especial confirm=Você tem certeza? absolute=true') ?> // Ambas chamadas geram o mesmo => <a class="ligacao_especial" onclick="return confirm('Você tem certeza?');" href="http://localhost/minhaaplic_dev.php/meumodulo/outraAcao/nome/anonimo"> Eu nunca digo meu nome</a>
Sempre que você usar um auxiliar do symfony que gera um marcador HTML, você pode inserir marcadores de atributos adicionais (como o atributo class no exemplo da Listagem 4-12) no argumento de opção. Você pode inclusive escrever estes atributos da maneira "rápida-e-suja" do HTML 4.0 (sem estas aspas duplas), e symfony irá gerá-los magnificamente sob XHTML formatado. Isto é uma outra razão por que os auxiliares são mais rápidos de escrever do que HTML.
NOTA Porque requer uma interpretação adicional e transformação, a sintaxe de textos é um pouco mais lenta que a sintaxe de vetores.
Similar aos auxiliares de formulário, os auxiliares de ligação são numerosos e têm várias opções. O Capítulo 9 irá descrevê-los em detalhes.
Reunindo Informações a partir de uma Requisição
Esteja o usuário enviando informações através de um formulário (usualmente com uma requisição POST) ou através de uma URL (requisição GET), você pode recuperar os dados relacionados a partir da ação com o método getRequestParameter() do objeto sfActions. A Listagem 4-13 mostra como, em outraAcao, você pode recuperar o valor do parâmetro nome.
Listagem 4-13 - Reunindo Dados a partir do Parâmetro de Requisição na Ação
<?php class meumoduloActions extends sfActions { ... public function executeOutraAcao() { $this->name = $this->getRequestParameter('nome'); } }
Se a manipulação de dados é simples, você não precisa sequer usar a ação para recuperar os parâmetros de requisição. O template tem acesso a um objeto chamado $sf_params, o qual oferece um método get() para recuperar os parâmetros de requisição, exatamente como o getRequestParameter() na ação.
Caso executeOutraAcao() estivesse vazia, a Listagem 4-14 mostra como o template outraAcaoSuccess.php recuperaria o mesmo parâmetro nome.
Listagem 4-14 - Reunindo Dados a partir de um Parâmetro de Requisição Diretamente no Template
<p>Olá, <?php echo $sf_params->get('nome') ?>!</p>
NOTA Por quê não usar as variáveis
$_POST,$_GET, ou$_REQUESTao invés disso? Porque deste modo suas URLs serão formatadas diferentemente (como emhttp://localhost/artigos/europa/franca/financa.html, sem?, nem=), as variáveis comuns do PHP não funcionarão mais, e apenas o sistema de roteamento será capaz de recuperar os parâmetros de requisição. Além disso, você pode querer adicionar filtragem dos dados de entrada para precaver-se de injeção de código malicioso, a qual é apenas possível se você manter todos os parâmetros de requisição em um único parâmetro limpo armazenador.
O objeto $sf_params é mais poderoso do que apenas fornecer um equivalente get para um vetor. Por exemplo, se você quer apenas testar a existência de um parâmetro de requisição, você pode simplesmente usar o método $sf_params->has() ao invés de testar o valor real com get(), como na Listagem 4-15.
Listagem 4-15 - Testando a Existência de um Parâmetro de Requisição no Template
<?php if ($sf_params->has('nome')): ?> <p>Olá, <?php echo $sf_params->get('nome') ?>!</p> <?php else: ?> <p>Olá, João Ninguém!</p> <?php endif; ?>
Você pode já ter advinhado que isto pode ser escrito em uma única linha. Como com a maioria dos métodos get em symfony, ambos, o método getRequestParameter() na ação e o método $sf_params->get() no template (o qual, na realidade, chama o mesmo método no mesmo objeto) aceitam um segundo argumento: O valor padrão a ser usado, se o parâmetro de requisição não está presente.
<p>Olá, <?php echo $sf_params->get('nome', 'João Ninguém') ?>!</p>
Sumário
Em symfony, as páginas são compostas de uma ação (um método no arquivo actions/actions.class.php com o prefixo execute) e um template (um arquivo no diretório templates/, usualmente terminando com um Success.php). Elas estão agrupadas em módulos, de acordo com suas funções na aplicação. Escrever templates é facilitado pelos auxiliares, os quais são funções providas pelo symfony que retornam código em HTML. Você precisa pensar na URL como uma parte da resposta, que pode ser formatada como for preciso, então você deve conter-se de usar qualquer referência para uma URL no nomeamento de ações ou em recuperação de parâmetros de requisição.
Uma vez que você conheça estes princípios básicos, você já poderá escrever uma aplicação web completa com symfony. Mas custaria-lhe muito tempo, já que quase toda tarefa que você precisará realizar durante este curso do desenvolvimento de aplicações é facilitada de uma maneira ou de outra por alguma característica do symfony...razão pela qual este livro não termina neste momento.
Attachments
- F0401.jpg (30.1 kB) -
A página de índice gerada por padrão
, added by rafastv on 06/17/08 20:29:58.
