domingo, 18 de novembro de 2012

Criando Templates no Web2py

O web2py permite que você crie uma aplicação padrão que já vem com tudo pronto para que você só tenha que se preocupar com a programação do seu aplicativo web. O layout padrão contém tudo o que você precisa para criar um aplicativo básico e ainda é possível obter dezenas de templates adicionais no site do web2py.
No entanto, muitas vezes temos a necessidade de criar um projeto com um layout diferente, do zero, mais personalizado. Nestes casos a melhor maneira de trabalharmos com layouts de aplicações web é utilizando templates. Um template é simplesmente um código HTML que pode ser aplicado em várias páginas dinâmicas, dando uniformidade a aplicação além de permitir uma manutenção rápida e reutilização de código.
Nos templates costumamos colocar blocos de código que são comuns a várias páginas como menus, cabeçalhos, rodapés, barras laterais ou componentes especiais.

O Básico 

 

Vamos começar com uma aplicação simples. Eu criei uma nova aplicação básica no web2py chamada MeuSite. Para começar do zero, vou ignorar todas as facilidades que o web2py oferece e apagar o conteúdo da página default/index.html. No lugar vou utilizar apenas a mensagem abaixo:
<h1>
Bem-vindo ao <span style="color: red;">Meu Site</span>!</h1>
Na hora de visualizar a aplicação o resultado será semelhante a isso:
 Agora vamos fazer uma pequena modificação na nossa view e ver o que acontece:
{{extend "layout.html"}}
<h1>
Bem-vindo ao <span style="color: red;">Meu Site</span>!</h1>
Uma simples linha na view produziu um resultado significativo:

O comando extend do web2py, assim como em vários outros frameworks MVC, serve para incluir a página dentro de um template já pronto, neste caso o template "layout.html" que já vem por padrão com o web2py. Podemos observar, pela imagem acima, que este template já possui um menu, um cabeçalho, um rodapé, um componente de integração com redes sociais além de incluir recursos de javascript que permitem os efeitos de notificação, exibição de menus, etc.
Este pacote de recursos incluído no template padrão é um dos responsáveis pela facilidade e rapidez com que conseguimos produzir novos aplicativos com o web2py.
Mas nem sempre isso é uma vantagem. Alguns destes recursos podem não ser necessários para nossa aplicação e resultar em um tempo maior de carregamento.
É importante ressaltar que nada impede que os recursos desnecessários contidos no "layout.html" sejam desabilitados livremente. Não precisamos, necessariamente criar um template novo.
Mas como este é o objetivo do artigo, vamos criar um template próprio, que contenha apenas o necessário para a nossa aplicação.

Capa e Menu 

 

Começaremos criando o topo da aplicação contendo um menu.
Para isso eu criei um arquivo na view chamado meu_template.html com o seguinte conteúdo:
<!DOCTYPE html>
<head><title>Meu Site</title>
<style type="text/css">
body{
background-color: gray;   
}
#pagina{
width:900px;
height:800px;
margin:0 auto;
background-color: white;
}
#capa{background-color: #000099;}
#menu ul{
padding: 0px;
margin: 0px;
list-style: none;
}
#menu ul li {display: inline;
}
#menu ul li a {
float: left;
padding: 10px 0px;
background-color: #000099;
font-family: Arial;
font-size: 16px;
text-align: center;
text-decoration: none;
color: white;
width: 25%;
}
#menu ul li a:hover {background-color: #6666ff;
}
</style>
</head>
<body>
<div id="pagina"><div id="capa"><img src="{{=URL('static','images/capa.jpg')}}"/><div id="menu"><ul>
<li><a href="#">Home</a></li>
<li><a href="#">Artigos</a></li>
<li><a href="#">Sobre</a></li>
<li><a href="#">Contato</a></li>
<li class="clear"></li>
</ul></div><br /><br />
    {{include}}
</div></body>
</html>
Não vou entrar em muitos detalhes sobre o HTML/CSS, apenas observe que eu defini a propriedade width=25% nos itens do menu para que os cinco links ocupem 100% do container, se o meu menu possuísse seis itens, o comprimento teria que ser de 20% e assim por diante.
Na página default/index.html vou alterar o template no comando extend:
{{extend "meu_template.html"}}
<h1>
Bem-vindo ao <span style="color: red;">Meu Site</span>!</h1>
Veja o resultado:


Observe que em determinado local do código do template existe um comando {{include}}. Este comando determina exatamente o local onde o conteúdo da página que irá extender o template deve aparecer. Se tiver dificuldade para entender a função do include experimente alterar o local dele no código, por exemplo, acima da div do menu e veja o resultado.

Barra Lateral 

 

Vamos incrementar o template adicionando uma barra lateral customizada.
Para isso, alterei o código do meu_template.html conforme o exemplo:
<!DOCTYPE html>
<head><title>Meu Site</title>
<style type="text/css">
body{
background-color: gray;   
}
#pagina{
width:900px;
height:800px;
margin:0 auto;
background-color: white;
}
#capa{background-color: #000099;}
#menu ul{
padding: 0px;
margin: 0px;
list-style: none;
}
#menu ul li {display: inline;
}
#menu ul li a {
float: left;
padding: 10px 0px;
background-color: #000099;
font-family: Arial;
font-size: 16px;
text-align: center;
text-decoration: none;
color: white;
width: 25%;
}
#menu ul li a:hover {background-color: #6666ff;
}
#barralateral{
width:300px;
height:550px;
float: right;
color:white;
font-family:Arial;
font-size:17px;
}
#barralateral li{list-style:none;margin-bottom:10px;}
#principal{width:600px;float:left;}
</style>
</head>
<body>
<div id="pagina"><div id="capa"><img src="{{=URL('static','images/capa.jpg')}}"/><div id="menu"><ul>
<li><a href="#">Home</a></li>
<li><a href="#">Artigos</a></li>
<li><a href="#">Sobre</a></li>
<li><a href="#">Contato</a></li>
<li class="clear"></li>
</ul></div>
<div id="principal">
<br /><br />
    {{include}}
