Cada projeto do TurboGears tende a ser um site completo e auto-suficiente. Desta forma, se queremos adicionar uma página HTML ao nosso site, mesmo que seja uma página estática, devemos fazê-lo à moda do TurboGears.
As páginas devem ser escritas em XML, numa gramática que o motor de templates Kid entende e transforma para HTML 4.01 transicional, HTML 4.01 estrito ou XHTML, conforme estiver configurado o projeto.
Quando você abriu a página http://localhost:8080, o conteúdo dela foi subproduto de dois arquivos: um template ajaxfin/templates/welcome.kid, e uma referência a esse template no Controlador (arquivo ajaxfin/controllers.py).
Observe a classe Root, criada automaticamente ao iniciar o projeto TurboGears:
class Root(controllers.RootController):
@expose(template="ajaxfin.templates.welcome")
def index(self):
import time
log.debug("Happy TurboGears Controller Responding For Duty")
return dict(now=time.ctime())
O decorator @expose é quem liga o método Root.index ao template welcome.kid. Note ainda que o caminho do template é especificado com pontos, não barras (para garantir a portabilidade).
Tente agora experimentar criar uma nova página. Copie o template ajaxfin/templates/welcome.kid para ajaxfin/templates/fincalc.kid. Se possível, mude algo no novo template, para que você tenha como fiscalizar que é a "sua" nova página. A seguir, Abra o arquivo ajaxfin/controllers.py e adicione mais um método à classe Root:
@expose(template="ajaxfin.templates.fincalc")
def fincalc(self):
import time
log.debug("Happy TurboGears Controller Responding For Duty")
return dict(now=time.ctime())
Logo que você salva controllers.py, o TurboGears (se estiver rodando) detecta a mudança e recarrega a classe. Carregue agora o link http://localhost:8080/fincalc.
Bem, nós queremos fazer uma calculadora Web, não uma página estática. Precisamos criar um template que "desenhe" uma calculadora. Devem haver formas melhores, mas a nossa versão baseada em formulário e tabela é a seguinte:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://purl.org/kid/ns#"
py:extends="'master.kid'">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/>
<title>AJAX Calculator (proof of concept)</title>
<SCRIPT SRC="/static/javascript/fincalc.js" TYPE="text/javascript"></SCRIPT>
<link rel="STYLESHEET" href="/static/css/fincalc.css" type="text/css"></link>
</head>
<body>
<hr/>
<form name="calc" onSubmit="return false">
<fieldset>
<legend>AJAX calculator (proof of concept)</legend>
<table>
<tr>
<td>
<input type="text" name="n" value="0" size="12"/>
</td>
<td>
<input type="button" name="Button_n" value="n" onClick="fincalc('n')" class="mybutton"/>
</td>
<td>
<input type="button" name="Button_pot" value="x^y" onClick="fincalc('pow')" class="mybutton"/>
</td>
<td>
<input type="button" name="Button_root" value="1/y" onClick="fincalc('inv')" class="mybutton"/>
</td>
</tr>
<tr>
<td>
<input type="text" name="i" value="0.00" size="12"/>
</td>
<td>
<input type="button" name="Button_i" value="i" onClick="fincalc('i')" class="mybutton"/>
</td>
<td>
<input type="button" name="Button_div" value="÷" onClick="fincalc('/')" class="mybutton"/>
</td>
<td>
<input type="button" name="Button_begin" value="Begin" onClick="begin_toogle()" class="mybutton_0"/>
<input type="hidden" name="begin" value="0"/>
</td>
</tr>
<tr>
<td>
<input type="text" name="PV" class="yellowform" value="0.00" size="12"/>
</td>
<td>
<input type="button" name="Button_PV" value="PV" onClick="fincalc('PV')" class="mybutton"/>
</td>
<td>
<input type="button" name="Button_times" value="×" onClick="fincalc('*')" class="mybutton"/>
</td>
<td>
<input type="button" name="Button_stoeex" value="CFP" onClick="stoeex_toogle()" class="mybutton_1"/>
<input type="hidden" name="stoeex" value="1"/>
</td>
</tr>
<tr>
<td>
<input type="text" name="PMT" class="yellowform" value="0.00" size="12"/>
</td>
<td>
<input type="button" name="Button_PMT" value="PMT" onClick="fincalc('PMT')" class="mybutton"/>
</td>
<td>
<input type="button" name="Button_minus" value="-" onClick="fincalc('-')" class="mybutton"/>
</td>
<td>
</td>
</tr>
<tr>
<td>
<input type="text" name="FV" class="blueform" value="0.00" size="12"/>
</td>
<td>
<input type="button" name="Button_FV" value="FV" onClick="fincalc('FV')" class="mybutton"/>
</td>
<td>
<input type="button" name="Button_plus" value="+" onClick="fincalc('+')" class="mybutton"/>
</td>
<td class="alignright">
<input type="text" name="decimals" value="2" maxlength="1" size="1"/>
</td>
</tr>
</table>
</fieldset>
</form>
<hr/>
</body>
</html>
A gramática desse arquivo de templates é basicamente XHTML, porém com um namespace a mais (py:). Os parâmetros prefixados com "py:" são código Python/Kid; é onde os truques do Kid são adicionados. Isto permite que o template seja diretamente testado num navegador. O Kid é bastante diferente, po rexemplo, do PHP.
Neste nosso exemplo, o único parâmetro Kid é py:extends="'master.kid'", que significa que nosso template é uma "subclasse" de ajaxfin/templates/master.kid, e dele herda elementos como cabeçalho e rodapé.
Se você preferir pode fazer download do projeto pronto e copiar esse arquivo pronto para seu projeto. Esta página, carregada no navegador, deve ficar mais ou menos assim:
Não está muito atraente, mas podemos adicionar um arquivo CSS para dar uma embelezada. Como o arquivo CSS é totalmente estático (nem sequer é transformado de XML para HTML), deve ficar na pasta <project>/static/css. Criamos o arquivo fincalc/static/css/fincalc.css com o seguinte conteúdo:
table
{
border: 0;
cell-padding: 2;
}
fieldset
{
border: 1px solid #781351;
width: 25em
}
legend
{
color: #fff;
background: #ffa20c;
border: 1px solid #781351;
padding: 2px 6px
}
input
{
text-align: right;
border: 3px double #999999;
border-top-color: #CCCCCC;
border-left-color: #CCCCCC;
padding: 0.25em;
background-color: #FFFFFF;
color: #333333;
font-size: 75%;
font-weight: bold;
font-family: Verdana, Helvetica, Arial, sans-serif;
}
.mybutton {
width: 5em;
}
.mybutton_0 {
width: 5em;
background-color: #F0F0F0;
}
.mybutton_1 {
width: 5em;
background-color: #FFFF00;
}
.blueform
{
background-color: #B0FFFF;
}
.yellowform
{
background-color: #FFFFC0;
}
.alignright
{
text-align: right;
}
Imagino que a aparência da página com o CSS no lugar deva ter ficado mais agradável:
Nesse ponto, a calculadora ainda não faz nada útil.
A seguir: As rotinas Javascript >>>