Habilitando Layouts no CodeIgniter (Template Engine) – Parte 1
February 18th, 2010 | Published in CodeIgniter, Php, Programação em geral | 10 Comments
Vejo muitos desenvolvedores criticarem o CodeIgniter por ele não utilizar o conceito de Layout ou ter um Template Engine dentro dele.
Template engine ou o conceito Layouts , falando em um exemplo rápido e prático seria mais ou menos o seguinte:
Pense que você tem um topo e um rodapé que nunca mudam no seu portal.
Ou seja, muda apenas o meio das páginas. Veja a figura abaixo.

E aí? Você vai ter que colocar esse topo e esse rodapé em todas as páginas que você chamar?
Ou você é malandro e vai fazer um include dentro das telas?
O Include seria uma solução interessante mais uma Template Engine faria isso sozinho para você.
Pra quem não conhece nenhuma solução para isso, o Smarty é uma template Engine das mais conhecidas no mundo do PHP.
Você tem uma lista com outras sugestões de Templates Engine nesse link da web Resources
Outros frameworks como o CakePHP tem uma solução dentro dele que faz esse trabalho.
Nesses tempos que desenvolvo em CodeIgniter já vi bizarrices do tipo colocar o Smarty dentro do CodeIgniter ou trazer bibliotecas de outras frameworks para o Core do CodeIgniter.
Mas podemos estender o Core do Framework e fazer ele trabalhar junto com a gente sem precisar de muitas manobras e malabarismos. Na documentação do CodeIgniter achamos essa prática com o nome de Hooks ou se preferir o português ganchos.
Há alguns anos um cara que considero um dos Gurus do desenvolvimento, Mozart Petter, o qual tive a honra de trabalhar junto, pesquisou uma solução nesse sentido para que não precisássemos abandonar o CodeIgniter.
Você encontra vários links pesquisando no google por Layouts in CodeIgniter, onde destaco o seguinte Blog http://hasin.wordpress.com/2007/03/05/adding-yield-codeigniter/
Abaixo vou colocar uma solução em 7 passos para você implementar isso em seu projeto de CI.
É importante que você procure entender em cada passo como o CodeIgniter vai visualizar isso tudo.
*Não se deixe confundir. É fácil. Se ficar difícil há algo errado, volte e reveja os passos.
Como os códigos são muito extensos, vou dividir em dois posts.
Parte 1 – Esse (passo 1 ao 4) e Parte 2 (passo 5 ao 7) que você acessa aqui.
Para quem não estiver com muita paciência, estou disponibilizando também um exemplo pronto de tudo funcionando que você pode baixar aqui.
Apenas confira se o .htaccess serve para o seu servidor ou máquina.
1 – Habilitando o Codeigniter para estender o Core
A primeira coisa a fazer é habilitar o codeIgniter para estender o Core, permitir os hooks.
Isso é feito no arquivo config.php dentro da pasta config.
Procure a variável $config['enable_hooks'] e troque seu valor para TRUE, ficando como abaixo.
/* |-------------------------------------------------------------------------- | Enable/Disable System Hooks |-------------------------------------------------------------------------- | | If you would like to use the "hooks" feature you must enable it by | setting this variable to TRUE (boolean). See the user guide for details. | */ $config['enable_hooks'] = TRUE;
Pronto! Próximo passo.
2 – Definindo um Hook
Dentro da pasta config temos um arquivo onde deve ser feitas as definições dos hooks que você quer utilizar.
Para cada hook é preciso definir um array com alguns parâmetros para que o CodeIgniter saiba o que fazer.
Importante: O índice do array vai funcionar como nome do seu hook.
Para o nosso Hook vamos definir.
- O nome da Classe que você precisa.
- O nome do método da classe que você deseja chamar.
- O nome do arquivo onde está desenvolvida a classe.
- O directório onde ela se encontra.
Fica da seguinte forma:
$hook['display_override'][] = array('class' => 'Layout',
'function' => 'init',
'filename' => 'Layout.php',
'filepath' => 'hooks');
Esses itens podem variar de acordo com o que você quiser ou precisar fazer.
O manual é uma grande referência para te ajudar com isto e traz alguns detalhes que não abordo aqui.
Certo! Você habilitou e definiu um Hook, ou gancho. Vamos para o próximo passo.
3 – Adicionando algumas constantes necessárias
No arquivo index da aplicação são definidas algumas constantes que ajudam no desenvolvimento da nossa aplicação, como por exemplo,
a extensão dos arquivos que serão usados, constante EXT, e o BASEPATH que traz o caminho da pasta do sistema.
Vamos adicionar aqui mais 3 constantes que vai nos facilitar lá na frente quando formos fazer nossa classe.
- LAYOUTPATH – Caminho onde ficará os layouts que construirmos.
- JSPATH – Caminho onde ficará os arquivos com javascript.
- CSSPATH – Caminho onde ficará os arquivos de estilo. CSS.
Ficando da seguinte forma:
/*
|---------------------------------------------------------------
| DEFINE APPLICATION CONSTANTS
|---------------------------------------------------------------
|
| EXT - The file extension. Typically ".php"
| SELF - The name of THIS file (typically "index.php")
| FCPATH - The full server path to THIS file
| BASEPATH - The full server path to the "system" folder
| APPPATH - The full server path to the "application" folder
|
*/
define('EXT', '.php');
define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
define('FCPATH', str_replace(SELF, '', __FILE__));
define('BASEPATH', $system_folder.'/');
define('LAYOUTPATH', $application_folder.'/layouts/');
define('JSPATH', $application_folder . '/js/');
define('CSSPATH', $application_folder . '/css/');
Reparem que usei a variável $application_folder, que é definida no mesmo arquivo, para completar o caminho das minhas constantes.
Você pode e deve mudar isso de acordo com seu projeto.
Essas constantes vão facilitar também para caso você precise mudar o caminho dos arquivos CSS por exemplo. Basta alterar aqui.
4 – Construindo seu Layout
Vamos agora construir o seu Layout.
Seria aquele topo e aquele rodapé que você não quer mexer. Ou um menu lateral.
Você pode construir o que quiser.
O local onde vamos criar nossos layouts foi definido na constante LAYOUTPATH.
Você pode ter quantos layouts quiser e nomeá-los como quiser.
Mas quando formos construir a classe você verá que definimos um Layout default para quando nenhum for chamado.
É esse que vamos criar agora. default.php
No exemplo abaixo eu criei um topo que tem um menu e um rodapé simples.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>{title_for_layout}</title>
{css_for_layout}
{js_for_layout}
</head>
<body>
<div id="geral">
<div id="topo">
<ul id="menu">
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</div>
<div id="meio">
{content_for_layout}
</div>
<br style="clear: both;" />
<div id="rodape">
<p class="rodape">
Todos os direitos reservados - Bla Bla Bla
</p>
</div>
</div>
</body>
</html>
É necessário prestar atenção em 4 variáveis que deixamos soltas no meio desse HTML do Layout.
- Primeira – {title_for_layout}
- Segunda – {css_for_layout}
- Terceira – {js_for_layout}
- Quarta – {content_for_layout}
Explicando rapidamente:
Essas Strings vão ser substituídas de acordo com o que definirmos no Controller em um próximo passo.
No lugar de {title_for_layout} irá o título da página. É legal podermos definir um título pelo controlador para deixá-lo dinâmico e assim ajudar no SEO.
No lugar de {css_for_layout} e {js_for_layout} entrarão os arquivos de CSS e JavaScript que definirmos para nossa página.
Você não precisa chamar todos os CSS ou JavaScripts se não for usá-los. Essa é uma grande sacada dessa solução.
Lembro de pegar projetos em Smarty onde estavão definidos inúmeros JavaScripts e CSS em um top.php onde em várias páginas eles nem era usados.
Por último, no lugar de {content_for_layout} irá o conteúdo da nossa View.
É o meio, o que muda.
É o que vamos fazer no próximo passo que está no próximo post.
February 18th, 2010 at 18:21 (#)
[...] Continuando a parte 1 deste post. Se você perdeu a primeira parte clique aqui para ler a primeira parte. [...]
April 17th, 2010 at 16:01 (#)
Talvez fosse interessante trabalhar com Ajax, neste caso poderíamos mudar a DIV meio usando um:
echo $this->ajax->link_to_remote(“Login”, array(‘url’ => ‘/login’, ‘update’ => ‘divmeio’));
Além de ficar visualmente mais bonito, não ser necessário carregar toda página e ainda não precisar configurar nenhum hook.
April 18th, 2010 at 06:16 (#)
Eu não sei se esse seria um uso legal do ajax…
e outra daí..para que usar um framework se vc não usa as coisas que ele te proporciona ??
Abraço!!
May 20th, 2010 at 15:35 (#)
Parabéns pelo artigo, vou estudar e ver a melhor forma de trabalhar com os Template em CI
Abraços
Marvio Rocha
June 15th, 2010 at 19:40 (#)
Gostaria de saber como faz para define constates para diretorios de imagens, aquivos .swf, audio e video.
define(‘LAYOUTPATH’, $application_folder.’/layouts/’);
define(‘JSPATH’, $application_folder . ‘/js/’);
define(‘CSSPATH’, $application_folder . ‘/css/’);
???
August 25th, 2010 at 11:45 (#)
peguei a versão já feita, porque, como você disse, sou preguiçoso! =P
mas quando rodo ela, apesar de as constantes estarem definidas, pego três erros:
“A PHP Error was encountered
Severity: Notice
Message: Use of undefined constant CSSPATH – assumed ‘CSSPATH’
Filename: hooks/Layout.php
Line Number: 99″
para cada um dos Path
tentei, mas não consigo mudar isso, algum conselho!?
August 25th, 2010 at 14:45 (#)
Cara isso aí é o seguinte… Provavelmente você esteja rodando em um servidor Windows o projeto e eu nos meus linux aqui, defino as Globais sem aspas.
Coloca entre aspas lá que deve funcionar.
Abraço!
August 25th, 2010 at 14:47 (#)
Ahdail, siga o exemplo dessas variáveis globais nesse arquivo….é só replicar as linhas onde aparecem CSSPATH por exemplo.
August 26th, 2010 at 08:32 (#)
Flávio, eu tô usando Ubuntu 10.4 e definindo as globals assim:
define(‘LAYOUTPATH’, $application_folder.’/layouts/’);
define(‘JSPATH’, $application_folder . ‘/js/’);
define(‘CSSPATH’, $application_folder . ‘/css/’);
tentei defini-las de maneira diferente:
define(‘LAYOUTPATH’, “{$application_folder}/layouts/”);
mas ainda pego o memso erro…
=/
tem mais alguma idéia?
August 31st, 2010 at 10:11 (#)
Dinho,
Eu uso Ubunto aqui também e está tudo certo.
Conseguiu resolver isso aí ?
Abraços!