</div>
<div id="barralateral">
    <div style="background-color:#3333ff;height:550px;">
    <div style="padding:30px;">
        <p><big>Encontre no Site</big></p>
    <input type="text"><input type="submit" value="Pesquisar">
    </div>
    <div style="padding:30px;">
        <p><big>Artigos Recentes</big></p>
    <ul>
        <li><b>Lorem Ipsum</b></li>
        <li><b>dolor sit amet</b></li>
        <li><b>consectetur adipiscing</b></li>
    </div>
    </div>   
</div>
</div></body>
</html>
O resultado ficou assim:

 

 Rodapé

 

Para completar o visual, adicionei um rodapé ao template com o seguinte código:
<!DOCTYPE html>
<head><title>Meu Site</title>
<style type="text/css">
body{
background-color: gray;   
}
#pagina{
width:900px;
height:800px;
margin:0 auto;
background-color: white;
}
#capa{background-color: #000099;}
#menu ul{
padding: 0px;
margin: 0px;
list-style: none;
}
#menu ul li {display: inline;
}
#menu ul li a {
float: left;
padding: 10px 0px;
background-color: #000099;
font-family: Arial;
font-size: 16px;
text-align: center;
text-decoration: none;
color: white;
width: 25%;
}
#menu ul li a:hover {background-color: #6666ff;
}
#barralateral{
width:300px;
height:550px;
float: right;
color:white;
font-family:Arial;
font-size:17px;
}
#barralateral li{list-style:none;margin-bottom:10px;}
#principal{width:600px;float:left;}
#rodape {
padding-top:10px;
background-color:#000099;
color: white;
font-family: Arial;
font-size: 16px;
text-align: center;
width:100%;
height:50px;
float:left;
}
</style>
</head>
<body>
<div id="pagina"><div id="capa"><img src="{{=URL('static','images/capa.jpg')}}"/><div id="menu"><ul>
<li><a href="#">Home</a></li>
<li><a href="#">Artigos</a></li>
<li><a href="#">Sobre</a></li>
<li><a href="#">Contato</a></li>
<li class="clear"></li>
</ul></div>
<div id="principal">
<br /><br />
    {{include}}
</div>
<div id="barralateral">
    <div style="background-color:#3333ff;height:550px;">
    <div style="padding:30px;">
        <p><big>Encontre no Site</big></p>
    <input type="text"><input type="submit" value="Pesquisar">
    </div>
    <div style="padding:30px;">
        <p><big>Artigos Recentes</big></p>
    <ul>
        <li><b>Lorem Ipsum</b></li>
        <li><b>dolor sit amet</b></li>
        <li><b>consectetur adipiscing</b></li>
    </div>
    </div>   
</div>
<div id="rodape">
2012 © Jonathan Hepp
</div>
</div></body>
</html>
Veja como ficou:

 

Mais Recursos

 

Note que o template é uma página HTML completa, inclusive com as tags head. Isto significa que você pode, e deve, utilizar os templates para incluir estilos, scripts e demais componentes externos necessários para suas aplicações. Você pode adicionar arquivos CSS da forma tradicional ou utilizando o response.files.append() (Mais detalhes no Livro).
Tenha em mente que embora o template esteja separado do conteúdo principal da sua aplicação, em tempo de execução, tudo vira uma única página HTML. Portanto, scripts e estilos adicionados no template afetam o conteúdo da aplicação, o que é desejável, porém pode trazer resultados inesperados se não houver atenção no momento do desenvolvimento. Por isso, procure adicionar no template apenas o que for necessário para a sua aplicação.

Layout Condicional

 

É possível definir que tipo de conteúdo será carregado no template de acordo com variáveis pré-definidas.
Observe esta modificação no trecho do código do template que define a barra lateral:

<div id="barralateral">
    {{if barralateral:}}
    <div style="background-color:#3333ff;height:550px;">
    <div style="padding:30px;">
        <p><big>Encontre no Site</big></p>
    <input type="text"><input type="submit" value="Pesquisar">
    </div>
    <div style="padding:30px;">
        <p><big>Artigos Recentes</big></p>
    <ul>
        <li><b>Lorem Ipsum</b></li>
        <li><b>dolor sit amet</b></li>
        <li><b>consectetur adipiscing</b></li>
    </div>
    </div>   
    {{pass}}
</div>
E na página default/index.html modifico o código desta forma:
{{barralateral=False}}
{{extend "meu_template.html"}}
<h1>Bem-vindo ao <span style="color:red;">Meu Site</span>!</h1>
Ou seja, definindo a variável barralateral para False, o conteúdo dentro do bloco if não é carregado no template e a barra lateral não será exibida. Agora, definindo a variável como True, a barra volta a ser exibida. Este é um recurso muito poderoso e que dá uma grande liberdade ao desenvolvedor para criar templates flexíveis e reaproveitáveis.
No entanto, observe que o uso exagerado deste recurso pode resultar em um aumento no tempo de carregamento das páginas.

Todo o Poder dos Templates

 

O exemplo mostrado neste artigo é basicamente estático. O web2py permite que um template inclua códigos de diversas páginas com conteúdo dinâmico (como o componente de artigos recentes, por exemplo). Em um futuro artigo, abordarei recursos mais avançados dos templates.

Um comentário: