<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>
      Construindo um Website Din&acirc;mico
      com Class::DBI, CGI::Application e Template Toolkit
    </title>
    <style type="text/css">
      body { padding-left: 10%; padding-right: 8%; }
      p { text-align:justify; font-family: sans-serif; }
      div.title p:first-child{ font-weight: bold; font-size: 200%; text-align: center; }
      div.title p{ font-weight: bold;
                   text-align: center;
                   font-size: 85%;
                   margin-left: 15%;
                   margin-right: 15%;
                 }
      div.preface p:first-child { margin-top: 0px;
                                  font-style: normal;
                                  font-weight: bold;
                                  font-size: 120%;
                                  text-align: left;
                                  text-decoration: underline;
                                }
      div.preface p { text-align: justify;
                      font-style: italic;
                      margin-left: 10%;
                      margin-right: 10%;
                      font-size: 80%;
                    }
      div.paragraph p { text-align: justify; }
      div.paragraph p:first-child { margin-top: 0px;
                                          font-weight: bold;
                                    font-size: 120%;
                                    text-decoration: underline;
                                  }
      pre.code { font-family: monospace;
                 font-size: 80%;
                 border: thin solid lightgray;
                 padding-top: 10px;
                 padding-left: 15px;
                 padding-bottom: 10px;
                 background-color: LightGray;
                 margin-left: 10%;
                 margin-right: 15%;
               }
      pre.code span.reserved-word { font-weight:bold; }
      
      div.display { text-align: center; }
    </style>
  </head>
  <body>
    <div class="title">
      <p>Construindo um Website Din&acirc;mico com Class::DBI, CGI::Application e Template Toolkit    </p>
      <p>Por Luis Campos de Carvalho, L&iacute;der do S&atilde;o Paulo Perl Mongers<br>
      mailto: monsieur_champs [at] yahoo [dot] com [dot] br</p>
    </div>
    
    <div class="preface">
      <p>Pref&aacute;cio</p>
      <p>Quando pensamos em aplicativos World Wide Web em Perl, normalmente nos vêem à cabe&ccedil;a aqueles programas gigantescos, desorganizados, cheios de problemas e praticamente imposs&iacute;veis de se manter. Neste modesto e mal-escrito artigo, eu pretendo mostrar que &eacute; poss&iacute;vel construir aplicativos din&acirc;micos, baseados nas tecnologias da World Wide Web, simples, r&aacute;pidos, f&aacute;ceis de manter e extens&iacute;veis, usando ferramentas de código fonte aberto, no&ccedil;&otilde;es sobre o paradigma da Orienta&ccedil;&atilde;o a Objetos, e algumas t&eacute;cnicas de engenharia de software b&aacute;sica.</p>
    </div>
    
    <div class="paragraph">
      <p>Molhando os P&eacute;s: primeiro contato com as tecnologias utilizadas neste artigo</p>
      <p>Para come&ccedil;ar, vamos falar da aplica&ccedil;&atilde;o que desejamos fazer: &eacute; simples, e chega a ser at&eacute; meio besta, para facilitar a compreens&atilde;o. Desta forma, ao inv&eacute;s de se prender aos detalhes e complexidades da aplica&ccedil;&atilde;o que vamos construir, o leitor ter&aacute; sua aten&ccedil;&atilde;o presa aos detalhes e complexidades envolvidas com <em>como</em> construir a aplica&ccedil;&atilde;o.</p>
      <p>Vamos construir um Módulo de Autentica&ccedil;&atilde;o de Usu&aacute;rios.</p>
      <p>A responsabilidade principal de um Módulo de Autentica&ccedil;&atilde;o de Usu&aacute;rios &eacute; se certificar de que um usu&aacute;rio de nosso website &eacute; realmente quem ele diz ser, e permitir a ele acesso aos demais recursos din&acirc;micos dispon&iacute;veis em nosso website fict&iacute;cio.</p>
      <p>Para construir esta aplica&ccedil;&atilde;o, vamos utilizar um <i>framework</i> de desenvolvimento de aplica&ccedil;&otilde;es din&acirc;micas para a World Wide Web chamado <a href="http://search.cpan.org/~markstos/CGI-Application-4.04_02/">CGI::Application</a>, combinado com um gerenciador de banco de dados relacional (eu escolhi usar o <a href="http://www.postgresql.org">PostgreSQL</a>, mas outros, como o <a href="http://www.mysql.com">MySQL</a> e o <a href="http://www.oracle.com">Oracle</a> se encaixam aqui perfeitamente e n&atilde;o precisam de adapta&ccedil;&otilde;es) atrav&eacute;s do uso de um conjunto de objetos Perl chamado <a href="http://search.cpan.org/~tmtm/Class-DBI-0.96/">Class::DBI</a>. Completam o nosso conjunto de bibliotecas-base um <i>framework</i> de visualiza&ccedil;&atilde;o muito poderoso chamado <a href="http://www.template-toolkit.org">Template Toolkit</a> e um pouco de teoria sobre padr&otilde;es de projeto e modelagem orientada a objetos.</p>
    </div>
    
    <div class="paragraph">
      <p>O Projeto da Aplica&ccedil;&atilde;o</p>
      <p>Antes de continuarmos, vamos especificar e modelar rapidamente nossa aplica&ccedil;&atilde;o. Isso, al&eacute;m de nos dar maior consciência sobre o que estamos construindo, ajuda as pessoas a compreender nosso trabalho (e a valoriz&aacute;-lo).</p>
      <p>Nosso Módulo de Autentica&ccedil;&atilde;o de Usu&aacute;rios ter&aacute; apenas um ponto de entrada: ele gerar&aacute; uma p&aacute;gina para coletar o nome e senha do usu&aacute;rio, tomar&aacute; uma decis&atilde;o baseado nos dados que o usu&aacute;rio lhe enviar e executar&aacute; uma das duas &uacute;nicas a&ccedil;&otilde;es planejadas para ele: ou criar&aacute; uma sess&atilde;o para o usu&aacute;rio e o redirecionar&aacute; para a parte restrita de nosso website din&acirc;mico, ou enviar&aacute; uma mensagem de erro, informando ao usu&aacute;rio que o par (nome, senha) apresentado n&atilde;o &eacute; v&aacute;lido. Em <em>Portugol</em>, para ficar simples:</p>
      
      <pre class="code">  <span class="comment"># Processo 1: coleta de credenciais</span>
  <span class="reserved-word">IN&Iacute;CIO;</span>
    constrói p&aacute;gina de coleta de dados;
    envia p&aacute;gina de coleta de dados;
  <span class="reserved-word">FIM.</span>
  
  <span class="comment"># Processo 2: autentica&ccedil;&atilde;o de usu&aacute;rios.</span>
  <span class="reserved-word">IN&Iacute;CIO;</span>
    &lt;usu&aacute;rio preenche informa&ccedil;&otilde;es de autentica&ccedil;&atilde;o&gt;;
    recebe dados de autentica&ccedil;&atilde;o de usu&aacute;rio;
    verifica dados;
    <span class="reserved-word">SE</span> dados v&aacute;lidos, <span class="reserved-word">ENT&Atilde;O</span>
      <span class="reserved-word">IN&Iacute;CIO</span>
        gera informa&ccedil;&atilde;o de sess&atilde;o;
        registra informa&ccedil;&atilde;o de sess&atilde;o;
        envia <i>cookie</i> identificador ao usu&aacute;rio;
        redireciona usu&aacute;rio autenticado para a aplica&ccedil;&atilde;o;
      <span class="reserved-word">FIM</span>
    <span class="reserved-word">SEN&Atilde;O</span>
      <span class="reserved-word">IN&Iacute;CIO</span>
        gera p&aacute;gina de informa&ccedil;&atilde;o de erro;
        envia p&aacute;gina ao usu&aacute;rio;
      <span class="reserved-word">FIM;</span>
    <span class="reserved-word">FIMSE;</span>
  <span class="reserved-word">FIM;</span></pre>

      <p>Agora que sabemos como deve ser nosso processo, vamos modelar rapidamente os dados necess&aacute;rios para autenticar um usu&aacute;rio. Precisamos apenas reter permanentemente algumas informa&ccedil;&otilde;es sobre os usu&aacute;rios, como um nome, e uma senha. Para isso, vamos criar uma tabela em nosso banco de dados relacional, utilizando este código SQL:</p>
      <p>Isto vai criar uma tabela em nosso banco de dados, onde poderemos registrar nossos usu&aacute;rios.</p>

      <pre class="code">-- Este script assume que voc&ecirc; tem um banco de dados PostgreSQL, pode
-- conectar-se a ele e tem permiss&otilde;es m&iacute;nimas para realizar cria&ccedil;&atilde;o de
-- tabelas e inclus&atilde;o de registros nas tabelas criadas.

-- Se voc&ecirc; tiver qualquer problema com isso, converse com seu DBA ou
-- Administrador de Sistemas local.

-- Copyleft 2005 Luis Campos de Carvalho
-- Copyleft 2005 Engenharia de Software Ltda
-- Doado aos S&atilde;o Paulo Perl Mongers

-- This script is free software; you can redistribute it and/or modify
-- it under the term of the GNU Public License.

CREATE SEQUENCE seq_usuario;

CREATE TABLE usuario (
  uid   INTEGER PRIMARY KEY DEFAULT NEXTVAL( 'seq_usuario'::text ),
  login VARCHAR UNIQUE      NOT NULL,
  senha VARCHAR             NOT NULL
);

-- EOF </pre>

    <p>A aplica&ccedil;&atilde;o do <a href="http://www.w3schools.com/sql/default.asp">SQL</a> no banco de dados varia muito. Por isso, vou deixar a tarefa de descobrir como se conectar ao banco de dados e criar tabelas para um futuro artigo sobre <a href="http://search.cpan.org/~timb/DBI-1.48/">DBI</a> e <a href="http://search.cpan.org/~tmtm/Class-DBI-0.96/">Class::DBI</a>.</p>
    <p>Vamos passar agora &agrave; parte de modelagem de objetos e módulos necessários para a aplicação. Para isso, antes, precisamos conversar um pouco sobre <a href="http://en.wikipedia.org/wiki/MVC">MVC</a>, <a href="http://search.cpan.org/~tmtm/Class-DBI-0.96/">Class::DBI</a>, <a href="http://www.template-toolkit.org">Template Toolkit</a> e <a href="http://search.cpan.org/~markstos/CGI-Application-4.03/">CGI::Application</a>.</p>
    </div>
  
  <div class="paragraph">
    <p>MVC, Class::DBI e CGI::Application</p>
    <p>Agora vamos entrar na parte complicada deste tutorial. O leitor amigo possivelmente deve ter ouvido alguma coisa a respeito de <a href="">MVC</a>, ou, para os iniciados, <em>Model-View-Controller</em>. Este &eacute; um padr&atilde;o de projeto (<em>Design Pattern</em>) que separa toda e qualquer aplica&ccedil;&atilde;o em tr&ecirc;s componentes b&aacute;sicos: o Modelo(<em>Model</em>), a Vis&atilde;o (<em>View</em>) e o Controlador (<em>Controller</em>). Leiam um <a href="http://www.andywardley.com/computers/web/mvc.html">contraponto</a>, por <a href="http://www.wardley.org/">Andy Wardley</a>.</p>
    <p>Em poucas palavras, j&aacute; que eu n&atilde;o pretendo nem de longe esgotar este assunto: o <b>Modelo</b> &eacute; respons&aacute;vel por manter nossos dados e manipul&aacute;-los de acordo com as regras de neg&oacute;cio (que implementamos neles). S&atilde;o os modelos (geralmente temos muitos) que sabem como e onde armazenar e recuperar os dados que captamos e utilizamos.</p>
    <p>Enquanto os modelos s&atilde;o respons&aacute;veis pelos dados e pelas regras de neg&oacute;cio (a forma de manipular os dados), as <b>Vis&otilde;es</b> tem como responsabilidade a exibi&ccedil;&atilde;o dos dados encontrados nos modelos. Uma vis&atilde;o normalmente conhece um modelo e sabe como exibir os dados daquele modelo por alguma m&iacute;dia espec&iacute;fica. Por exemplo: suponha que temos uma lista de usu&aacute;rios (um Modelo representando usu&aacute;rios) e desejamos exibir estes usu&aacute;rios pela internet (com <a href="http://www.w3.org/MarkUp/">HTML</a>) e em um telefone celular (com <a href="http://www.umtsworld.com/technology/wap.htm">WAP</a>). Para tornar isso poss&iacute;vel, n&atilde;o precisamos mexer em nada relacionado com nossa lista de usu&aacute;rios: precisamos apenas implementar Vis&otilde;es capazes de exibir em HTML ou WAP. Assim, quando desejamos exibir a lista de usu&aacute;rios em HTML, utilizamos a vis&atilde;o capaz de exibir a lista em HTML e quando desejamos exibir nossos usu&aacute;rios em WAP, utilizamos a vis&atilde;o que implementa exibi&ccedil;&atilde;o WAP.</p>
    <p>Finalmente, o <b>Controlador</b> tem um papel n&atilde;o muito intuitivo, mas muito importante, depois que se aprende a utiliz&aacute;-lo corretamente: &eacute; dele a responsabilidade de decidir, para cada requisi&ccedil;&atilde;o enviada para nossa aplica&ccedil;&atilde;o, qual modelo deve ser acionado para tratar dela. &Eacute; tamb&eacute;m do Controlador a responsabilidade de verificar as credenciais de um usu&aacute;rio e determinar suas permiss&otilde;es de acesso. Normalmente, uma aplica&ccedil;&atilde;o web tem apenas um controlador, n&atilde;o importa o qu&atilde;o grande ela seja.</p>
    <p>A esta altura, voc&ecirc; deve estar se perguntando qual a rela&ccedil;&atilde;o disso tudo com as bibliotecas Perl <a href="http://search.cpan.org/~tmtm/Class-DBI-0.96/">Class::DBI</a>, <a href="http://www.template-toolkit.org">Template Toolkit</a> e <a href="http://search.cpan.org/~markstos/CGI-Application-4.04_02/">CGI::Application</a>. &Eacute; hora de explicar: cada uma desta bibliotecas implementa um dos elementos do MVC que vamos utilizar em nossa aplica&ccedil;&atilde;o: <a href="http://search.cpan.org/~tmtm/Class-DBI-0.96/">Class::DBI</a> implementa modelos, <a href="http://www.template-toolkit.org">Template Toolkit</a> implementa vis&otilde;es e CGI::Aplication implementa nosso controlador. Vamos construir agora cada uma das diferentes partes do padr&atilde;o de projeto que utilizaremos:</p>
  </div>
  
  <div class="paragraph">
    <p>Implementa&ccedil;&atilde;o da Camada de Acesso a Dados com Class::DBI</p>
    <p>Para implementar o modelo, vamos precisar de ajuda de mais um padr&atilde;o de projetos, o <i>Data Access Object</i>, ou <a href="http://en.wikipedia.org/wiki/Data_Access_Object">DAO</a>, para os íntimos.</p>
    <p>Este padr&atilde;o de projeto consiste em manter objetos separados para cuidar das responsabilidades específicas de manipular e armazenar os dados. Fazemos isso para que, quando precisarmos alterar a forma ou o local de armanzenamento das informa&ccedil;&otilde;es, n&atilde;o precisemos alterar nossos processo de manipula&ccedil;&atilde;o de dados, apenas o processo de armanzenamento e recupera&ccedil;&atilde;o. Isto torna menor a possibilidade de introdu&ccedil;&atilde;o de novos erros em um sistema antigo por mudan&ccedil;as menos importantes para o neg&oacute;cio.</p>
    <p>Para implementar o DAO, vamos utilizar uma biblioteca pronta. Isto &eacute; muito melhor que ser obrigado a "reinventar a roda" e construir n&oacute;s mesmos.</p>
    <p>Optamos pela biblioteca <a href="http://search.cpan.org/~tmtm/Class-DBI-0.96/">Class::DBI</a>. Poder&iacute;amos ter optado por outras semelhantes, como a <a href="http://search.cpan.org/~cwinters/SPOPS-0.87/">SPOPS</a>, que tem funcionalidade semelhante, mas oferece muitos recursos extras.</p>
    <p><a href="http://search.cpan.org/~tmtm/Class-DBI-0.96/">Class::DBI</a> deve ser implementada atrav&eacute;s de extens&atilde;o do objeto Class::DBI, e declara&ccedil;&atilde;o de alguns m&eacute;todos est&aacute;ticos para informar &agrave; biblioteca sobre nosso banco de dados, nossas tabelas e nosso m&eacute;todo preferido de carga de dados. Adicionalmente, podemos ir al&eacute;m e implementar m&eacute;todos para desempenhar tarefas mais espec&iacute;ficas, como algum tipo de <i>query</i> especial para nossa aplica&ccedil;&atilde;o, ou outras funcionalidades semelhantes. Mas isso tamb&eacute; est&aacute; fora do nosso escopo de hoje. Vamos ver como deve ser nossa classe-base, devidamente comentada:</p>

    <pre class="code">=head1 NAME

DAO::Base - Classe base para objetos de acesso a dados

=cut

package DAO::Base;

use strict;
use warnings;

use base qw( Class::DBI );

our $VERSION = sprintf '%d.%02d', q$Revision:$ =~ m/(\d+)\.(\d+)/;

=head1 SYNOPSIS

  use base qw( DAO::Base );

=head1 DESCRIPTION

  Esta é a classe base dos Objetos de Acesso a Dados, derivados de
  Class::DBI.

=cut

__PACKAGE__->connection( 'dbi:Pg:dbname',
                         'dbuser', 'secret',
                         { AutoCommit => 1,
                           RaiseError => 1,
                           PrinError  => 0,
                         }
                       );

=head1 AUTHOR

  Luis Campos de Carvalho
  Engenharia de Software Ltda.

=head1 REVISION

  $Revision: $

=head1 COPYRIGHT

  Copyleft 2005 Engenharia de Software Ltda.

  Doado aos São Paulo Perl Mongers.

  This module is free software; you can redistribute it and/or modify it
  under the term of the GNU Public License.

=head1 SEE ALSO

    L&lt;Class::DBI&gt;
</pre>
        
    <p>Este m&oacute;dulo &eacute; composto de algumas declara&ccedil;&otilde;es interessantes: primeiramente, o nome do pacote <code>package DAO::Base</code> foi escolhido com finalidade did&aacute;tica. &Eacute; simples modificar isto quando for utilizado em um projeto s&eacute;rio (sim, estou acreditando que as pessoas v&atilde;o se aproveitar deste c&oacute;digo em projeots s&eacute;rios!).</p>
    <p>A pr&oacute;xima coisa interessante a se notar &eacute; relacionada com heran&ccedil;a: eu declarei que este pacote tem como base (e herda funcionalidades de) Class::DBI, com a asser&ccedil;&atilde;o <code>use base qw( Class::DBI );</code> isto &eacute; equivalente a dizer <code>BEGIN{ require Class::DBI; push @ISA, 'Class::DBI'; }</code>, mas &eacute; bem mais curto e f&aacute;cil de entender.</p>
    <p>Tamb&eacute;m &eacute; neste m&oacute;dulo que devemos declarar os dados de conex&atilde;o com nosso banco de dados, para que ela possa ser compartilhada transparentemente entre todos os m&oacute;dulos derivados deste. Declaramos nossa conex&atilde;o utilizando o m&eacute;todo est&aacute;tico <code>Class::DBI::connection()</code>, mas o chamamos com <code>__PACKAGE__->connection()</code>. Isto &eacute; boa pr&aacute;tica de programa&ccedil;&atilde;o orientada a objetos em Perl, j&aacute; que n&atilde;o podemos assumir qual o tipo que ser&aacute; passado para n&oacute;s quando da instancia&ccedil;&atilde;o desta classe. A diretriz <code>__PACKAGE__</code> cuida sozinha destes detalhes, fazendo a coisa certa por n&oacute;s. Ela sempre vai resolver para o nome do pacote correto, n&atilde;o importa o que aconte&ccedil;a. Para saber mais sobre os par&acirc;metros passados ao banco de dados, por favor consultem a documenta&ccedil;&atilde;o do <a href="http://search.cpan.org/~timb/DBI-1.48/">DBI</a>.</p>
    <p>Depois de declarar nossa conex&atilde;o com o banco de dados, estamos prontos para extender esta classe e especializ&aacute;-la para cada uma das tabelas que teremos.</p>
    <p>A &uacute;nica tabela que teremos neste sistema &eacute; a tabela de usu&aacute;rios. Mas lembrem-se: para extender este sistema para um sistema completo e &uacute;til, basta seguir a mesma linha de pensamento que estamos desenvolvendo aqui e continuar implementando as funcionalidades restantes.</p>
    <p>Nosso objeto de acesso a dados de usu&aacute;rio ser&aacute; declarado desta forma:</p>
  
    <pre class="code">=head1 NAME

  DAO::Usuario - Objeto de Acesso a Dados da tabela 'usuario'.

=cut

package DAO::Usuario;

use warnings;
use strict;

use base qw( DAO::Usuario );

our $VERSION = sprintf '%d.%02d', q$Revision:$ =~ m/(\d+)\.(\d+)/;

=head1 SYNOPSIS

  use DAO::Usuario; $user = DAO::Usuario->create( ... ); $user =
  DAO::Usuario->retrieve( ... ); $user = DAO::Usuario->search( ... );

=head1 DESCRIPTION

Este é o módulo de acesso a dados da tabela de usuarios do sistema de
autenticacao de usuarios desenvolvido para o mini-curso da UNISAL.

=cut

__PACKAGE__->table( 'usuario' );
__PACKAGE__->columns( All => qw[ id login senha ] );

=head1 AUTHOR

  Luis Campos de Carvalho Engenharia de Software Ltda.

=head1 REVISION

  $Revision: $

=head1 COPYRIGHT

  Copyleft 2005 Engenharia de Software Ltda.

  Doado aos São Paulo Perl Mongers.

  This module is free software; you can redistribute it and/or modify
  it under the term of the GNU Public License.

=head1 SEE ALSO

L&lt;Class::DBI&gt;
</pre>
  
    <p>Reparem que este m&oacute;dulo se parece muito com o outro. Declaramos um pacote no mesmo n&iacute;vel, <code>DAO::Usuario</code>, para modelar nossos usu&aacute;rios. Em seguida, declaramos que herdamos as fucnionalidades de <code>DAO::Base</code>, em especial duas muito importantes: 1) &eacute; de l&aacute; que vem nossas informa&ccedil;&otilde;es de banco de dados, que vamos precisar para fazer com que este m&oacute;dulo possa recuperar e armazenar alguma informa&ccedil;&atilde;o no banco de dados; e 2) como <code>DAO::Base</code> herda de <code>Class::DBI</code> (lembra?), tamb&eacute;m nosso m&oacute;dulo herda as funcionalidades implementadas l&aacute;. &Eacute; este pequeno detalhe que faz com que tudo isso funcione perfeitamente.</p>
    <p>As declara&ccedil;&otilde;es que precisamos fazer aqui s&atilde;o simples: precisamos declarar qual tabela este m&oacute;dulo acessa, e quais os campos da tabela que estar&atilde;o vis&iacute;veis para nossa aplica&ccedil;&atilde;o. N&atilde;o, voc&ecirc; n&atilde;o precisa declarar todos os campos como vis&iacute;veis. Mas n&atilde;o h&aacute; como o <code>Class::DBI</code> conhecer (ou utilizar) os campos que voc&ecirc; n&atilde;o declarar. Use isto com sabedoria.</p>
    <p>Para declarar tabelas, utilizamos a diretriz auto-explicativa <code>__PACKAGE__->table( 'usuario' )</code>. Como todos j&aacute; perceberam, o &uacute;nico par&acirc;metro passado (o nome da tabela) &eacute; obrigat&oacute;rio.</p>
    <p><strong>Depois</strong> (lembrem-se: <strong>Depois</strong>!) de declarar qual tabela desejamos acessar, podemos ent&atilde;o declarar quais colunas desta tabela desejamos que nosso m&oacute;dulo veja. Note que isso implica que podemos ter tabelas com quantos atributos desejar, e podemos controlar quais m&oacute;dulos acessam que colunas atrav&eacute;s desta declara&ccedil;&atilde;o.</p>
    <p>Para declarar as colunas vis&iacute;veis, utilizamos <code>__PACKAGE__->columns( All => qw[ id login senha ] );</code> isto declara tr&ecirc;s colunas vis&iacute;veis, e <strong>implicitamente</strong> declara que a primeira coluna da lista (<code>id</code>) &eacute; nossa chave prim&aacute;ria.</p>
    <p>Com isso, encerramos a parte de constru&ccedil;&atilde;o da camada de acesso a dados. O que temos at&eacute; este momento s&atilde;o dois objetos simples: <code>DAO::Base</code> e <code>DAO::Usuario</code>. </p>
    <p>Por agora, vamos apenas reservar estes m&oacute;dulos. Vamos precisar deles mais adiante.</p>
  </div>
  
  <div class="paragraph">
    <p>Implementa&ccedil;&atilde;o das Vis&otilde;es com Template Toolkit</p>
    <p>Agora que podemos contar com nossos objetos de acesso a dados, vamos implementar nossas vis&otilde;es. S&atilde;o elas que dar&atilde;o um rosto para nossa aplica&ccedil;&atilde;o, e por isso mesmo devem ser tratadas com um certo cuidado. Como esta &eacute; uma aplica&ccedil;&atilde;o reutiliz&aacute;vel, devemos tomar alguns cuidados extras com a documenta&ccedil;&atilde;o dos <em>templates</em>, para que seja sempre poss&iacute;vel a um desenvolvedor adapt&aacute;-lo &agrave;s suas necessidades.</p>
    <p>Nossa primeira vis&atilde;o precisa pedir ao usu&aacute;rio que entre com seu nome e senha em duas caixas de texto. Tamb&eacute;m precisa oferecer a ele um bot&atilde;o que vai nos levar de volta para a aplica&ccedil;&atilde;o. Nossa segunda vis&atilde;o ser&aacute; utilizada apenas em caso de erros: caso o nome ou senha fornecidos pelo usu&aacute;rio n&atilde;o o identifiquem corretamente, precisamos informar isto a ele. Em caso de autentica&ccedil;&atilde;o positiva, vamos utilizar um redirecionamento HTTP (c&oacute;digo de resposta 302) para indicar ao <em>browser</em> do usu&aacute;rio para onde ir em seguida, e ao mesmo tempo transmitir a este programa as credenciais do usu&aacute;rio que ele conduz.</p>
    <p>Com algum esfor&ccedil;o de desenvolvimento, construimos a primeira vis&atilde;o, que vamos chamar de <code>ask-credentials.tmpl</code>. Ela se parece muito com isso:</p>

    <div class="display">
      <img align="center" valign="middle" src="images/login.gif" alt="quadro de login" border="0" />
    </div>
    
    <p>O c&oacute;digo fonte HTML utilizado para gerar isto &eacute; assim:</p>
    
    <pre class="code">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                          "http://www.w3.org/TR/html4/loose.dtd"&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;&lt;/title&gt;
    &lt;meta name="AUTHOR" content="Luis 'Champs' de Carvalho"&gt;
    &lt;style type="text/css"&gt;
      form { font-family: monospace;
             border: thin solid gray;
             position: absolute;
             top: 45%; left: 60%;
             padding-left: 5%;
             padding-right: 5%;
             background-color: lightyellow;
           }
      form p:first-child { font-weight: bold; }
      form p.submit { text-align: right; }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;form action="[% action %]" method="POST" enctype="application/x-www-form-urlencoded"&gt;
      &lt;p&gt;Entrada do Sistema&lt;/p&gt;
      &lt;p&gt;Login:
        &lt;input type="text" name="login" size="16" tabindex="1" align="middle"&gt;
      &lt;/p&gt;
      
      &lt;p&gt;Senha:
         &lt;input type="password" name="passwd" size="16" tabindex="2" align="middle"&gt;
      &lt;/p&gt;
      &lt;p class="submit"&gt;&lt;input type="submit" name="mode" value="Login" tabindex="3"&gt;&lt;/p&gt;
    &lt;/form&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
  
    <p>Preste aten&ccedil;&atilde;o a alguns pequenos detalhes: os nomes dos campos que estamos utilizando s&atilde;o importantes. Vamos conferir: o campo onde o usu&aacute;rio escrever&aacute; seu <em>login</em> chama-se <code>login</code>; o campo onde escrever&aacute; sua senha &eacute; especial (do tipo <code>password</code>, e chama-se <code>passwd</code>; e finalmente, o bot&atilde;o de envio chama-se <code>mode</code>. Isto &eacute; muito importante, pois &eacute; atrav&eacute;s deste campo que a aplica&ccedil;&atilde;o determinar&aacute; qual deve ser o pr&oacute;ximo passo.</p>
    <p>Note tamb&eacute;m que preenchemos o atributo <code>action</code> do <em>tag</em> <code>form</code> com uma esp&eacute;cie de <em>tag</em> especial. Isto &eacute; um comando para o Template Toolkit. Vamos voltar a estes detalhes em breve. Por enquanto, basta prestar aten&ccedil;&atilde;o nisso.</p>
    
    <p>Precisamos ainda de mais uma vis&atilde;o, para informar o usu&aacute;rio que ele n&atilde;o possui credenciais v&aacute;lidas. Ele deve ser assim:</p>
    
    <pre class="code">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
&lt;html&gt;
&lt;!-- $Id$ --&gt;
&lt;head&gt;
  &lt;title&gt;Erro na Autentica&ccedil;&atilde;o!&lt;/title&gt;
  &lt;meta name="AUTHOR" content="Luis 'Champs' de Carvalho"&gt;
  &lt;style type="text/css"&gt;
    p.error { border: thin solid black;
              background-color: red;
              font-weight: bold;
              text-align: center;
              position: absolute;
              left: 35%;
              top: 35%;
            }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;p class="error"&gt;[% error_message %]&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

    <p>Note que voltamos a utilizar um daqueles comandos especiais para o Template Toolkit. Vamos falar sobre isso em alguns instantes. O importante agora &eacute; que isso liq&uuml;ida com o assunto das vis&otilde;es, e nos permite come&ccedil;ar a explicar como deve ser constru&iacute;o o n&uacute;cleo da aplica&ccedil;&atilde;o.</p>

  </div>
  
  <div class="paragraph">
    <p>Introdu&ccedil;&atilde;o ao conceito de Stash</p>
    <p><b>Stash</b> &eacute; simplesmente um conceito. &Eacute; um reposit&oacute;rio de dados semi-p&uacute;blico, que utilizamos para acumular informa&ccedil;&otilde;es sobre a requisi&ccedil;&atilde;o que estamos processando. Eu digo semi=p&uacute;blico por que n&atilde;o podemos acessar o stash de uma requisi&ccedil;&atilde;o exceto se estivermos processando esta requisi&ccedil;&atilde;o.</p>
    <p>Vamos implementar nosso stash com um <i>design pattern</i> chamado <a href="">Singleton</a>, que no nosso caso servir&aacute; para garantir que todas as refer&ecirc;ncias para o stash sejam processadas pelo mesmo stash, dentro de uma determinada requisi&ccedil;&atilde;o.</p>
    <p>Nosso m&eacute;todo stash() &eacute; implementado automaticamente pela biblioteca <a href="">Class::Accessor</a>, que cria automaticamente m&eacute;todos de acesso a estruturas de dados auxiliares, com declara&ccedil;&otilde;es simples como "<code>__PACKAGE__->mk_accessors( qw[ stash ] );</code>".</p>
  </div>
      
  <div class="paragraph">
    <p>Introdu&ccedil;&atilde;o ao Class::Accessor</p>
  </div>
  
  <div class="paragraph">
    <p>Introdu&ccedil;&atilde;o ao AppConfig</p>
  </div>
  
  <div class="paragraph">
    <p>Introdu&ccedil;&atilde;o ao Template Toolkit</p>
  </div>

  <div class="paragraph">
    <p>Introdu&ccedil;&atilde;o ao CGI::Application</p>
  </div>
    
  <div class="paragraph">
    <p>Implementa&ccedil;&atilde;o do Controlador com CGI::Application</p>
  </div>

  </body>
</html>