[ Tutorial ] Zend Framework – Parte 03

Routes, Layout, View

Sumário

Continuando com o nosso projeto disponível nas partes anteriores deste tutorial em minha página Zend Framework, nesta parte do tutorial vamos aprender como criar Routes, uma forma prática de redirecionar sua aplicação para as mais diversas situações, entre elas, quando alguma página mudou de lugar na sua aplicação. E seguindo a solicitação de alguns leitores, como criar trabalhar com Layouts e aprender o conceito básico de View.

Agora que você já sabe como trabalhar com módulos, actions e controllers e respondendo a uma pergunta dos amigos que utilizaram meus tutoriais como fonte de aprendizado, ai vai a resposta:

Pergunta: A maioria dos tutoriais na internet não utiliza ou cita Módulos, preciso mesmo utilizar Módulos?
Resposta: Não. Não precisa! Mas seria uma perca de tempo e recursos. O objetivo deste tutorial é fornecer algo mais sólido e próximo de um projeto real para o desenvolvedor que deseja realizar projetos ousados.

A pergunta acima foi feita por vários desenvolvedores que entraram em contato nas últimas 2 semanas depois que atualizei os tutoriais e achei interessante citá-la.

Routes

O que são Routes? Rotas, do inglês! O Leitor deve estar perguntando se eu estou tirando da cara dele. Mas não! Normalmente, as palavras bem definidas fazem com que fixemos o objetivo e não criemos confusão antecipada.
Uma rota é um ponto de acesso ou trajeto definido e delimitado após uma experiência ou análise prévia.
No Zend, é o processo de pegar o ponto final de URI, decompor o mesmo, e definindo qual módulo, controller, action deverá servexecutado na solicitação ( request ).

O Roteamento ocorre somente uma vez quando uma solicitação é feita; antes do controller ser chamado.

Utilizando Routers

Existem duas formas fundamentais de se criar Routes com o Zend.
A primeira é através do arquivo application.ini e outra através de um dos 6 tipos:

  • Zend_Controller_Router_Route
  • Zend_Controller_Router_Route_Static
  • Zend_Controller_Router_Route_Regex
  • Zend_Controller_Router_Route_Hostname
  • Zend_Controller_Router_Route_Chain
  • Zend_Controller_Router_Rewrite

Por questões de praticidade, eu sempre utilizo a primeira, pois a equipe do Zend criou uma interface que faz todo o trabalho para você direto no arquivo de configuração. ‘Routes’ não são o tipo de coisa que você deve se preocupar demais num projeto, sem desprezar sua importância, é claro, por isto a sacada foi boa! E seria perca de tempo se matar digitando um monte de código PHP quando você pode fazer o mesmo com algumas linhas no arquivo de configuração, e se isto existe é para isto que foi criado. Mais adiante, veremos como programar Routes, utilizando o batalhão de classes acima, mas por hora vamos entender como as coisas funcionam no arquivo de configuração.

Anteriormente na Parte 02

Nós criamos o controlador ‘index’ automaticamente anteriormente no momento da criação do projeto, e depois alguns actions que resultaram nos URLs:

  • http://zend.localhost/index/index
  • http://zend.localhost/index/quem-somos
  • http://zend.localhost/index/servicos
  • http://zend.localhost/index/produtos
  • http://zend.localhost/index/contato

Mas estas URLs com ‘index’ não ficaram legal.

Nós poderíamos ter criado um controlador para cada caso:

QuemSomos, Servicos, Produtos e Contato

Mas necessariamente, não faria sentido, a menos que cada página do site tivesse sub-páginas, algo do tipo.

Produtos -> Categorias
Produtos -> Resultados
PRodutos -> Ver

Etc…

Por questões de aprendizagem de Refatoração do Projeto, mais adiante nós modificaremos a funcionalidade da seção ‘Produtos’ de nosso site a fim de corresponder com nossas necessidades, mas por ora, ele é apenas uma página que lista os tipos de produtos, ou uma ação dentro do controlador index.

O que nós atualmente queremos é algo do tipo:

  • http://zend.localhost/home
  • http://zend.localhost/quem-somos
  • http://zend.localhost/servicos
  • http://zend.localhost/produtos
  • http://zend.localhost/contato

Que é o que vamos fazer agora!

Abra o seu arquivo /application/configs/application.ini e procure pela seção [production].

Cole as linhas abaixo:

 lang="sql;
[production]
resources.router.routes.home.route = /home
resources.router.routes.home.defaults.module = default
resources.router.routes.home.defaults.controller = index
resources.router.routes.home.defaults.action = index

Vamos entender o que aconteceu.

A primeira linha define o que deverá ser chamado, no nosso caso ‘home‘:

 lang="sql
resources.router.routes.home.route = /home

A segunda linha define o module, no nosso caso ‘default‘ que é o modulo padrão:

 lang="sql
resources.router.routes.home.defaults.module = default

A terceira linha define o controller (index) :

 lang="sql
resources.router.routes.home.defaults.controller = index

E a quarta define o action (index) :

 lang="sql
resources.router.routes.home.defaults.action = index

Repare na estrutura e veja que somente foi modificada a última parte de cada linha (module|controller|action). A lógica é esta:

resources.router.routes.NOME_DA_ROTA.MODULO.CHAVE = VALOR

O NOME_DA_ROTA deverá ser único para cada rota, como veremos mais abaixo.
O MODULO, apesar de ser ‘default‘ em nossa aplicação, para este caso deverá ser passado como ‘defaults‘.

Agora você pode testar:

http://zend.localhost/home

Que seria o mesmo que:

http://zend.localhost/ ou http://zend.localhost/index/index

Se você não entendeu, releia. Se entendeu vamos fazer o mesmo para as próximas páginas de nosso projeto:

 lang="sql;
[production]
; home
resources.router.routes.home.route = /home
resources.router.routes.home.defaults.module = default
resources.router.routes.home.defaults.controller = index
resources.router.routes.home.defaults.action = index

;quemsomos
resources.router.routes.quemsomos.route = /quem-somos
resources.router.routes.quemsomos.defaults.module = default
resources.router.routes.quemsomos.defaults.controller = index
resources.router.routes.quemsomos.defaults.action = quem-somos

;servicos
resources.router.routes.servicos.route = /servicos
resources.router.routes.servicos.defaults.module = default
resources.router.routes.servicos.defaults.controller = index
resources.router.routes.servicos.defaults.action = servicos

;produtos
resources.router.routes.produtos.route = /produtos
resources.router.routes.produtos.defaults.module = default
resources.router.routes.produtos.defaults.controller = index
resources.router.routes.produtos.defaults.action = produtos

; contato
resources.router.routes.contato.route = /contato
resources.router.routes.contato.defaults.module = default
resources.router.routes.contato.defaults.controller = index
resources.router.routes.contato.defaults.action = contato

IMPORTANTE: Note que nomeamos cada rota e alteramos as primeiras e quartas linhas de cada bloco.

Agora você pode acessar cada página:

  • http://zend.localhost/home
  • http://zend.localhost/quem-somos
  • http://zend.localhost/servicos
  • http://zend.localhost/produtos
  • http://zend.localhost/contato

Fácil não?

Mais adiante veremos como passar parametros e como recuperá-los.

Layouts

Conforme solicitado pelos amigos leitores, vou ensinar nesta terceira parte sobre Layouts.

O que é um Layout?

De repente você esteja acostuma com o termo ‘tema’, ‘template’, ‘design’, etc mas não tenha intimidade com ‘layout’.
Um Layout é basicamente uma estrutura hierárquica em sua aplicação que mantém partes de código que se repetirão em todas ou algumas páginas da aplicação.
Toda aplicação web é composta por uma estrutura HTML padrão que precisa ser mantida e normalmente o que muda de uma pagina para outra é o conteúdo, e se mantém sempre o cabeçalho, rodapé, laterais.
Um Layout no Zend Framework é parte do MVC e utiliza-se do ViewRenderer que oferece uma vasta gama de recursos que são carregados automaticamente para o objeto $view.

Enable Layout

No Zend Framework o Layout é habilitado pelo ZF Tool, digitando a linha abaixo:

 lang="sql
