Habilitando Layouts no CodeIgniter (Template Engine) – Parte 2

23

Posted by flaviosilveira | Posted in CodeIgniter, Php, Programação em geral | Posted on 18-02-2010

Atenção!! Este artigo foi escrito em cima da versão 1 do Codeigniter. Para detalhes de como usar com a versão 2 do framework clique aqui.

Continuando a parte 1 deste post.
Se você perdeu a primeira parte clique aqui para ler a primeira parte.

5 – Construindo sua View

Sua View deve ser feita normalmente, como voce já está acostumado a fazer, com o nome que você colocaria normalmente.
Apenas com o conteúdo que muda de uma página para outra.

O HTML que você colocar aqui na View irá substituir a variável {content_for_layout} que definimos no layout acima.
Vou colocar nessa nossa view de exemplo apenas um título e um parágrafo para demonstrar.
Ficando assim:


<h1>Titulo VIEW</h1>

<p>Paragrafo teste teste teste teste.</p>

Chamei essa view de home.php.

6 – Desenvolvendo a Classe

Quando definimos nosso Hook no passo 2, setamos que a pasta onde ficaria nossa classe seria a pasta hooks que vem por padrão no projeto do CodeIgniter.

Vamos criar nossa classe dentro dessa pasta, e, com o nome que também especificamos na definição do Hook que foi Layout.php
Se você não seguiu o exemplo, faça suas devidas adaptações.

A classe é um pouco extensa, leia com atenção.
Para ajudar ela está com os comentários do próprio Mozart Petter.

// Padrao do CI para não acessar a Classe direto pelo Browser
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Layout Class
 *
 * @package hooks
 * @description Implementa as views do tipo layout no framework.
 */

class Layout
{

public $base_url;

/**
* Metodo que executa as implementacoes.
* Este metodo e chamado atraves do arquivo hooks.php
* na pasta config.
*
* @return
*/
public function init()
{
// Instancia do CI.
$CI =& get_instance();

// Definindo o base_url.
$this->base_url = $CI->config->slash_item('base_url');

// Pegando a saida que o CI gera normalmente.
$output = $CI->output->get_output();

// Pegando o valor de title, se definido no controller.
$title = (isset($CI->title)) ? $CI->title : '';

// Links CSS definidos no controlador.
$css = (isset($CI->css)) ? $this->createCSSLinks($CI->css) : '';

// Links JS definidos no controlador.
$js = (isset($CI->js)) ? $this->createJSLinks($CI->js) : '';

// Se layout estiver definido e a regexp nao bater.
if (isset($CI->layout) && !preg_match('/(.+).php$/', $CI->layout))
{
$CI->layout .= '.php';
}
else
{
$CI->layout = 'default.php';
}

// Definindo caminho completo do layout.
$layout = LAYOUTPATH . $CI->layout;

// Se o layout for diferente do default, e o arquivo nao existir.
if ($CI->layout !== 'default.php' && !file_exists($layout))
{
// Exibe a mensagem, se o layout for diferente de '.php'.
if ($CI->layout != '.php') show_error("You have specified a invalid layout: " . $CI->layout);
}

// Se o arquivo layout existir.
if (file_exists($layout))
{
// Carrega o conteudo do  arquivo.
$layout = $CI->load->file($layout, true);

// Substitui o texto {content_for_layout} pelo valor de output em layout.
$view = str_replace('{content_for_layout}', $output, $layout);

// Substitui o texto {title_for_layout} pelo valor de title em view.
$view = str_replace('{title_for_layout}', $title, $view);

// Links CSS.
$view = str_replace('{css_for_layout}', $css, $view);

// Links JS.
$view = str_replace('{js_for_layout}', $js, $view);
}
else
{
$view = $output;
}

echo $view;
}

/**
* Gera os links CSS utilizados no layout.
*
* @return void
*/
private function createCSSLinks($links)
{
$html = "";

for ($i = 0; $i < count($links); $i++)
{
$html .= "<link rel='stylesheet' type='text/css' href='" . $this->base_url . CSSPATH . $links[$i] . ".css' media='screen' />n";
}

return $html;

}

/**
* Gera os links JS utilizados no layout.
*
* @return void
*/
private function createJSLinks($links)
{
$html = "";

for ($i = 0; $i < count($links); $i++)
{
$html .= "<script type='text/javascript' src='" . $this->base_url . JSPATH . $links[$i] . ".js'></script> n";
}

return $html;
}

}

7 – Fazendo as chamadas no Controller

Chegou o momento final!
É hora de juntar tudo isso que fizemos até agora.

A construção do seu controller é normal, como você está acostumado, mas temos que inserir algumas variáveis globais nele.

  • Uma para o Layout default do controller, para que você não precise fazer a mesma definição várias vezes.
  • Uma para o título, onde você pode definir um default para todos as páginas que vão surgir desse controller mas, o interessante é estar um título por página.
  • Outra para guardar um Array dos CSS’s que você vai usar na página.
  • E por último, outro Array para guardar os JavaScripts que você vai usar na página.

Vejamos como fica.
Acompanhe pelos comentários.


<?php

/**
 *
 */
class Principal extends Controller
{

/**
* Layout default utilizado pelo controlador.
*/
public $layout = 'default';

/**
* Titulo default.
*/
public $title = '::: Titulo default :::';

/**
* Definindo os css default.
*/
public $css = array('default');

/**
* Carregando os js default.
*/
public $js = array('home');

/**
* Construtora.
* @return
*/
function Principal()
{

parent::Controller();

}

// Metodoo index
function index()
{
// Carregando a view.
$this->load->view('home');
}

// Metodo teste
function teste()
{
//Title
$this->title = '::: TESTE Título :::';

//CSS
$this->css = array('test');

//JS
$this->js = array('jquery');

// Carregando a View
$this->load->view('teste');
}

}

?>

Vamos reparar no seguinte.
Há dois métodos nesse controller que vão chamar páginas diferentes, o index e o teste.

Para o index não definimos nada de Layout, Titulo, CSS ou JS.
Ou seja, vai vir tudo do valor default que usamos quando definimos as variáveis globais.

Já no método teste, por algum motivo precisamos de um CSS, um JS e um Título diferente.
Então redefinimos esses valores no nosso método com o que precisamos.

A gente poderia ter definido um outro Layout caso tivesse a necessidade, da mesma forma com que fiz com esses valores.
Aí, claro, teria que criar um outro Layout na pasta layouts.



UPDATE 20 DE NOVEMBRO DE 2010
Detalhe importante observado pelo Diego Felix (@diegofelix), que comentou esse detalhe abaixo nos comentários, no dia 16 de setembro desse mesmo ano.

 

Eu tenho como costume em meus projetos com CI, retirar a pasta system no qual ele vem por padrão.
Faço então a alteração da variável $system_folder no arquivo de configuração e tudo segue sem problemas.

Exceto esse tutorial, que não leva em consideração essa pasta system.
Você tem duas opções para consertar isso:

Primeiro:
No local onde são definidas as variáveis contantes, adicionar sua pasta system antes de $application_folder.
Exemplo: define(‘LAYOUTPATH’, ‘system/’ . $application_folder.’/layouts/’);

Particularmente acho essa solução acima atrasada, por deixar o projeto estático.
Se ocorrer de você alterar a pasta system, terá que alterar nesse local também. Chato.

Segundo:
Seguindo essa linha de raciocínio, de não deixar o projeto estático, prefiro fazer o seguinte:
No local onde são definidas as variáveis constantes, adicionar a variável $system_folder.
Exemplo: define(‘LAYOUTPATH’, $system_folder . ‘/’ . $application_folder.’/layouts/’);

Mas há um detalhe.
No arquivo index.php, em torno da linha 53, é adicionado a variável $system_folder o seu caminho completo do servidor. Isso, claro, vai gerar problemas para o projeto.
O que eu faço então é pegar as variáveis constantes que usam a pasta system, e jogar antes desse bloco.
Se você seguir pelo projeto exemplo, verá que as coloquei logo depois do comentário “END OF USER CONFIGURABLE SETTINGS”.

Feito isso, caso você altera sua pasta system, basta alterar no local de sempre para o projeto continuar funcionando.


Pessoal é isso!
Fazia tempo que queria escrever sobre isso, espero que ajude a galera por aí.
Dúvidas podem mandar sem problemas, vou responder no que estiver a meu alcance.

Se você teve dificuldades, baixe o projeto pronto aqui e dê uma olhada mais de perto.

Agradeço novamente ao Mozart Petter, grande Brother, que implementou essa solução que uso até hoje em meus projetos. E, como sempre, também ao pessoal que garante minhas 30 visitas diárias, Valeu!

É isso pessoal.
Até a próxima!!!

Be Sociable, Share!

Comments (23)

[...] 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. [...]

Ótimo post Flávio, ficou show de bola essa adaptação Two Step View para o Codeigniter, e espero que possa encontrar mais posts com essa qualidade e utilidade por aqui… muito obrigado.. sucesso e que DEUS lhe abençoe…

Flávio, segui os passos indicados e recebi uma página em branco.
Então fiz o download dos arquivos e… página em branco.

Hugo..

Baixei o projeto aqui e está tudo ok.

Você configurou o CodeIgniter adequadamente ??
config e .htaccess ?

Abraço!!

Olá Flávio!

Também gostei muito do sistema de layout, até fiz algumas implementações.

Grato pelo ótimo tutorial.

Legal luciano..
se importa de mandar essas implementações para a gente ??

Abraço!!

E ai flavio,
tentei adaptar seu código pra funcionar no padrao HMVC ~> http://net.tutsplus.com/tutorials/php/hvmc-an-introduction-and-application/

mas ai ele nao funcionou direito, nao linkou o css nem o js =

Brayan,
consegue me mandar o projeto para eu dar uma olhada ???

Abraço!!

Opa.. mandei no seu e-mail.

Recebeu ai?

valww

Pessoal.

Para quem seguiu o tutorial a risca e não funcionou.

Se o seu sistema estiver dentro da pasta System. você terá que alterar a as constantes.

colocando ‘system/’ antes de $application_folder.

ficando assim:

define(‘LAYOUTPATH’, ‘system/’.$application_folder.’/layouts/’);
define(‘JSPATH’, ‘system/’.$application_folder.’/js/’);
define(‘CSSPATH’, ‘system/’.$application_folder.’/css/’);

Senão não vai funcionar.

Sugiro inclusive que o Flávio faça essa observação em seu tutorial.

Pois o projeto de exemplo dele funciona porque ele não tem a pasta system.

Abraços.

Legal a observação Diego..

A solução que você jogou fica estática, perde o dinamismo.
Eu vou adaptar o projeto e coloco a correção.

Abraço!

obrigado pelo projeto, sò que eu tenho um problema,
se digito http://code.artivisibili.com dà erro 404, tenho que digitar Http://code.artivisibili.com/Frontpage , onde “Frontpage” è o meu controller. Onde foi que eu errei?
eu estou começando hà pouco com CI e estou ficando maluco pra resolver.

p.s.: eu botei tambèm “Frontpage” no lugar de “welcome” na routes.php,mas nao funcionou.

foi mal, era uma besteira de quem nao leu bem a guida… o nome file deve ser(ao contrario da classe) tudo minusculo.

[...] O que mais gera acessos aqui no Blog são os artigos sobre Codeigniter, e principalmente a parte de layouts. É o artigo Habilitando Layouts no CodeIgniter (Template Engine) que está dividido em parte 1 e parte 2. [...]

Achei muito legal o seu post mas já não existe essa função do próprio codeigniter? $this->library(‘parse’).
Ela na verdade é um pouco mais completa com a possibilidade de looping assim como SMARTY Template.

André,
Template parser Class na verdade é para outro propósito.
Esse post refere-se a algo mais parecido com os Layouts no Zend Framework.

http://codeigniter.com/user_guide/libraries/parser.html

Abraço!

Muito boa sua matéria Flavio, me ajudou muito :-)

Quanto a localização da pasta, eu troquei ‘system/’.$application_folder.’ por APPPATH que vem definido no CI2 :-)

Estou tentando dividir o layout em partes assim:
{layout_header} — dentro dele eu chamo o {css_for_layout}
{content_for_layout}
{js_for_layout}
{layout_footer}

Porem não estou conseguindo….
Pode esclarecer de como dividir ele em partes.
Obrigado

Gostei muito das dicas e tenho um problema não consigo navegar entre as paginas você pode da uma dica de como fazer a navegação entre paginas
to tentando fazer isso:
exe:1

Link
Link

exe:2

Teste
contato

da este erro

Objeto não encontrado!

A URL requisitada não foi encontrada neste servidor. O link na página referida parece estar com algum erro ou desatualizado. Por favor informe o autor desta página sobre o erro.

Se você acredita ter encontrado um problema no servidor, por favor entre em contato com o webmaster.
Error 404
localhost
12/10/11 17:36:53
Apache/2.2.21 (Win32) mod_ssl/2.2.21 OpenSSL/1.0.0e PHP/5.3.8 mod_perl/2.0.4 Perl/v5.10.1

Erlon, Verifique se o arquivo htaccess está ok. Dê uma verificada nisso com a documentação oficial.
Qualquer coisa, faça o download do exemplo na parte 1 do artigo, ou também na versão para o Codeigniter 2 do artigo.
Abraço!

Olá, otimo post!
Estou com um probleminha no arquivo .htaccess! Como devo proceder? Quais configurações devo fazer?

Att,

Cara, bem legal mesmo. Estou começando a achar que vou precisar dever minha vida ao C.I, kkkkkkkkk ! Muito bom…

Quanto à essa solução, ainda vou compara-la à solução de templates do próprio C.I 2.0, ai posso determinar qual é mais eficiênte e/ou mais simples.

Quanto à esta solução (que prefiro nomear de templates), tive que fazer algumas adaptações p/ funcionar corretamente no meu cenário mas ficou show. (pelo menos por enquanto, hehehe)

Post a comment