zf enable layout

Este comando criará uma pasta e um arquivo em ‘/application/layouts/scripts/layout.phtml’ com a linha:


<?php echo $this->layout()->content; ?>

Esta linha carregará o conteudo do arquivo view script do action sendo chamado.

Dentro do arquivo de configuração application.ini foi adicionada a linha:

 lang="sql
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"

Acesse sua aplicação e veja que nada mudou.

Agora modifique o arquivo layout.phtml para que o mesmo fique assim:


<html>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <title>Meu Projeto Zend Framework</title>
    <body>
	<div id="header">{Meu Cabeçalho aqui}</div>
	<div id="content">
	<?php echo $this->layout()->content; ?>
	</div>
	<div id="footer">{Meu rodapé aqui}</div>
    </body>
</html>

Acesse todas as páginas de nosso projeto e verifique que a estrutura se manteve a mesma.

Então se você deseja criar alguma navegação no topo, lateral, rodapé ou outros blocos de HTML você poderá fazê-los neste arquivo.

NOTA: Não remova a declaração $this->layout()->content:


<?php echo $this->layout()->content; ?>

Do contrário o conteúdo dos arquivos view não serão exibidos.

Mais adiante veremos como adicionar Scripts e CSS e como criar uma esquema de temas.

Views e Templates

Outra coisa interessante no desenvolvimento web, além de Layouts são as ferramentas de template. Existem várias por ai tais como Smarty, PHP Template, etc… eu mesmo até já fiz uma (risos).
No Zend não há necessidade de se utilizar uma ferramenta de templates, pois o View faz isto.

O que é o View?

O View é uma classe que trabalha com a parte View que já aprendemos anteriormente ( não estou tirando de novo – risos ), ou seja, ele existe para auxiliar a manter o view script (arquivos dos actions) separado dos arquivos Model e Controller. Ele oferece um sistema de Helpers, Filters e variáveis escapadas.

Um Exemplo para entender

CASO: Você deseja que determinados valores sejam carregados automaticamente em cada página, variando de acordo com o controlador e o action, no caso o valor da tag ‘TITLE’ de cada página e o ‘Titulo da página’ para identificar onde o usuário está.
No nosso projeto, precisamos identificar cada página com títulos distintos:


// pagina home
...
<title>Seja Bem Vindo - Tutorial Zend</title>
...
<h1>Seja Bem vindo</h1>

...

// pagina quem-somos
...
<title>Quem Somos - Tutorial Zend</title>
...
<h1>Quem Somos</h1>

...

/**
 * E ASSIM POR DIANTE!!!!
 */

Para fazermos isto, precisamos utilizar o View da seguinte forma:

Abra o arquivo IndexController.php

E insira as linhas dentro do método indexAction():


...
public function indexAction()
{
    $this->view->pageTitle = 'Seja Bem-vindo - Tutorial Zend';
    $this->view->contentTitle = 'Seja Bem-vindo';
}
...

No arquivo view/scripts/index/index.phtml remova todo o conteúdo gerado automaticamente e coloque:


<h1><?=$this->contentTitle;?></h1>

Acesse a página home de nosso projeto e veja que o título apareceu lá.

No entanto, ainda falta definir o TITLE de cada página, isto será feito no arquivo layouts.phtml:


...
<title><?= $this->pageTitle;?></title>
...

Atualize a página e veja que agora o TITLE possui a string que definimos.

[NOTA] : Faça o mesmo dentro de cada método action de nosso controlador para cada página modifique o arquivo view correspondente (quem-somos, servicos, produtos, contato).

Em resumo é isto:

No action você usa:


$this->view->CHAVE = VALOR;

E no view script (arquivo .html do action):


$this->CHAVE; // NOTE QUE NÃO HÁ O view

Bom, vamos ficar por aqui. Mais adiante veremos muita coisa boa.

Resumo

Nesta terceira parte de nosso tutorial você aprendeu o conceito fundamental de Routes e aprendeu como definir facilmente rotas no arquivo de configuração. Também aprendeu como habilitar Layout no Zend framework e modificou o arquivo gerado. Vimos como utilizar o View para trabalharmos com o paradigma de Templates.
Nas próximas partes continuaremos e veremos pegar os parametros do URL e como obter valores via GET e POST através de Forms criados pelo Zend.
Abraço do Giba!

4 comentários sobre “[ Tutorial ] Zend Framework – Parte 03”

    1. Olá, Marcos.
      Tem como fazer isto.
      No entanto, você vai sobrecarregar a aplicação desnecessariamente e vai precisar colocar algum controle.
      Eu recomendo você criar um array com os controllers que sua aplicação possui e verificar se o parametro está no array,
      se nao estiver, beleza, busca no banco, senão vai ser um controller.
      Entretanto, se o usuário não existir e nem o controller, vai carregar a pagina passada no roteamento e o controlador de erros foi pro beleléu.

      Mas que seja… se voce faz questão:

      ; usuario
      resources.router.routes.usuario.route = :usuario
      resources.router.routes.usuario.defaults.module = default
      resources.router.routes.usuario.defaults.controller = index
      resources.router.routes.usuario.defaults.action = index

      e para verificar a brincadeira:

      class Default_IndexController extends Zend_Controller_Action
      {
      public function init()
      {
      $appControllers = array('index', 'controller1', 'controller2', 'controllerETC');
      $this->request = $this->getRequest();
      $usuario = $this->request->getParam( 'usuario' );

      if( !in_array( $usuario, $appControllers ) ) {
      print $usuario;
      // operações com o Banco de Dados
      }
      }

      public function indexAction() {}
      }

  1. Oi Gilberto,

    Congratulações pelo tutorial. Consegui realizar tudo certinho.

    Dois pontos a ponderar:
    – achei muito desnecessário configurar o route no application.ini, pois se a aplicação for de grande porte, imagina quantas vezes teríamos que editar o arquivo? Não há forma de “automatizar” isso, sem a necessidade de configurar o route no aplication.ini?
    – somente existe um layout para todos os controllers. Se eu quiser escolher um layout específico em uma action, como posso fazer isso? É tão complexo assim?

    Obrigado e um abraço,
    Vinicius.

    1. Dois pontos a responder:
      1 – Indiferente de configurar via application.ini ou outros métodos disponíveis pelo zend (http://framework.zend.com/manual/en/zend.controller.router.html), qualquer método que você utilizar para gerenciar rotas, vai exigir ‘configuração’… e de todas o application.ini é o mais rápido e pratico. Mas, há de se considerar também… que a rota é uma ‘exceção’ da aplicação que demanda ‘modificar’ o funcionamento normal.
      Você poderia fazer isto via Apache… o que seria muito mais complicado.
      E quanto ao fato de aplicações de grande porte, não vejo como automatizar uma coisa que tem que ser feita manualmente e descritivamente item por item, uma vez que cada item precisa ser passado para a aplicação cada qual com sua peculiaridade.
      Outra coisa que você precisa se focar nesta avaliação, é o fato de que um framework MVC propõe resolver questões do padrão de software MVC, logo, alguma coisa acabaria demandando mais configurações, e creio que Rotas acabam por ser.
      Também lembrando… que em MVC uma rota possui 4 camadas: A Rota em si, Módulo, o Controller e o View… por trás dos panos a coisa é bem mais exigente.
      E por fim, uma aplicação que precise de muitas rotas está pecando na arquitetura… rotas são uma alternativa à uma exceção, tal como um caminho que mudou ou uma página temporária que precisa ser redireciona, ou mesmo abreviação de URL e não uma forma de redirecionar o usuário para páginas que poderiam ser chamadas normalmente.

      2 – Não existe somente um Layout para todos os controler!!! Você pode ter ‘um’ layout por página, basta criar um novo layout, colocar na pasta ‘layout/scripts’ e no controller chamar:
      $this->_helper->layout->setLayout('nome_do_layout');
      Eu geralmente tenho 3 layouts diferentes nas minhas aplicações…
      1 – layout – para o site
      2 – login – para login
      3 – admin – para administração.

      Espero ter ajudado…

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *