Você está na página 1de 288

O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

O Livro
do Zope
Aviso: Esta é a visão de impressão com todas as páginas do Manual de Referência em uma página. A
versão paginada está disponível aqui, se você preferir esta.

Tradução do livro "The Zope Book"

1. Prefácio
Seção introdutória do livro

Bem-Vindo ao Livro do Zope. Este livro foi desenvolvido para introduzir você ao Zope e suas aplicações.
Zope é um servidor de aplicações para a web de código aberto. Se você está interessado em fazer páginas
para a web, programar web scripts, usar banco de dados, gerenciar conteúdo, ou fazer uma tarefa de
desenvolvimento colaborativo para a web, então você deve ler este livro.

Por que Eu Devo Ler este Livro?


Este livro é direcionado a ambos os tipos de usuários, os que já utilizam o Zope e os que que irão utilizar
o Zope:

Você não precisa ser um programador para ler este livro, ou para usar o Zope.
Você deve ter alguma idéia de como a web funciona; incuindo uma noção básica de HTML e
URLs.
Você deve saber o que são um web browser e um servidor web e deve ter alguma idéia de como
eles se comunicam.

A primeira parte do livro explica como você usa o Zope através de sua interface web de gerenciamento
para administrar conteúdos dinâmicos. Os conceitos nestes capítulos são conceitos fundamentais do
Zope que mostram a você como usar o Zope para publicar conteúdos na web.

Algumas seções adiante do livro abrangem tópicos avançados tais como Banco de Dados Relacionais,
scripts com várias linguagens de programação, e XML. Estes capítulos não ensinam sobre Banco de
Dados Relacionais, programação, ou XML, eles simplesmente mostram a você como usar estas
tecnologias com o Zope.

2. Introduzindo o Zope
Este capítulo explica o que o Zope é. Descreve de maneira geral o que você pode fazer
com o Zope. Você também aprende sobre as diferenças entre Zope e outros servidores de
aplicação web.
O que é Zope?
Zope é um framework para construir aplicações web. Uma aplicação web é um programa de computador
que os usuários acessam com um web browser na Internet. Você também pode pensar em uma
aplicação web como um web site dinâmico que oferece não somente informações estáticas para os

1 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

usuários mas os deixa usar ferramentas dinâmicas para trabalhar com uma aplicação.

Aplicações web estão em todo lugar, e os usuários da web trabalham com elas a todo momento.
Exemplos comuns de aplicações web são sites que deixam você fazer buscas pela web, como Yahoo,
colaborar em projetos, como SourceForge, ou se comunicar com outras pessoas através de e-mail, como
HotMail. Todos esses tipos de aplicações podem ser desenvolvidos com Zope.

Então o que você obtem quando baixa o Zope? Você na verdade adquire muitas coisas. Zope consiste de
vários componentes diferentes que trabalham juntos para ajudar você a construir aplicações para web.
O Zope vem com:

Um servidor web

O Zope vem com um servidor embutido que envia conteúdo a você e seus usuários. Claro que você já
deve ter um servidor web, como Apache ou Microsoft IIS e você pode não querer usar o Zope. Não se
preocupe, o Zope trabalha com estes servidores web também, e com qualquer outro servidor web que
suporte o Common Gateway Interface (CGI).

Uma Interface baseada na Web

Quando você constrói aplicações para a web com o Zope, você usa seu web browser para interagir com a
interface de gerenciamento do Zope (management interface). Esta interface é um ambiente de
desenvolvimento que o deixa fazer coisas como criar páginas para a web, adicionar imagens e
documentos, conectar-se a banco de dados relacionais externos e escrever scripts em diferentes
linguagens.

Um banco de dados objeto

Quando você trabalha com o Zope, você está, na maioria das vezes, trabalhando com objetos que são
armazenados no banco de dados objeto do Zope. A interface de gerenciamento do Zope oferece um
modo simples, familiar para administrar objetos que se assemelha a maneira que muitos gerenciadores
de arquivos trabalham.

Integração Relacional

Você não precisa armazenar suas informações no banco de dados objeto do Zope se você não quiser,
porque o Zope trabalha com outros bancos de dados relacionais como Oracle, PostgreSQL, Sybase,
MySQL e muitos outros.

Suporte a linguagem script

Zope lhe permite escrever aplicações web em várias linguagens diferentes, como Python, Perl, e a
própria Document Template Markup Language (DTML - Linguagem de Marcação para Modelos de
Documentos).

Estas são algumas das características que fizeram o Zope tão popular para desenvolver aplicações para
web. Talvez a melhor de todas as características do Zope seja que ele é amigável e que sua licença é open
source. Isto não significa somente que o Zope não tem custos para ser baixado, mas que ele também é
gratuito para você usá-lo em seus próprios produtos e aplicações sem pagar royalties ou taxas de uso. A
licença open source do Zope também significa que todo o "código fonte" do Zope está disponível para
olhar, entender, e estender. O Zope não deixa você restrito a uma solução proprietária que quer fazer de
você e de seu usuário reféns.

De um ponto de vista técnico, há três idéias chaves para entender o que o Zope pode fazer para você:
colaboração poderosa, administração simples de conteúdo, e componentes para web. As seções

2 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

seguintes são principalmente orientadas para pessoas que tomam decisões sobre Zope, assim se você
estiver interessado em utilizá-lo, vá para o próximo capítulo, Usando Zope.

Colaboração Poderosa
Anos atrás, as principais tecnologias do Zope eram desenvolvidas pela Zope Corporation para um
Provedor de Serviços para a Internet que fornecia páginas para web para jornais. Estes jornais, por sua
vez, queriam oferecer páginas web para seus clientes. Para se adaptar a esse ambiente, o Zope foi
projetado para delegar controle seguro para diferentes tipos de usuários em qualquer nível dentro do
web site. Delegar controle seguro significa levar em consideração essas coisas:

1. Apresentar informação de uma maneira fácil de entender. A maioria das pessoas entendem
melhor quando clicam em folders do que quando editando comandos para banco de dados,
sendo assim o Zope utiliza uma interface que se assemelha a um simples administrador de
arquivos, como Microsoft Windows Explorer e outros administradores de arquivos populares.
2. Ferramentas com linhas de comando podem ser difíceis de usar e as pessoas geralmente ficam
mais confortáveis usando web browsers, sendo assim o Zope foi projetado para ser usado quase
exclusivamente através de um web browser.
3. Ambientes colaborativos exigem ferramentas para permitir que os usuários desfaçam seus erros
e trabalhem sem interferir em outro trabalho, assim o Zope tem Undo (desfazer), Versions
(Versões), e outras ferramentas que ajudam as pessoas a trabalhar juntas e com segurança.

Essas características fazem do Zope um ambiente ideal de programação e apresentação de conteúdos


para web por grupos e subgrupos de usuários.

Gerenciamento Simples de Conteúdo


Muitas aplicações para web são tradicionalmente construídas em três camadas. Dados e outras
informações são armazenados em bancos de dados, os programas que conduzem o comportamento da
aplicação são armazenados dentro de arquivos em um local, e o HTML e o layout e informação de
apresentação são armazenados em outro lugar.

Ao mesmo tempo que isso tem vantagens, tem também desvantagens. Diferentes tipos de ferramentas e
especialidades devem ser usadas para trabalhar com os diferentes componentes. Todos os
componentes diferentes podem precisar de seus próprios tipos de segurança e preocupação com a
manutenção. Muitos desses tipos de ferramentas não são gerenciáveis de um web browser ou de uma
simples linha de comando ou ferramentas GUI como FTP.

No Zope, todos esses componentes são trazidos juntamente com um sistema coerente. Todos requerem
um conjunto comum de serviços: segurança, administração baseada na web, busca, escalabilidade,
organização e outros. Com todos esses conceitos juntos em um sistema gerenciável, o Zope faz com que
você use um conjunto de conhecimentos e um conjunto de ferramentas para desenvolver aplicações
complexas para a web. Além disso, centralizar nosso modelo significa dizer que o Zope pode trabalhar
mais facilmente com outras ferramentas externas, como banco de dados relacionais, editores web GUI,
e outros sistemas que podem operar conjuntamente com o Zope.

Componentes Web
A Web é uma plataforma dinâmica em crescimento. A web desenvolveu padrões e APIs suficientes que
criadores de serviços, produtos e tecnologias podem pensar na web em termos de um modelo
arquitetônico para desenvolver suas aplicações em todos os lugares, ao invés de somente um meio de
distribuir documentos HTML estáticos para usuários.

3 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

A prova disso está surgindo em muitos lugares. A arquitetura .NET da Microsoft prevê um mundo de
componentes para a web executando em sistemas remotos, oferencendo serviços específicos para
aplicações em todo o mundo. Frontier, da UserLand Software, foi o precursor de um simples protocolo
de serviços para a web chamado XML-RPC que permite que os componentes da web se comuniquem
entre si (o Zope também trabalha com XML-RPC, que é discutido no Capítulo 10, "Scripts Avançados em
Zope"). Com os componentes da web, o modelo de uma pessoa sentada em frente do browser não será
mais o único modelo da web.

História do Zope
Em 1996, Jim Fulton, o CTO da Zope Corporation e guru do Python, foi designado para dar uma aula de
programação em CGI, apesar de não saber muito sobre o assunto. Jim estudou toda a documentação
existente de CGI durante a viagem para dar aula. No final da aula, Jim observou que não tinha gostado
dos tradicionais ambientes de programação baseado em CGI: sua fragilidade, falta de orientação a
objetos, e como expunha detalhes do sevidor web. A partir destas reflexões, a parte central do Zope foi
escrita no vôo de volta da aula.

A Zope Corporation lançou três pacotes de software open source para suportar publicações para a web,
Bobo, Document Template, e BoboPOS. Estes pacotes foram escritos em Python. Eles evoluiram para os
principais componentes do Zope oferecendo o web ORB (Object Request Broker), linguagem script
DTML, e banco de dados objeto. O Zope é ainda principalmente escrito em Python com poucas seções
de preformance crítica em C.

Até então, a Zope Corporation tinha desenvolvido um servidor de aplicação comercial baseado em seus
três componentes open source. Este produto foi chamado Principia. Em novembro de 1998, o
investidor Hadar Pedhazur convenceu a Zope Corporation a abrir o código fonte do Principia. Se tornou
Zope, que tem sua própria página em Zope.org (em inglês).

Quem Pode se Beneficiar com o Zope?


O Zope faz com que muitas pessoas trabalhem juntas para criar serviços para a web. Administrar e
coordenar estas pessoas em sites grandes pode ser uma tarefa difícil. Identificamos alguns papéis
comuns neste cenário:

Consumidores: usam o site para localizar e trabalhar com conteúdo útil.


Usuários de Aplicação: criam e administram o conteúdo do site.
Projetistas do Site: criam a cara do site.
Desenvolvedores do Site: planejam os serviços do site.
Desenvolvedores do Conteúdo: criam softwares para distribuição.
Administradores: mantêm o software e o ambiente rodando.
Arquitetos de Informação: tomam decisões sobre plataformas e cuidam da visão a longo prazo.

O Zope é uma plataforma na qual os Desenvolvedores de Site criam serviços para Projetistas do Site e
Usuários Profissionais, e os Desenvolvedores de Componentes distribuem pelo mundo novos produtos
e serviços para os usuários do Zope.

O Zope pode instalar produtos para públicos diferentes. Por exemplo, Squishdot é um sistema para
sites noticiosos interativos, é escrito em Zope, e inspirado no Slashdot.org, e vem pronto para usar. Os
usuários do Squishdot não vão necessariamente ver que o Zope está disfarçado. Outros produtos do
Zope, tais como o Framework de Administração de Conteúdo da Zope Corporation, levam à mesma
conclusão, observando que os usuários não necessitam saber da existência do Zope disfarçado.

4 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Como Você Pode se Beneficiar com o Zope?


Observamos a filosofia e a arquitetura do Zope, agora vamos analisar algumas das aplicações do Zope.
Todos os sites resolvem problemas diferentes, mas muitos sites cuidam de um conjunto de fluxos
comuns diários. Aqui estão alguns dos principais usos do Zope:

Apresentar Conteúdo Dinâmico

Você quer juntar a apresentação do web site para seus usuários, integrar informação em banco de dados
e oferecer pesquisa a seus usuários. Você também quer deixar seu web site automatizado e facilitar os
processos. O seu site pode reagir inteligentemente a visitantes para oferecer uma experiência
convincente? O Zope permite que você desenvolva páginas dinâmicas. Vem com facilidades para
personalização, integrando informação em banco de dados e busca.

Para Administrar seu Web Site

Um pequeno web site é fácil de administrar, mas um web site que serve milhares de documentos,
imagens, e arquivos necessita oferecer ferramentas poderosas de gerenciamento. Você pode
administrar os dados do site, lógica de aplicação e de apresentação tudo em um lugar? Você pode
administrar seu conteúdo, ou ele está saindo do seu controle? O Zope oferece a você ferramentas
simples e poderosas para gerenciar gigabytes de conteúdos da web. Você pode administrar sua lógica,
apresentação e dados de seu web browser.

Oferecer segurança para seu Web Site

Quando você lida com muitos usuários na web, a segurança se torna muito importante. É crucial
organizar usuários e ser capaz de delegar tarefas com segurança para eles. Por exemplo, as pessoas em
seu departamento de engenharia precisam ser capazes de administrar suas páginas e lógica de
aplicação, designers podem precisar atualizar os templates do site, e administradores de banco de
dados precisam administrar as consultas ao banco de dados. O seu sistema pode controlar milhares de
usuários, talvez associados a seu LDAP existente ou a outro banco de dados do usuário com regras
flexíveis de segurança? O Zope lhe permite adaptar seu site para milhares de gerenciadores de site e
milhões de visitantes. Você pode simplesmente controlar as políticas de segurança e delegar controle
seguro a outros.

Oferecer Serviços de Rede

Atualmente a maioria dos web sites servem usuários, mas em breve web sites precisarão servir
programas para computadores remotos e outros web sites. Por exemplo , você gostaria de deixar os
itens de suas notícias automaticamente disponíveis para ligar serviços de web sites. Ou talvez você
queira fazer produtos para vender em seu site automaticamente sendo procurado de um site de
comparação de produto. Você pode lançar seus dados existentes e lógica de aplicação para criar serviços
de rede ou você terá que recomeçar do nada? O suporte embutido do Zope faz de cada site do Zope um
serviço de rede. Sua lógica de aplicação e dados podem ser acessados pela web via HTTP e XML-RPC.

Integrar Conteúdo Diverso

Seu conteúdo está espalhado em todo lugar, em bancos de dados relacionais, arquivos, web sites,
arquivos FTP, XML. Você pode unificar dados dentro de uma aplicação coerente? Seu sistema suporta
padrões web de maneira que você possa integrar conteúdos de sistemas legados e novos sistemas que
você vai adicionar no futuro? O Zope suporta padrões web permitindo que você use seus dados
existentes, infraestrutura e sistemas de arquivos.

Prover Escalabilidade

5 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Então você percebeu que o Zope é rico e agora está obtendo mais êxito que você tinha imaginado. Agora
você precisa controlar um nível de tráfico dramaticamente maior que antes. Você pode mover seu site
para um banco de dados e uma plataforma de servidor diferente e distribuir a carga por servidores
múltiplos? O seu web site pode acompanhar seu sucesso? O Zope permite que suas aplicações para a
web se adaptem a várias máquinas caso necessário para controlar sua carga. O Zope torna isso possível
mantendo um pequeno site que pode se tornar de um dia para o outro um grande site baseado em sua
tecnologia "ZEO" (veja o Capítulo 11 para maiores detalhes).

O que o Zope Concede a Você


Vamos dar uma olhada mais detalhada nas características do Zope que permitem que você construa e
administre sites para a web dinâmicos.

Ambiente de Administração Único

A primeira coisa que você notará sobre o Zope é que ele deixa você administrar os dados, a lógica e a
apresentação do seu site pelo seu web browser. Isto significa que o Zope é fácil de usar e é remotamente
administrável. O Zope deixa você colaborar com outros para interativamente desenvolver seu web site.

Ferramentas Embutidas

O Zope vem com ferramentas de gerenciamento de site, um servidor web, um mecanismo de busca,
conectividade com banco de dados, segurança e serviços de colaboração, e mais. Além disso, o Zope
oferece a você tudo o que você precisa para construir um poderoso web site.

Suporte a Padrões Aberto

O Zope sobressai-se por juntar diversos dados por causa de seu suporte a padrões abertos. O Zope
suporta padrões de Internet inclusive SQL, ODBC, XML, DOM, FTP, HTTP, FastCGI, XML−RPC, SOAP,
e muito mais.

Licensa de Fonte Aberto

Com o Zope você não apenas adquire uma aplicação, você adquire o fonte e uma comunidade.
Considerando que o Zope é open source você não vai ser refém de um simples vendedor; mas você será
livre para usar, distribuir e adaptar o Zope às suas necessidades. Zope também se beneficia de usuários
ativos e da comunidade de fomentadores. A comunidade melhora o suporte do Zope, examina a
segurança do mesmo, concerta bugs, e adiciona características.

Extensibilidade

O Zope pode ser estendido em muitas direções. Aplicações externas podem ser criadas facilmente e
distribuídas. A comunidade do Zope já produziu centenas de postagens de discussão na web.

Alternativas do Zope
Há muitas ferramentas disponíveis para ajudar você a construir aplicações para a web. Nos primórdios
da história da web, aplicações simples para a web eram construídas quase exclusivamente com
programas CGI escritos em Perl ou outras linguagens. Agora há muitas opções abrangendo open source
frameworks como PHP, opções comerciais tais como Cold Fusion da Allaire, servidores de aplicação
para Java, e Story Server da Vignette.

O Zope oferece uma mistura única de características, algumas parecidas, e outras diferentes das
características oferecidas por outras ferramentas de aplicação para a web. O Zope é muito fácil de usar,

6 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

é open source, poderoso, e oferece suporte para muitos tipos de aplicações. Aqui está uma pequena lista
de defeitos comuns em ferramentas para a web e as vantagens do Zope:

Algumas ferramentas não oferecem um administrador de arquivo simples como interface de


usuário, e são difíceis de usar. O Zope tem uma interface de usuário simples.
Algumas ferramentas requerem configuração complexa. O Zope é fácil de instalar e não requer
nenhuma configuração antes de você começar a usá-lo.
Algumas ferramentas requerem o uso de ferramentas pouco familiares e proprietárias. O Zope
trabalha com qualquer web browser padrão e nenhuma outra ferramenta será requerida para
usar este livro.
Algumas ferramentas não se adaptam tão bem quanto o Zope para controlar um número grande
de desenvolvedores e usuários. O Zope tem um sistema de gerenciamento consistente e
poderoso que pode se adaptar a muitos usuários com privilégios únicos e facilmente
gerenciados.
Concluindo, a maioria das ferramentas comerciais, fontes fechados não deixam você estendê-las,
personalizá-las e redistribuí-las. O Zope é open source.

Comunidade do Zope
O Zope foi uma das primeiras ferramentas deste tipo a se tornar open source. Desde que abriram o
código fonte do Zope, a quantidade de usuários vem crescendo muito.

A comunidade do Zope consiste de usuários do Zope e desenvolvedores. Muitos dos membros da


comunidade são profissionais tais como consultores, desenvolvedores e web masters, que investem seu
tempo e dinheiro em apoiar o Zope. Outros são estudantes e hackers curiosos, estão aprendendo como
usar uma ferramenta nova e legal. A comunidade está junto ocasionalmente em conferências, mas gasta
a maior parte de seu tempo discutindo o Zope em muitas listas de Zope e web sites. Você pode achar
mais sobre as listas de Zope em http://www.zope.org/Resources/MailingLists.

Agora que você já aprendeu sobre as características do Zope e sua história, é hora de começar a usá-lo.
No próximo capítulo você aprenderá como adquiri-lo e rodá-lo. Considerando que o Zope é gratuito,
você pode fazer o download da última versão, e começar a trabalhar imediatamente.

3. Usando o Zope
Este capítulo vai ajudar você a entender e a rodar o zope. Ele vai orientar você a instalar
e executar o Zope. Este capítulo contém os mais importantes conceitos sobre o Zope. Até
o final deste capítulo você será capaz de usar o Zope para criar e administrar simples
mas poderosas aplicações para a web.
Baixando o Zope
Os primeiros passos para usar o Zope são fazer o download e instalá-lo. O Zope está disponível
gratuitamente no site Zope.org A versão mais recente está disponível na seção Download do Zope. org.

Atualmente o Zope está disponível como um binário para Windows, Linux e Solaris. Isto significa que
você pode fazer o dowload e instalá-lo sem a necessidade de compilar qualquer programa. Para outras
plataformas você deve fazer o download do código e compilar o Zope. O Zope pode ser compilado e
rodar na maioria dos sistemas operacionais baseados no Unix. Como regra geral de uso, se Python está
disponível pelo seu sistema operacional, e você tem um compilador C, então você provavelmente pode
usar o Zope.

7 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Instalando Zope
Você instalará o Zope de diferentes maneiras dependendo da sua plataforma. Se você está rodando uma
versão mais recente do Linux, você talvez já tenha o Zope instalado. Você pode obter o Zope em ambas
as formas binária e código fonte. Existem também vários formatos binários diferentes disponíveis.

Instalando Zope para Windows

Zope para Windows vem como um arquivo de instalação própria .exe. Para instalar o Zope, dê um clique
duplo no instalador. O instalador encaminhará você para o processo de instalação. Escolha o nome para
a sua instalação do Zope e um diretório para instalá-lo. Clique em Next (próximo)e crie uma nova conta
de usuário no Zope. Esta conta será chamada de usuário inicial (initial User). Isto cria uma conta que
você pode usar para se logar no Zope pela primeira vez. Você pode mudar este nome de usuário e a
senha depois se você desejar.

Se você usa o Windows NT ou Windows 2000, você pode escolher rodar o Zope como um serviço. Rodar
o Zope com um serviço é uma boa opção para um servidor público. Se você está rodando o Zope
somente para uso pessoal não perca tempo executando o Zope como um serviço. Tenha em mente que
se você está rodando Windows 95, Windows 98 ou Windows ME (Millenium Edition), você não pode
executar o Zope como um serviço.

Se você decidir desinstalar o Zope mais tarde você pode usar o programa Unwise.exe que está no
diretório do Zope.

Baixando os Binários do Linux e Solaris

Baixar o binário para a sua plataforma e extrair o tarball:

$ tar xvfz Zope-2.4.0-linux2-x86.tgz

Neste exemplo, você está baixando a versão 2.4.0. Esta pode não ser a versão mais recente do Zope no
momento em que estiver lendo isto, assim certifique-se e obtenha a versão mais recente e estável do
Zope para a sua plataforma.

Isto irá desempacotar o Zope dentro de um novo diretório. Entre no diretório do Zope e execute o script
de intalação do Zope:

$ cd Zope-2.4.0-linux2-x86
$ ./install

O instalador vai imprimir informações enquanto instala o Zope. Entre outras coisas, ele vai criar uma
conta de usuário inicial. Você pode mudar o nome do usuário inicial e a senha depois com o script
zpasswd.py (veja o Capítulo 6).

O instalador irá configurar o Zope para executar como seu userid (identificação de Usuário) do UNIX.
Se você preferir rodar o Zope com outro userid, você pode usar a linha de comando -u que irá trocar e
especificar o usuário que você quer configurar o Zope para executá-lo. Existem muitos livros com mais
informações sobre userids e administração de Unix em geral você deve verificar se você quer fazer algo
especial. No momento as coisas irão correr bem se você simplesmente instalar o Zope para rodar como
seu userid não especificando outras opções extras de linhas de comandos.

Para maiores informações sobre a instalação do Zope veja as instruções de instalação que estão no

8 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

doc/INSTALL.txt e procure mais sobre o script instalador ativando a ajuda com o comando -h:

$ ./install -h

Obtendo Zope no Formato RPM e deb

A Digital Creations não disponibilizou o Zope no formato RPM, mas outras pessoas o fizeram. Jeff Rush
regularmente disponibiliza pacotes RPMs do Zope. Para maiores informações verifique sua página (
http://starship.python.net/crew/jrush/Zope/). O Zope também está disponível no formato do pacote
deb do Debian Linux. Você pode encontrar os pacotes deb do Zope no site do Debian. Geralmente as
últimas liberações do Zope são distribuídas de maneira instável.

Compilando o Zope pelo Código Fonte

Se os binários não estiverem disponíveis para a sua plataforma, então você pode compilar o zope a
partir do código fonte. Para fazer isto instale o Python através dos fontes para a sua plataforma e
certifique-se de ter o compilador C. Você pode conseguir o Phyton no site Python.org. Embora nós
tentemos usar a versão mais recente do Python para Zope, talvez já exista uma última versão do Python
ainda mais recente do que a versão que nós usamos "oficialmente" para o Zope. Para informações sobre
qual a versão do Python você precisa compilar para o Zope, veja as observações que estão na página
para cada versão. Zope 2.4 requer Python 2.1. Zope 2.3 e versões mais recentes usam o Python 1.5.2.

Faça o download da distribuição do código fonte do Zope e extraia o tarball:

$ tar xvfz Zope-2.4.0-src.tgz

Isto desempacota o Zope em um novo diretório. Entre no diretório do Zope e execute o script
instalador:

$ cd Zope-2.4.0-src
$ python wo_pcgi.py

O instalador compila o Zope e configura sua instalação. O instalador imprime informações quando está
executando, inclusive o nome do usuário inicial e a senha. É importante anotar esta informação pois
somente com ela você poderá logar no Zope. Para maiores informações veja as instruções de instalação
que estão no arquivo doc/install.txt. Você pode mudar mais tarde a conta de usuário inicial com o script
zpasswd.py (veja o Capítulo 7).

Iniciando o Zope
Dependendo da sua plataforma, você pode executar o Zope com diferentes comandos. Qualquer que
seja sua plataforma, você pode executar o Zope tanto manual como automaticamente. Quando o Zope é
executado manualmente, você simplesmente diz ao Zope quando iniciar e quando parar. Quando o Zope
é executado automaticamente, o Zope irá iniciar e parar quando seu computador iniciar e desligar.

Iniciando o Zope no Windows

O instalador cria um diretório do Zope com um arquivo de lote chamado start.bat. Dê um clique duplo
no ícone start.bat. Isto abrirá uma janela com informações sobre login. Nesta janela você descobrirá
qual a porta que o Zope está executando. Você pode se logar no Zope com o web browser.

9 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Se você estiver rodando o Zope como um serviço, você pode iniciar e fechar o Zope através dos Serviços
do painel de controle. O Zope escreverá eventos para o evento de log assim você pode saber quando o
seu serviço começa e quando termina. Se você rodar o Zope como um serviço você deve saber em qual
porta o Zope está rodando, considerando que você não terá acesso direto aos detalhes de informação do
login.

Zope vem com seu próprio sevidor web. Quando você inicia o Zope, inicia seu servidor web. Se você
desejar você pode conectar o Zope a um servidor web existente como IIS, isto não faz parte do enfoque
deste livro. O Guia de Administrador do Zope contém este tipo de material.

Iniciando o Zope no Unix

Excute a operação start:

$. /start &

O Zope começará a rodar e imprimirá informações sobre o login para o console. Você deve ver
informações sobre qual a porta de acesso do Zope. Você pode agora se logar no Zope a partir do
browser.

O Zope vem com o seu próprio servidor web. Quando o Zope é inicado, seu servidor web inicia. Se você
quiser você pode conectar o Zope com seu servidor web já existente como o Apache, mas este assunto
não faz parte do enfoque deste livro. O Guia de Administrador do Zope contém este tipo de material.

O comando start pode também ser editado para iniciar o Zope com diferentes opções. Como
personalizar o startup do seu Zope, também está descrito no Guia do Administrador.

Entrando no Zope
Para entrar no Zope você precisa de um browser. A interface do Zope é escrita inteiramente em HTML,
sendo assim o Zope funciona com qualquer browser que entenda os códigos HTML atuais . Mozilla, e
qualquer versão do Microsoft Internet Explorer ou Netscape Navigator superior a versão 3.0.

Para entrar na interface de administrador, aponte seu browser para a URL de administrador do Zope. A
URL de administrador é a mesma URL, colocando junto /manage. Supondo que você tenha instalado o
Zope em sua máquina local, rodando na porta padrão 8080, a URL de administrador é:

http://localhost:8080/manage

Esta URL geralmente funciona, mas você pode precisar logar em uma máquina diferente da que nós
mostramos aqui. Para descobrir exatamente qual URL deve ser usada, observe as informações de login
do Zope que aparecem no início. Por exemplo:

10 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

------
2000-08-07T23:00:53 INFO(0) ZServer Medusa (V1.18) started at Mon Aug 7 16:00:53 2000
Hostname: peanut
Port:8080

------
2000-08-07T23:00:53 INFO(0) ZServer FTP server started at Mon Aug 7 16:00:53 2000
Authorizer:None
Hostname: peanut
Port: 8021
------
2000-08-07T23:00:53 INFO(0) ZServer Monitor Server (V1.9) started on port 8099

A primeira entrada mostra que o Zope está rodando em uma máquina chamada peanut e que o servidor
web está rodando na porta 8080. Isto significa que a URL de administrador é http://peanut:8080
/manage. Mais tarde no livro veremos outros servidores referenciados nas informações de login.

Depois que você entrar com a URL de administrador no seu browser, seu browser fará você logar no
Zope através do nome do usuário e senha. Digite o nome do usuário inicial e a senha criadas durante o
processo de instalação. Se você não souber o nome do usuário inicial e a senha, então pare o Zope
fechando esta janela e mude o usuário inicial e a senha com o comando zpasswd.py e reinicie o Zope.
Veja o Capítulo 7, "Usuários e Segurança", para maiores informações sobre configuração de conta de
usuário inicial.

Controlando o Zope com a Interface de Gerenciamento


Após ter conseguido entrar no Zope você vai ver uma página web da Interface de Gerenciamento do
Zope, como mostra a Figura 2.1.

Figura 2.1 - Interface de Gerenciamento do Zope.

A interface de gerenciamento do Zope permite que você controle o Zope a partir do seu browser.

Usando o Navegador
A interface de Gerenciamento do Zope está separada em três quadros (frames). Com o frame da

11 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

esquerda você navega no Zope Como se você estivesse navegando através de um sistema de arquivos
com um gerenciador de arquivo como o Windows Explorer. Este frame é chamado de Navegador, e é
mostrado no frame da esquerda na Figura 2-1. Neste frame você consegue ver o diretório root (raíz) e
todos os seus subfolders (subpastas). O diretório raíz está no canto superior esquerdo da árvore. O
diretório raíz é o "topo" do Zope. Tudo que estiver no Zope vai estar dentro do diretório raíz.

Algumas das pastas possuem o sinal de adição (+) a sua esquerda. Estas marcas indicam que você pode
expandir os folders (pastas) para ver os subfolders que estão dentro deles.

No frame acima da árvore de diretórios o Zope mostra informações de login em um frame. Nesta janela
você pode ver que você está logado como "manager" (administrador). Quando você se logar no Zope
você usará a conta de usuário inicial e você verá o nome desta conta no lugar do "manager".

Para gerenciar um folder, clique nele e ele aparecerá no frame direito da janela do browser. Este frame é
chamado de workspace (área de trabalho).

Usando a Área de Trabalho


O frame direito da interface de gerenciamento mostra os objetos que você está gerenciando no
momento. Quando você entra pela primeira vez no Zope o objeto corrente é o diretório raíz, como
mostrado no frame direito da Figura 2.1. A área de trabalho mostra informações sobre o objeto corrente,
e deixa que você o mude.

No topo da tela existem várias abas. A aba que está selecionada no momento está em uma cor mais
clara. Cada aba leva a uma view (aba) diferente do objeto autal. Cada aba deixa que você execute uma
função diferente de gerenciamento naquele objeto.

Na Figura 2.1, você está olhando para a aba Contents (Conteúdos) do objeto da pasta da raíz.

No topo da área de trabalho, abaixo das abas, há uma descrição do tipo de objeto atual e a URL. Na
esquerda há um ícone representando o tipo do objeto atual, e à direita dele está a URL do objeto.

Na Figura 2.1 "Folder at /" mostra que o objeto atual é um folder e que sua URL é /. Observe que esta
URL é a URL relativa do objeto para a URL de base do Zope. Assim se a URL ou o seu site do Zope
fossem http://mysite.example.com:8080, então a URL do "Folder at /myFolder" seria
http://mysite.example.com:8080/myfolder.

Como você explora diferentes objetos do Zope, você pode notar que as URLs (como mostrado na tela de
gerenciamento), podem ser usadas para navegar entre os objetos.

Por exemplo, se você está administrando um folder em /Zoo/reptiles/snakes você pode retornar ao
folder em /Zoo dando um clique na palavra Zoo na URL do folder.

No frame no topo da interface de gerenciamento, é exibido seu login atual, junto com um menu de
seleção que permite a você selecionar:

Preferências

Aqui, você pode ajustar as preferências padrão para a sua seção do Zope, você pode até esconder o
frame do topo.

Logout

Selecinando este item do menu você será deslogado do Zope.

12 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Links Rápidos

Estes são links rápidos para recursos da comunidade e documentação do Zope.

Entendendo Usuários em Zope


O Zope é um sistema multi-usuário. Você já viu como você pode logar no Zope através da interface de
gerenciamento com o nome do usuário inicial e a senha. O Zope suporta outros tipos de usuários:

Emergence User (Usuário de Emergência)

O usuário de emergência é raramente usado no Zope. Esta conta é usada para criar outras contas de
usuários e consertar as coisas se você acidentalmente ficar impedido de acessar.

O usuário de emergência é ao mesmo tempo muito poderoso e muito fraco. Ele não é restringido pela
maioria dos controles de segurança. Porém, o usuário de emergência só pode criar um tipo de objeto:
Users (Usuários). O uso do Usuário de Emergência para consertar seu sistema no caso de acidentais
travamentos é discutido no Guia do Administrador.

Manager (Administrador)

O administrador é quem mais trabalha no Zope. Você precisa estar logado como administrador para
fazer a maioria do trabalho envolvido com a construção de páginas para a web. O usuário inicial é um
administrador, e você pode criar tantas contas de administrador quantas você precisar.

Others (Outros)

Você pode criar seus próprios tipos de usuários que se encaixam nos grupos, ou são responsáveis por
executar uma função (role) que você definiu. Isto será explicado no Capítulo 6 que trata da segurança e
usuário do Zope.

Criando Usuários
Administradores podem criar usuários no Zope em um único tipo de folder chamado User Folder (Pasta
de Usuários).

O ícone do user folder parece-se com os folders com a figura de uma pessoa neles. Os user folders
sempre têm o nome acl_users, como mostra Figura 2.1.

Clique no folder acl_users no diretório raíz para entrar nele. Folders de Usuários contêm objetos
Usuário. Você pode criar novos usuários e editar os existentes. Clique no botão Add para criar um novo
usuário, mostrado na Figura 2.2.

13 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 2.2 - Adicionando um novo usuário.

Preencha o formulário para criar um novo usuário. No campo Name coloque o nome do usuário
escolhido. Escolha uma senha e coloque-a nos campos Password e Confirm. Deixe o campo Domains
em branco. Esta é uma característica avançada e é discutida no Capítulo 7 "Usuários e Segurança".
Selecione o papel Manager da lista de seleção Roles. Então clique no botão Add.

Parabéns você acaba de criar uma conta de administrador. O Zope mostrará a você esta nova conta de
administrador dentro do user folder. Se desejar mais tarde você pode mudar ou deletar este usuário.

Mudando Logins
Para mudar o seu login selecione Logout no topo do frame da interface de gerenciamento. Você estará
pronto para logar novamente. Para mudar os logins, entre com o novo nome de usuário e senha.

Para sair da sessão selecione Logout no topo do frame da interface de gerenciamento e cancele o novo
login. Você deverá ver uma mensagem dizendo que você está deslogado. Se você tentar acessar a
interface de gerenciamento do Zope depois de ter saído, você terá que logar novamente. Você também
pode sair do Zope fechando o seu browser.

Criando Objetos
A interface de gerenciamento do Zope representa tudo em termos de objetos e folders. Quando você
constrói aplicações para a web com o Zope, você gasta a maioria do seu tempo criando e gerenciando
objetos nos folders. Por exemplo, para fazer uma nova conta de administrador você cria um objeto
usuário em um user folder.

Retorne ao diretório raíz clicando no topo do lado esquerdo no frame de Navegação.

Para adicionar um novo objeto ao folder corrente selecione um objeto do menu de seleção no frame a
direita chamado "Select type to add..." (Selecione o tipo a ser adicionado). Este menu é chamado de lista
de adição de produtos.

Por exemplo, para criar um folder, selecione Folder da lista de adição de produtos. Neste ponto, será
mostrado um formulário de adição que coleta informações sobre o novo folder, como mostra a Figura
2.3.

14 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 2.3 - Folder Adição de Formulário

Digite "zoo" no campo Id, e o "Zope Zoo" no campo título. Então clique no botão Add.

O Zope criará um novo folder no folder atual. Você pode verificar isto observando que há um novo folder
chamado zoo dentro do diretório raíz.

Clique no zoo para entrar nele. Observe que a URL do folder é baseada no ID do folder. Você pode criar
mais folders dentro do seu novo folder se você quiser. Por exemplo, crie um folder dentro do folder zoo
com um id arctic. Vá ao folder zoo e escolha Folder do menu de opções. Então digite "artic" no ID do
folder, e "Artic Exhibit" para o título. Agora clique no botão Add. Você sempre cria novos objetos da
mesma maneira.

1. Vá até o folder onde você quer adicionar um novo objeto.


2. Escolha o tipo de objeto que você quer adicionar do menu.
3. Preencha um formulário de adição e clique em Submit.
4. O Zope criará o novo objeto no folder atual.

Note que todo o objeto do Zope tem um id que você precisa especificar no formulário de adição, quando
você cria o objeto. O id é como o Zope chama os objetos. Os objetos também usam seus ids para suas
respectivas URLs.

O Capítulo 3, "Usando os Objetos Básicos do Zope", mostra todos os objetos básicos do Zope e o que
eles podem fazer por você.

Movendo Objetos
A maioria dos sistemas de computador deixa você mover arquivos de um diretório para outro com as
funções recortar, copiar e colar. A inteface de gerenciamento do Zope possui um sistema similar que
deixa você mover os objetos pelos folders recortando ou copiando-os, e então colando-os em um novo
lugar.

Para experimentar com a função recortar e colar, crie uma nova pasta no diretório raíz com um id bears.
Então selecione bears selecionando a check box na esquerda do folder. Então clique no botão Cut. O cut
remove os objetos selecionados da pasta e os armazena temporariamente na memória (clipboard). O
objeto não irá, no entanto, desaparecer da pasta de origem até que ele seja colado em outro lugar.

Agora entre na pasta zoo clicando nela, e então entre na pasta arctic clicando nela. Você também
poderia ter usado o navegador para chegar a este mesmo local. Agora, clique no botão Paste para colar
o(s) objeto(s) recortado(s) na pasta especificada. Você deve ver a pasta bears aparecer no novo local.
Você pode verificar que o folder foi removido indo ao diretório raíz e observando que a pasta bears não

15 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

está mais lá.

O Copy (copiar) funciona parecido com o recortar. Quando você cola objetos copiados, os objetos
originais não são mudados. Selecione o(s) objeto(s) que você quer copiar e clique no botão Copy. Então
navegue até a outra pasta e clique no botão Paste.

Você pode recortar e colar pastas que contenham outros objetos e mover muitos objetos ao mesmo
tempo com um único recortar e colar. Por exemplo, vá a pasta zoo e copie a pasta arctic. Agora cole-a
dentro da pasta zoo. Agora você terá duas pastas dentro da pasta zoo, arctic e copy of arctic. Se você
colar um objeto no mesmo folder que você o copiou, o Zope mudará o id do objeto colado. Este é um
passo necessário, pois você não pode ter dois objetos com o mesmo id no mesmo folder.

Para renomear a pasta copy of arctic, selecione a pasta checando a check box na esquerda desta pasta.
Então clique no botão Rename. Isto mostrará um formulário de renomeação como mostra a Figura 2.4.

Figura 2.4 - Renomeando um Objeto

Digite um novo id "mountains" e clique em OK. Os ids do Zope podem ter letras, números, espaços,
separações com sublinhas (underscores) e pontos, e são sensíveis ao contexto (case-sensitive). Aqui
estão alguns ids válidos do Zope: index.html, 42, Snake-Pit

Agora sua pasta zoo contém as pastas arctic e mountains. Cada uma delas contém uma pasta bears.
Isto é porque quando fizemos uma cópia da pasta arctic também foi copiada a pasta bears que está
contida nela.

Se você quiser deletar um objeto, selecione-o e então clique no botão Delete. Diferente de objetos
cortados, os objetos deletados não são postos temporariamente na memória e não podem ser colados.
Na próxima sessão veremos como podemos recuperar objetos deletados.

O Zope não permite que você recorte, delete, ou renomeie alguns objetos particulares do diretório raíz.
Estes objetos incluem Control_Panel, standard_html_header, standard_html_footer, e
standard_error_message. Estes importantes objetos são necessários para operações do Zope.
Também, estas operações não funcionarão em algumas situações. Por exemplo, você não pode colar um
objeto usuário em um folder comum.

Se você está tendo problemas com a cópia e colagem, certifique-se de que você tenha ativado os cookies
no seu browser.O Zope usa os cookies para manter um rastro dos objetos que você cortou e copiou.

Desfazendo Erros
Qualquer ação no Zope que cause mudança no objeto pode ser desfeita, pela aba Undo. Você pode

16 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

recuperar desfazendo os erros.

Selecione a pasta Zoo que nós criamos anteriormente e clique Delete. A pasta desaparece. Você pode
voltar desfazendo a ação de deletar.

Clique na aba Undo, como mostra a Figura 2.5.

Figura 2.5 - Aba Undo

Selecione a primeira transação rotulada /manage_delObjects, e clique no botão Undo.

Esta ação diz para o Zope desfazer a última transação. Você pode verificar que a tarefa foi realizada
vendo que a pasta zoo retornou.

Detalhes e Pegadinhas do Desfazendo


Undo funciona no banco de dados objeto que o Zope usa para armazenar todos os seus objetos.
Mudanças no banco de dados objeto acontecem em transações. Você pode pensar em transação como
quaisquer mudanças que você faça no Zope, tais como criar um folder ou colar muitos objetos em um
novo lugar. Cada transação descreve todas as mudanças que aconteceram ao executar uma ação.

Você não pode desfazer uma transação se esta transação depender de uma transação anterior. Por
exemplo, se você cola um objeto em uma pasta e então apaga um objeto na mesma pasta, você pode
querer saber se você pode ou não desfazer a colagem anterior. Ambas as transações mudam o mesmo
folder assim você não pode simplesmente desfazer a primeira transação. A solução é desfazer ambas as
transações. Você pode desfazer mais de uma transação ao mesmo tempo selecionando múltiplas
transações na aba Undo e clicando em Undo.

Outro problema a se estar atento é que você não pode desfazer uma coisa que já foi desfeita. Então se
você adicionar uma pasta e então desfizer essa ação em particular, você não pode voltar a nova pasta
desfazendo novamente.

Uma última observação com relação ao desfazer. Somente mudanças nos objetos armazenados no banco
de dados objeto do Zope podem ser desfeitas. Se você integrou dados em um servidor de banco de
dados relacional como Oracle ou MySQL (discutido no Capítulo 10) então essas mudanças não podem
ser desfeitas.

Administrando e Monitorando o Zope


O Control Panel (Painel de Controle) é um objeto no diretório raíz que controla vários aspectos
operacionais do Zope.

17 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Clicando no objeto Control_Panel do diretório raíz, como mostra a Figura 2.6.

Figura 2.6 - O Painel de Controle

Para fechar o Zope, clique no botão Shutdown. Fechando o Zope fará com que o servidor pare de
controlar as solicitações e saia completamente da memória. Você terá que iniciar o Zope manualmente
para continuar usando-o. Somente feche o Zope se você tiver terminado de usá-lo, e terá capacidade de
acessar o servidor no qual o Zope está rodando, de forma que você possa reiniciá-lo depois.

Se você estiver executando o Zope no UNIX sob o controle de um daemon, ou como um serviço no
Windows, você pode reiniciar o Zope a partir da pasta Painel de Controle. Clicando no botão Restart o
Zope será fechado e imediatamente iniciará uma nova instância do servidor do Zope. Pode levar alguns
segundos para que o Zope volte e inicie o controle das solicitações.

No painel de controle você também verá muitos links na parte inferior da tela, um deles é o Database
Managment (Gerenciamento do Banco de Dados), que controla o banco de dados de objetos do Zope.

Transações não são removidas até que você dê um pack no Banco de dados do Zope. Isto significa que
você pode desfazer todas as transações exceto aquelas já foram removidas por um pack no banco de
dados. Quando você escolhe dar um pack no banco de dados você pode especificar que transações
remover assim você pode por exemplo somente remover transações mais velhas que uma semana.

Usando o Sistema de Ajuda


O Zope possui um sistema de ajuda embutido. Toda tela de gerenciamento tem um botão de ajuda no
canto superior direito. Este botão executa uma nova janela do browser e leva você ao Sistema de Ajuda
do Zope.

Vá ao folder raíz. Clique no botão Help, e você deve ver o que a Figura 2.7 mostra.

18 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 2.7 - Sistema de Ajuda

O sistema de ajuda tem uma organização parecida com os dois primeiros planos da interface de
gerenciamento do Zope, ele tem um frame para navegação e um para mostrar o tópico corrente.

Sempre que você clica no botão de ajuda da tela de gerenciamento do Zope, o frame direito do sistema
de ajuda mostra o tópico de ajuda para a tela de gerenciamento atual. Neste caso, você vê informações
sobre a aba Contents da pasta.

Navegando e Buscando Ajuda


Normalmente você usa o sistema de ajuda para obter ajuda em um tópico espcífico. De qualquer forma,
você pode navegar por todo o conteúdo da ajuda se você estiver curioso, ou simplesmente para
encontrar coisas além da tela de gerenciamento que você está visualizando agora.

O sistema de ajuda deixa você navegar por todos os tópicos de ajuda na aba Contents do frame de ajuda
à esquerda, como mostra a Figura 2.7. Você pode expandir e ocultar os tópicos de ajuda. Para ver um
tópico de ajuda no frame da direita, clique nele.

Toda a ajuda nas telas de gerenciamento do Zope, está localizada na pasta Zope help. Dentro dela você
achará muitos tópicos de ajuda. Você também encontrará uma pasta de ajuda chamada API Reference.
Esta pasta contém ajuda sobre scripts Zope, que será explicado explicado no Capítulo 9, " Script
Avançado do Zope."

Quando você instala componentes externos eles também incluem ajuda que você possa navegar. Cada
componente instalado tem sua própria pasta de ajuda.

Procure o sistema de ajuda clicando na aba Search (busca) e entre com um ou mais termos para
pesquisa. Por exemplo, para achar todos os tópicos de ajuda que mencionam pastas, digite "folder"
dentro do campo de busca.

Iniciando o Tutorial do Zope


O Zope vem com um tutorial embutido. O tutorial ajudará você em todos os fundamentos para a criação
e gerenciamento de objetos do Zope. Para entrar no tutorial, adicione um Zope Tutorial à pasta atual
selecionando Zope Tutorial da lista de produtos. Dê a ele um id que seja único no folder corrente, como
tutorial. O tutorial vem com vários exemplos que você pode mudar e copiar para seu uso.

Se você começar o tutorial e quiser parar antes de você ter completado todas as lições, você pode
retornar depois ao tutorial. Apenas vá ao sistema de ajuda e encontre a lição que você gostaria continuar

19 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

no Zope Tutorial na pasta ajuda. Não é necessário reinstalar o tutorial.

Se você tiver problemas com o tutorial, certifique-se que você ativou os cookies do seu browser. O
tutorial usa os cookies para manter um rastro para saber onde seus objetos exemplo estão. Assim, se
você ativou o JavaScript em seu browser, o tutorial certificar-se-á de que a interface de gerenciamento
do Zope está em sincronia com sua lição no tutorial.

Agora que você tem o Zope rodando, está na hora de explorar mais o sistema. Você viu como
administrar o Zope pela web e aprendeu um pouco sobre os objetos do Zope. No próximo capítulo você
verá muitos objetos diferentes e descobrirá como construir aplicações simples com eles.

4. Usando Objetos Básicos do Zope


Este capítulo introduz objetos, que são os elementos mais importantes do Zope. Nele
mostramos o que é um objeto em geral, então introduzimos os objetos básicos do Zope:
folders (pastas), DTML documents (Documentos DTML), DTML methods (Métodos
DTML), files (arquivos) e images (imagens).

Ao construir uma aplicação para a web com Zope, você constrói a aplicação a partir de objetos. Pelo
projeto, objetos diferentes lidam com partes diferentes de sua aplicação. Alguns objetos mantêm o
conteúdo de seus dados, tais como documentos de processador de textos, planilhas e imagens. Alguns
objetos controlam a lógica de sua aplicação aceitando dados de um formulário da web, ou executando
um script. Alguns objetos controlam o modo que seu conteúdo é exibido, ou apresentado a seu
espectador, por exemplo, como uma página da web, ou por e-mail. Em geral os objetos do Zope têm três
tipos de papéis:

Conteúdo

Os objetos do Zope, tais como documentos, imagens e arquivos têm tipos diferentes de dados textuais e
binários. Além dos objetos no Zope conterem conteúdo, o Zope pode trabalhar com conteúdo
armazenado externamente, por exemplo, em um banco de dados relacional.

Lógica

O Zope tem facilidades para escrever lógica de negócio com scripts. O Zope permite a você escrever um
comportamento usando Python, Perl, e SQL. "Lógica de aplicação" é qualquer tipo de programação que
não envolve apresentação, mas particularmente envolve o transporte de tarefas como objetos
modificados, envio de mensagens, teste de condições e resposta a eventos.

Apresentação

Você pode controlar o layout do seu site com objetos do Zope que agem como modelos de página da
web. O Zope vem com uma linguagem script baseada em tags chamada de Linguagem de Marcação para
Modelo de Documentos (DTML -Document Template Markup Language) para controlar a apresentação.

A palavra objeto é um termo sobrecarregado. Dependendo de seu contexto, pode significar várias coisas
diferentes. Neste capítulo, você pode pensar em um objeto do Zope como um componente de aplicação
que você pode controlar e editar usando um web browser.

O Zope vem com muitos objetos embutidos que o ajudam a executar diferentes tarefas. Você também
pode instalar objetos externos ao Zope para ampliar as capacidades do Zope. Este capítulo explica os
objetos mais básicos e como eles trabalham. Você pode criar sites completamente funcionais no Zope
usando os poucos objetos básicos que são mostrados neste capítulo.

20 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Este capítulo é estruturado livremente em torno das três categorias anteriores, Conteúdo, Lógica, e
Apresentação. Há outros tipos de objetos no Zope que não se ajustam claramente em um destes três
papéis; esses são explicados no final do capítulo.

Usando Pastas do Zope


Pastas (do inglês, Folders) são os blocos de construção do Zope. O objetivo de uma pasta é conter outros
objetos, e organizar os objetos separando-os em grupos diferentes.

Pastas podem conter todos os tipos de objetos, incluindo outras pastas, assim você pode criar pastas
dentro de pastas para formar uma árvore de pastas. Este tipo de pasta dentro de um arranjo de pastas
proporciona estrutura ao seu site em Zope. Uma boa estrutura é muito importante, como quase todos
os aspectos de Zope (desde a segurança até o comportamento para apresentação), são influenciados
pela estrutura de pasta de seu site.

Estrutura de pasta deveria ser algo familiar a qualquer um que trabalhou com arquivos e pastas no
computador com um programa de gerenciamento de arquivo como o Microsoft Windows Explorer ou
qualquer um dos gerenciadores de arquivos populares do UNIX como xfm, kfm, ou o gerenciador de
arquivos do Gnome. A interface de gerenciamento do Zope tenta se parecer o máximo possível com um
destes programas populares de forma que você esteja familiarizado em como organizar os objetos no
Zope como você organizaria arquivos em seu computador.

Gerenciando os Conteúdos da Pasta

No Capítulo 2 "Usando o Zope", você criou objetos e moveu estes objetos. Em resumo, você cria objetos
em pastas ao escolher o tipo de objeto que você está procurando no menu de seleção no topo da aba
Contents da pasta. Então você preenche o formulário de adição e dá um submit. Um objeto novo é então
acrescentado à pasta atual. Você pode mover objetos entre as pastas usando os botões Cut (Recortar),
Copy (Copiar), Paste (Colar), Delete (Apagar), e Rename (Renomear).

Importando e Exportando Objetos

Você pode mover objetos de um sistema do Zope para outro usando export e import. Você pode
exportar todos os tipos de objetos do Zope para um arquivo de exportação. Este arquivo pode ser
importado então para dentro de qualquer outro sistema do Zope.

Você pode pensar em exportar um objeto como clonar um pedaço de seu sistema Zope para um arquivo
que você pode então mover de máquina para máquina. Você pode pegar este arquivo e pode montar o
clone em qualquer outro servidor Zope. Imagine que você tinha alguns documentos em uma pasta do
Zope. Se você quisesse copiar apenas esses objetos para o sistema Zope de seu amigo, você poderia
exportar a pasta e enviar o arquivo de exportação por e-mail ao amigo, que poderia importá-lo então.

Suponhamos que você tenha uma pasta para tarefa de casa que você queira exportar de seu servidor
Zope na escola, e levar para casa com você para trabalhar no servidor Zope da sua casa. Você pode criar
uma pasta como esta em seu diretório raiz chamada "homeWork". Vá para a pasta que contém sua pasta
homeWork. Selecione a pasta homeWork checando a checkbox próximo a ela. Então clique o botão
Import/Export. Você deve agora estar trabalhando na tela da pasta Import/Export.

21 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 3.2 - Visão de Import/Export objetos

Há duas sessões para esta tela. A metade de cima é a sessão de exportação e a metade de baixo é a
sessão de importação. Para exportar um objeto desta tela, digite o id do objeto dentro do primeiro
campo do elemento, Export object id. Em nosso caso o Zope já preencheu este campo para nós,
considerando que nós selecionamos o folder homeWork na tela anterior.

A próxima opção do formulário deixa você escolher entre fazer o download do arquivo de exportação
para seu computador ou deixá-lo no servidor. Se você selecionar Download to local machine, e clicar o
botão Export, seu browser estará pronto para fazer o download do arquivo de exportação. Se você
selecionar Save to file on server, então o Zope salvará o arquivo na mesma máquina na qual o Zope está
rodando, e você mesmo deve trazer o arquivo daquele local. O arquivo de exportação será escrito parao
diretório var do Zope em seu servidor. Por default os arquivos exportados têm a extensão do arquivo
.zexp.

Em geral é mais útil baixar o arquivo de exportação para a sua máquina local. Às vezes é mais
conveniente salvar no servidor se, por exemplo você estiver em uma conexão lenta e o arquivo de
exportação for muito grande, ou se você estiver apenas tentando mover o objeto exportado para outra
instância do Zope no mesmo computador.

O elemento final do formulário de exportação é a caixa de seleção XML format?. Selecionando esta caixa
exportamos o objeto no formato eXtensible Markup Language (XML). Não selecionando esta caixa
exportamos o arquivo no formato binário do Zope. O formato XML é muito maior para baixar, mas é
legível e gramaticalmente analisável. Por enquanto a única ferramenta que entende este formato XML é
o próprio Zope, mas no futuro deverão haver outras ferramentas que podem entender o formato XML
do Zope. Em geral você deveria deixar esta caixa não selecionada a menos que você esteja curioso em
saber como o formato XML se parece e queira examiná-lo.

Clique o botão Export e salve seu arquivo de exportação homeWork.zexp

Agora supõe-se que você já foi para casa e quer importar o arquivo no servidor Zope da sua casa.
Primeiro você deve copiar o arquivo de exportação no diretório import do Zope em seu servidor. Agora,
vá para a tela Import/Export da pasta onde você quer executar a importação. Entre com o nome do
arquivo de exportação no campo Import File name e clique no Import para importar esses objetos no
Zope.

O Zope lhe dá opção ou para Take ownership of imported objects ou para Retain existing ownership
information. Ownership (propriedade) será discutida no Capítulo 7 "Usuários e Segurança." . Agora,
deixe a opção Take ownership of imported objects selecionada.

Depois que você importar o arquivo você deve ver um novo objeto na pasta do Zope onde você executou

22 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

a importação.

Para levar a sua lição de casa para a escola, execute o mesmo processo de import e export. Observe que
você não pode importar um objeto em uma pasta que tem um objeto com o mesmo id. Então, quando
você levar a sua lição de casa para a escola, você precisará importá-la dentro de uma pasta que não tem
uma pasta homeWork nela. Então, você precisará apagar sua velha pasta homeWork e copiar a pasta
mais recente em seu lugar.

Pastas Temporárias

Pastas Temporárias (Temporary folders) são pastas do Zope que são usadas para armazenar objetos
temporários. Pastas Temporárias agem quase da mesma forma que uma pasta comum com três
diferenças significativas:

1. Tudo contido na pasta temporária desaparece quando você reinicializa o Zope.


2. Você não pode desfazer ações para objetos armazenados em pastas temporárias.
3. Você não pode usar uma Versão para manipular objetos em uma pasta temporária.

Por padrão, existe uma pasta temporária em sua pasta raiz chamado temp_folder. Você pode reparar
que existe uma objeto intitulado, "Session Data Container" em temp_folder. Este é um objeto usado
pela configuração do sistema de seção default do Zope (Zope's default sessioning system configuration).
Veja mais tarde neste capítulo a seção "Usando Sessões" para mais informações sobre sessões.

Pastas temporárias armazenam seus conteúdos na RAM ao invés de no banco de dados do Zope. Isto faz
com sejam apropriados para armazenar pequenos objetos que recebem muitas operações de escrita, tais
como dados de sessão. Entretanto, é uma má idéia usar temporary folders para armazenar grandes
objetos porque seu computador pode potencialmente ficar sem RAM.

Usando Modelos de Páginas do Zope


No Zope 2.5, um tipo novo, poderoso de objeto foi acrescentado chamado Page Templates. Page
templates permitem que você defina apresentação dinâmica para uma página da web escrevendo um
modelo HTML. O HTML em seu modelo é feito dinamicamente pela inserção de elementos especiais de
namespace XML para seu HTML que define o comportamento dinâmico para aquela página.

Modelos de Páginas são Poderosos por Algumas Razões:

Eles são sempre HTML válido. Não há necessidade de inserir código inválido em seus modelos
como você poderia com outras linguagens dinâmicas.
Page templates separam lógica de apresentação. Intencionalmente focando nos objetivos da
apresentação, modelos de páginas não permitem que você as use como uma linguagem de
programação como propósitos gerais.
Projetistas do HTML não precisam ser programadores.Uma vez que os modelos de páginas
começam de um HTML, seus projetistas não precisam saber nada sobre programação para
desenvolver o projeto inicial de um modelo de página.
Seus programadores não precisam ser projetistas de HTML. Page templates também têm um
benefício de direção, porque seus programamdores podem fazer seus modelos dinâmicos apenas
adicionando atributos da tag XML, eles podem experimentar diferentes comportamentos
dinâmicos sem destruir ou reescrever seu HTML original.

Criando Modelos de Páginas do Zope

Crie um Folder chamado Sales na pasta raiz. Clique na pasta Sales e então selecione Page Template da

23 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

lista de adição sobre a qual você aprendeu no Capítulo 2. Este processo levará você ao formulário de
adição de um modelo de página. Especifique o id "SalesPage" e o título "Template for Sales Staff" e
clique em Add. Você criou com sucesso um page template. Entretanto, seu conteúdo é um texto padrão,
assim vá para o passo seguinte para editar o conteúdo.

Editando Modelos de Páginas do Zope

A maneira mais fácil de editar um modelo de página é clicando em seu nome ou ícone na interface de
gerenciamento do Zope. Quando você clica em qualquer um desses itens, você é levado a aba Edit do
page template que oferece a você uma área de texto onde você pode editar o modelo. Substitua o
conteúdo original que vem com o modelo de páginas com o seguinte HTML:

<html>
<body>
<h1>This is my first page template!</h1>
</body>
</html>

e clique Save. Agora você pode clicar na aba View para visualizar o page template. Este modelo
particular não faz nada de especial nem tem qualquer comportamento dinâmico. Nas seções posteriores
neste capítulo, iremos adicionar alguns comportamentos dinâmicos. No Capítulo 5, você usará o modelo
de páginas com maiores detalhes para criar apresentação dinâmica.

Atualizando Modelos de Páginas do Zope

Suponha que você preferiria não editar seus modelos HTML em um browser, ou que você tenha
algumas páginas existentes que gostaria de trazer para dentro do Zope. O Zope permite que você
atualize seus arquivos html existentes e converta-os em modelos de páginas.

Selecione Page Template do menu de adição, isto vai levar você ao formulário de adição para o page
templates que nós vimos anteriormente. O último elemento no formulário de adição é o botão Browse.
Clique neste botão. Seu browser irá abrir uma caixa para você selecionar um arquivo. Selecione o
arquivo texto em seu computador que você quer atualizar neste modelo.

Digite em seu Id algo para o novo Documento e clique Add. Depois de clicar Add, você será levado de
volta à tela de gerenciamento. Lá você verá seu novo modelo de páginas.

Usando os Documentos do Zope


Documentos armazenam texto. Nas aplicações web você geralmente usa documentos para criar páginas
web. Você também pode usar documentos para armazenar arquivos de texto, pedaços de texto ou
código HTML como barras laterais ou cabeçalhos. Além de conter textos, um documento permite que
você edite o texto através da web. O Zope tem vários tipos diferentes de documentos. O mais
importante é o documento DTML. DTML significa Linguagem de Marcação para Modelos de
Documentos.

Há outros tipos de objetos de terceiros (geralmente chamados de "Products") disponíveis de fontes


como Zope.org que estenderão sua instalação para suportar outros tipos de conteúdos textuais e não
textuais.

Documentos DTML

Use o DTML Document para criar páginas web e seções de documentos, como uma barra lateral que

24 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

pode ser compartilhada por páginas web. DTML Documents podem conter comandos de script em
DTML (linguagem de script baseada em tags do Zope). A mistura de HTML e DTML gera páginas
dinâmicas para a web.

DTML Documents são também utilizados para criar conteúdo compartilhado, como estruturas de
documentos comuns.

Criando Documentos DTML

Crie uma Pasta chamada Sales e selecione DTML Document da lista de adição. Este processo o levará ao
formulário de adição para o documento DTML. Especifique o id "SalesStaff " e o title (título) "The Jungle
Sales Staff" e clique Add. Você criou com sucesso um documento DTML. Porém, seu conteúdo é um
texto padrão, assim passe para o próximo passo para editar o conteúdo.

Editando Documentos DTML

O modo mais fácil e rápido para editar um DTML Document é pela interface de gerenciamento. Para
selecionar um documento, clique no seu nome ou ícone para que apresente o formulário mostrado na
Figura 3.2.

Figura 3.2 - Editando um DTML Document

Esta visualização mostra uma área de texto na qual você pode editar o conteúdo do seu documento. Se
você clicar o botão Save Change você salva as mudanças que você fez na área de texto. Você pode
controlar o tamanho da área de texto com os botões Taller, Shorter, Wider, e Narrower. Você também
pode carregar um novo arquivo no documento com o campo File e o botão Upload File.

Apague o conteúdo default que está automaticamente dentro do documento DTML atual SalesStaff.

Acrescente o seguinte conteúdo HTML ao documento SalesStaff:

<html>
<body>
<h2>Jungle Sales Staff</h2>

<ul>
<li>Tarzan</li>
<li>Cheetah</li>
<li>Jane</li>
</ul>

</body>

</html>

25 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Depois que você completou as mudanças em seu documento, clique no botão Save Changes. O Zope
retorna com uma mensagem dizendo que suas mudanças foram feitas. Agora, você pode olhar o
documento clicando na aba View.

Parabéns! Você acaba de usar o Zope para criar uma página HTML. Você pode realizar a criação e edição
em um passo ao invés de dois usando o botão Add and Edit na página de adição.

Você pode editar o seu HTML online e visualizá-lo imediatamente. De fato, você pode criar sites inteiros
em Zope com documentos HTML e folders. Este processo mostra apenas a superfície dos benefícios do
Zope, mas ele oferece uma boa maneira de familiarizar você com o Zope. Você também pode escrever
alguns conteúdos dinâmicos em Zope e deixar que aqueles que são interessados em design editem suas
próprias páginas HTML desta maneira.

Subindo (uploading) um Arquivo HTML

Suponha que você preferiria não editar seus arquivos HTML em um browser, ou que você tem algumas
páginas HTML que você gostaria de colocar no Zope. O Zope permite que você atualize seus arquivos de
texto existentes e os converta em DTML Documents.

Selecione Add DTML Document do menu de adição, que o levará ao formulário de adição para
documentos DTML. O último elemento do formulário no formulário de adição é o botão Browse. Clique
este botão. Seu browser apresentará uma caixa de diálogo para seleção do arquivo. Selecione o arquivo
texto em seu computador que você quer subir (upload) neste documento.

Digite um Id para o novo Documento e clique Add. Depois de clicar Add, você será levado de volta à tela
de gerenciamento. Lá você verá seu novo documento.

Visualizando Documentos DTML

O primeiro objetivo de um DTML Document é organizar o conteúdo útil. O Uso primário do conteúdo é
ser visto. DTML Documents podem ser vistos de diferentes maneiras:

Interface de Gerenciamento

Da interface de gerenciamento você pode clicar em uma aba View do Documento para ver o conteúdo do
documento.

Chamando Diretamente Pela Web

Documentos podem ser chamados diretamente através da web pela sua URL de localização através de
um browser.

Chamado por Outro Objeto

Outros objetos, especialmente outro objeto DTML, podem exibir o conteúdo de um Documento.

Chamando Através da Web

Como todos os objetos do Zope, uma URL de um documento DTML é baseada em seu id. Por exemplo,
se você tem um documento DTML na pasta raíz chamado Bob, então sua URL deveria ser:

http://localhost:8080/Bob

Se Bob está num sub-folder chamado Uncles então sua URL deveria ser:

26 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

http://localhost:8080/Uncles/Bob

Poderia haver outros documentos DTML na pasta Uncles chamada Rick, Danny e Louis. Você acessa-os
através da web similarmente:

http://localhost:8080/Uncles/Rick
http://localhost:8080/Uncles/Danny
http://localhost:8080/Uncles/Louis

Traduzir URLs para objetos não é uma idéia nova. servidores web como o Apache fazem isso todo o
tempo. Eles traduzem URLs para arquivos e diretórios em um sistema de arquivos. O Zope leva essa
simples idéia para dimensões maiores. No Zope, URLs são sempre simples para ler porque elas
mapeiam facilmente e simplesmente a maneira que os objetos estão organizados no Zope. è por isso que
dissemos a você que a estrutura do seu site é a chave para o sucesso do seu site.

Ir diretamente para a URL de um DTML Document chamamos de chamando-o através da web. Isto faz
com que o conteúdo do documento DTML seja processado e retornado para seu web browser. No
próximo capítulo sobre DTML, veremos o que significa processar o DTML, mas agora você pode
facilmente experimentar o DTML e conteúdo HTML simples para obter a idéia.

Chamando de Outro Objeto

Ao usar o Zope você provavelmente já encontrou exemplos de DTML como este:

<dtml-var standard_html_header>

<h1>This is some simple HTML</h1>

<dtml-var standard_html_footer>

Aqui nós vimos que um objeto DTML, standard_html_header está sendo chamado pelo documento
que contém este código. Neste caso, os conteúdos processados do primeiro documento são inseridos
dentro dos conteúdos deste documento chamado. Este é um conceito fundamental no Zope e será
usado ao longo do livro.

Revisando Mudanças nos Documentos

A aba Undo deixa você desfazer uma transação de cada vez, mas freqüentemente é útil desfazer
somente mudanças para um objeto. Lembre-se de que uma transação pode ser um grupo de ações todas
recebidas ao mesmo tempo. Se um documento foi editado em uma transação que também incluiu a
mudança de um objeto, você deve apenas querer desfazer a mudança ao documento, mas não desfaz a
mudança no arquivo. Para fazer isso, você pode ir até a aba History daquele objeto e pode olhar para os

27 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

estados anteriores do objeto, como mostra a Figura 3.4.

Figura 3.4 - A aba History

Documentos até suportam a idéia de comparar revisões, lhe permitindo localizar mudanças a seus
objetos. Por exemplo, documentos e métodos DTML lhe permitirão selecionar duas revisões e
compará-las uma à outra. Você deve querer usar isto para ver o que pessoas fizeram a seu objeto, por
exemplo, digamos você tenha um documento que continha uma lista de todos os animais em um
Zoológico. Se um de seus colegas de trabalho vai e edita aquela lista e a salva, você pode usar a
característica de comparação de história para comparar a mais recente "nova" versão do arquivo com a
próxima versão mais recente.

Esta comparação é exibida em um formato popular chamado diff. O diff mostra as linhas que foram
acrescentadas ao novo documento (através um mais), que linhas foram subtraídas do documento antigo
(através de um menos), e quais linhas foram substituídas ou foram mudadas (através de um ponto de
exclamação).

Edição Remota com FTP, WebDAV e PUT


O Zope permite editar documentos diretamente em seu browser, entretanto essa não é a única maneira
que os documentos podem ser editados no Zope. Para documentos simples, a edição através da web é
um método cômodo. Mas para documentos grandes, complexos, ou documentos que têm formatação
especial, é útil poder usar o editor que você já está acostumado.

Documentos DTML podem ser editados com FTP, WebDAV, e o protocolo HTTP PUT. Muitos editores
de HTML e de texto suportam estes protocolos para edição de documentos em servidores remotos.
Cada um destes protocolos tem vantagens e desvantagens:

FTP

FTP é o Protocolo de Transferência de Arquivo. FTP é usado para transferir um arquivo de um


computador para outro. Muitos editores de texto suportam FTP, por isso ele é muito útil.

WebDAV

WebDAV é um novo protocolo da internet baseado no protocolo fundamental da Web, HTTP. DAV
representa Autorização e Versão Distribuída (Distributed Authoring and Versioning). Pelo fato de DAV
ser novo, não pode ser suportado por tantos editores de texto quanto o FTP.

PUT

28 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

O protocolo HTTP suporta um modo simples de atualizar conteúdos de um servidor chamado PUT.
PUT é suportado por muitos editores de HTML, como o Netscape Composer.

Usando um destes métodos, você pode editar seu conteúdo com uma variedade de ferramentas. Nas
próximas seções, nós lhe mostraremos algumas ferramentas simples que usam FTP para editar o
conteúdo no Zope.

Atualizando Documentos e Arquivos com o WS_FTP

WS_FTP é um cliente de FTP popular para Windows que você pode usar para atualizar documentos e
arquivos no Zope com o protocolo FTP. WS_FTP pode ser baixado da Home Page do Ipswitch.

Há outro cliente de FTP popular para Windows, e muitos browsers como Netscape e Microsoft Internet
Explorer vem com clientes de FTP. Esta seção também refere-se a outros clientes de FTP.

No Capítulo 2 "Usando o Zope", você determinou a URL de seu sistema do Zope olhando para o log do
começo. Descobrir como contatar o servidor de FTP de seu Zope segue um processo semelhante:

−−−−−−
2000−08−07T23:00:53 INFO(0) ZServer Medusa (V1.18) started at Mon Aug 7 16:00:53 2000
Hostname: peanut
Port:8080
−−−−−−
2000−08−07T23:00:53 INFO(0) ZServer FTP server started at Mon Aug 7 16:00:53 2000
Authorizer:None
Hostname: peanut
Port: 8021
−−−−−−
2000−08−07T23:00:53 INFO(0) ZServer Monitor Server (V1.9) started on port 8099

O log inicial diz que o servidor de FTP do Zope está executando na porta 8021 na máquina chamada
peanut. Quando você começar WS_FTP, você precisará saber o nome de máquina e informação da porta
assim você pode conectar-se ao Zope via FTP. Depois de digitar no nome da máquina e porta do seu
servidor do Zope, clique o botão Conectar. WS_FTP lhe pedirá agora um nome de usuário e senha.
Entre com seu nome de usuário de administrador e senha para a interface de gerenciamento do Zope.

Se você digitar seu nome de usuário e senha corretamente, WS_FTP lhe mostrará como seu site no Zope
se parece através de FTP. Há pastas e documentos que correspondem exatamente ao modo que seu
diretório raiz do Zope se parece pela web, como mostra a Figura 3.3.

29 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 3.3 - Editando Zope por FTP

Transferência de arquivos para e do Zope é uma tarefa muito fácil feita com o WS_FTP. No lado
esquerdo da janela do WS_FTP está uma caixa de seleção de arquivo que representa arquivos em sua
máquina local. A caixa de seleção de arquivo no lado direito da janela do WS_FTP representa objetos em
seu sistema do Zope. Transferir arquivos de seu computador para o Zope ou vice versa é tão fácil quanto
selecionar o arquivo que você queira transferir e clicar a seta da esquerda (download) ou a seta da
direita (upload). WS_FTP tem muitas características interessantes e padrões que você pode usar para
fazer facilmente o gerenciamento de objetos remotos do Zope.

Editando Objetos do Zope com o Emacs

Emacs é um editor de texto muito popular. Na realidade, Emacs é mais do que apenas um editor de
texto, é uma cultura inteira. Emacs vem em dois sabores, GNU Emacs e XEmacs. Ambos os sabores de
Emacs podem trabalhar diretamente em cima de FTP para manipular documentos do Zope e outros
conteúdos textuais.

Emacs deixará você tratar qualquer sistema de FTP remoto como qualquer outro filesystem local,
fazendo do gerenciamento remoto do conteúdo do Zope um processo fácil. Então, você não precisa sair
do Emacs para usar o Zope.

Emacs oferece um conjunto mais rico de capacidade de edição de texto do que a maioria das áreas de
texto dos browsers. Emacs pode ser usado para editar documentos diretamente e manipular objetos via
FTP, então Emacs é um agradável ambiente de desenvolvimento para o Zope.

Por default quando você iniciar o Zope, o Zope execita um servidor de FTP da mesma maneira que roda
um servidor de HTTP. Você pode especificar em que porta o servidor FTP deveria executar quando você
inicia o Zope, mas por default esta porta é a 8021.

Para logar no Zope, rode o Emacs. O arquivo que você visita para abrir uma conexão de FTP depende de
qual editor de texto você está executando: XEmacs ou Emacs:

Xemacs

Para visitar um arquivo remoto em XEmacs, visite um arquivo pela forma: /user@server#port:/

Isto abrirá uma conexão para a pasta / do servidor de FTP rodando no servidor e executando na porta
port.

Emacs

Para visitar um arquivo remoto no Emacs, visite um arquivo pela forma: /user@server port:/

O espaço literal é inserido segurando as teclas Controle e Q, e pressionando o espaço "C-Q".

Para a instalação típica do Zope com XEmacs, o nome do arquivo para abrir uma sessão de FTP com o
Zope é /user@localhost#8021:/.

Emacs lhe pedirá uma senha para logar no servidor de FTP do Zope.

Visitando a pasta / de um servidor de FTP no Zope, Emacs listará os conteúdos do diretório raiz:

drwxrwx--- 1 Zope Zope 0 Dec 30 1998 Control_Panel


drwxrwx--- 1 Zope Zope 0 Dec 30 1998 QuickStart
drwxrwx--- 1 Zope Zope 0 Dec 30 1998 Sales

30 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

-rw-rw---- 1 Zope Zope 1024 May 3 1999 index_html


-rw-rw---- 1 Zope Zope 1381 May 3 1999
standard_error_message
-rw-rw---- 1 Zope Zope 55 Dec 30 1998
standard_html_footer
-rw-rw---- 1 Zope Zope 81 Dec 30 1998
standard_html_header

Você pode visitar quaisquer destes "arquivos" (que realmente são objetos do Zope) selecionando-os do
modo do Emacs. A edição com o Emacs é muito útil, mas para a maioria, o Emacs é um programa muito
complexo que não é muito acessível à maioria das pessoas. Por exemplo, a maioria dos usuários do
Macintosh não tem familiaridade com uma ferramenta como o Emacs. Há vários editores "mais fáceis"
que podem ser usados que também usam FTP e WebDAV. Na realidade, WebDAV é projetado para ser
usado por ferramentas como Adobe GoLive e Macromedia Dreamweaver.

Editando DTML Documents com WebDAV

WebDAV é um novo protocolo de Internet comparado com o HTTP ou FTP, assim há poucos clientes
que o suportam. Porém, há muito impulso atrás do movimento do WebDAV e mais clientes estão
usando-o. Para mais informação sobre que programas suportam o protocolo WebDAV, veja a homepage
do WebDAV.

WebDAV é uma extensão ao protocolo de HTTP que oferece características ricas para muitos usuários
que ao mesmo tempo preparam e editam o conteúdo nos sites da web. WebDAV oferece características
como locking, controle de revisão, e marcação de documentos ou objetos com propriedades. Por causa
das metas do WebDAV de, pela web editar algumas metas do Zope, o Zope tem suportado o protocolo
WebDAV há algum tempo.

O protocolo de WebDAV está evoluindo depressa, e novas características estão sendo adicionadas a
todo momento. Você pode usar qualquer cliente do WebDAV para editar seus DTML Documents
simplesmente apontando o cliente para a URL de seu documento e editá-lo. Para a maioria dos clientes,
porém, isto fará com que eles tentem editar o resultado de renderização do documento, não do fonte.
Para documentos que usam a linguagem modelo DTML do Zope para criar conteúdos dinâmicos, isto
pode ser um problema.

Até que os clientes adquiram o último padrão de WebDAV e entendam a diferença entre o fonte de um
documento e seu resultado, o Zope oferece um servidor de HTTP especial que você pode habilitar com o
a opção de linha de comando -W. Este servidor executa em uma porta diferente do seu servidor de
HTTP normal e retorna diferente, conteúdos do fonte especiais para pedidos do WebDav que entram
naquela porta. Esta é uma característica avançada e é explicado mais na Seção de Documentação do
Zope.org.

Usando Arquivos do Zope


Arquivos do Zope contêm dados crus, da mesma maneira que os arquivos em seu computador fazem.
Muitas informações, como softwares, audio, video e documentos são transportados pela Internet e pelo
mundo como arquivos. Você pode usar arquivos para organizar qualquer tipo de informação que o Zope
especificamente não suporta, como arquivos Flash, applets, tarballs, etc.

Arquivos não consideram seus conteúdos para serem de qualquer formato em especial, textual ou
outro. Arquivos são bons para organizar qualquer tipo de conteúdo binário que seja apenas informação
de computador de algum tipo. Os arquivos também são bons para organizar conteúdo textual que não
necessite de script DTML.

31 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Todo objeto Arquivo tem um tipo de conteúdo particular que é uma Internet MIME padrão designação
para tipo de arquivo. Quando você atualiza um arquivo no Zope, este tenta julgar o tipo de conteúdo do
nome do arquivo, mas o Zope nem sempre julga corretamente.

Atualizando Arquivos

Como DTML Methods e Documents, Arquivos permitem atualizar um arquivo de seu computador
quando você criar um objeto novo. Clique o botão Browse para escolher um arquivo de seu computador
local quando estiver criando um novo File do Zope. Tente escolher um arquivo como um arquivo Word
(.doc) ou um arquivo Portable Document Format (.pdf). Observe, quando atualizar um arquivo com seu
browser, você pode ter que indicar o tipo de arquivo que você está procurando na caixa de diálogo de
atualização do seu browser. Depois de selecionar um arquivo para atualizar, clique Add. Dependendo do
tamanho do arquivo que você quer atualizar, pode levar alguns minutos para adicionar o arquivo ao
Zope.

Depois de adicionar o Arquivo, clique no novo Arquivo e olhe a sua aba Edit. Aqui você verá que o Zope
adivinhou o tipo do conteúdo como mostra a Figura 3.5.

Figura 3.5 - Propriedade Tipo do conteúdo do Arquivo

Se você adicionar um documento do Word, o tipo do conteúdo é application/msword. Se você adicionar


um arquivo PDF, o tipo do conteúdo é application/pdf. Se o Zope não reconhecer o tipo do arquivo, ele
escolhe um default, o tipo genérico do conteúdo application/octet-fluxo.

Você pode mudar os conteúdos de um Arquivo existente indo para a aba Upload. Aqui você pode
substituir os conteúdos do Arquivo por um arquivo novo. Se você não preencher o id e o title deste
formulário e você atualizar um arquivo, o Zope usará o filename do id e o title do objeto.

Editando Arquivos

Se seu arquivo contém texto e é menor que 64K, então o Zope deixa você editá-lo na interface de
gerenciamento. Um arquivo texto é aquele que tem um tipo conteúdo que começa com text/, como
text/html, ou text/plain. Você pode algumas vezes achar conveniente editar arquivos de texto na
interface de gerenciamento. De qualquer forma, você pode sempre editar arquivos localmente e depois
atualizá-los no Zope.

Visualizando Arquivos

Você pode visualizar um arquivo indo para a aba View da interface de gerenciamento. Você também
pode ver um Arquivo visitando sua URL. Na realidade a aba View é apenas uma maneira de chegar à

32 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

URL do Arquivo pela interface de gerenciamento do Zope. Por exemplo, se você tem um arquivo em seu
diretório raiz do Zope chamado employeeAgreement.pdf então você pode visualizar aquele arquivo em
seu browser indo para a URL http://localhost:8080/employeeAgreement.pdf. Dependendo do tipo do
arquivo, seu browser pode exibir o arquivo ou pode baixá-lo.

Usando Imagens no Zope


Imagens exibem gráficos como GIF, JPEG, e arquivos PNG. No Zope, Imagens são semelhantes a
objetos Arquivos, mas incluem comportamento extra por administrar conteúdo gráfico.

Objetos Imagem têm a mesma interface de gerenciamento como os objetos Arquivo. Tudo na seção
anterior sobre usar objetos Aquivo também se aplica a imagens.

Visualizando Imagens com HTML

O uso mais comum para Imagens no Zope está em colocar figuras nas páginas da web. Para pôr uma
figura em uma página da web, você precisa usar a tag HTML IMG. Suponha que você tem um objeto
Imagem em seu diretório raiz chamado logo que contém uma imagem do logo da sua organização.

Usar esta Imagem em seu HTML é um processo muito direto: você pode referenciá-la com uma tag IMG
como você faria para incluir qualquer tipo de imagem em uma página da web:

<dtml-var standard_html_header>
<img src="logo">
<h1>Welcome!</h1>
<dtml-var standard_html_footer>

Neste exemplo, você referencia a imagem do logo criando uma tag HTML IMG, mas normalmente isto
não é necessário para criar sua própria tag IMG para exibir imagens. Objetos Imagem sabem como gerar
suas próprias tags HTML. Quando você insere um objeto Imagem no DTML, isto gera uma tag IMG para
ela.

Agora, nós queremos que este logo seja visto em toda página no canto superior esquerdo, assim ponha
uma referência ao logo no método standard_html_header:

<html>
<body>
<dtml-var logo>

Agora, veja o diretório raiz dando um clique na aba View. Se você olhar para o fonte da página da web
que o Zope cria, você pode ver que o viar do código DTML transformou-se para você em uma tag HTML
IMG:

<html>
<body>
<img src="logo" width="50" height="30">

O uso da tag var da DTML para traçar as Imagens faz coisas simples, porque o Zope automaticamente
calcula para você os atributos de altura e largura da tag IMG. Se você não gosta do modo que o Zope
constrói uma tag IMG, ela pode ser personalizada. Veja o Apêndice B para mais informação sobre o
objeto Imagem e como ele pode controlar a tag IMG.

Existem vários tipos de objetos externos do Zope (geralmente chamados de "Produtos") para armazenar
e visualizar o conteúdo de imagem disponível da seção visual do Zope.org.

33 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Visualizando Imagens Através da Web

Imagens podem ser visualizadas diretamente indo a URL dessas Imagens em seu browser. Por exemplo,
digamos que você queira ver o logo da sua companhia diretamente. O logo existe como um objeto
imagem em seu diretório raiz. É chamado logo, você pode ver isto facilmente indo diretamente a sua
URL http://localhost:8080/logo de URL.

Considerando que as Imagens do Zope trabalham apenas como imagens armazenadas em um servidor
web normal, você pode acessar suas imagens do Zope de outros servidores web. Suponha que você tem
uma Imagem do Zope cuja URL é http://imageserver:8080/Birds/Parakeet.jpg. Você pode incluir esta
Imagem em qualquer página da web servida de qualquer servidor da web usando a URL absoluta da
Imagem em sua página da web:

<html>
<h1>Remote Image</h1>
<img src="http://imageserver:8080/Birds/Parakeet.jpg">
</html>

Este exemplo mostra como você pode usar dados do Zope de fora do Zope usando protocolos de
Internet padrões. Depois no Capítulo 8 deste livro nós veremos como a maioria dos objetos do Zope
podem oferecer serviços para o mundo externo.

Usando Propriedades do Objeto


Propriedades são modos de associar informação aos objetos no Zope. Muitos objetos do Zope, inclusive
folders e documentos, suportam propriedades. Propriedades podem rotular um objeto para identificar
seus conteúdos (muitos objetos dos conteúdos do Zope têm uma propriedade tipo para o conteúdo).
Outro uso para propriedades é oferecer meta-dados para um objeto como seu autor, título, estado, etc.

Propriedades podem ser mais complexas que strings; elas também podem ser números, listas, ou outras
estruturas de dados. Todas as propriedades são administradas pela aba Properties. Clique na aba
Properties de um objeto e você será levado à aba de administração das propriedades, como mostra a
Figura 3.6.

Figura 3.6 - Aba de administração das propriedades

Uma propriedade consiste de um name (nome), um value (valor) e um type (tipo). O tipo de uma
propriedade define que tipo de valor ou valores ela pode ter.

Na Figura 3.6 você pode ver que aquela pasta tem três propriedades, title, Author, KeyWords. As
propriedades título (title) e Autor (Author) são propriedades string, enquanto a propriedade Palavras

34 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

chaves (KeyWords) tem um tipo token. Uma propriedade tokens é como uma sequência de palavras.

O Zope suporta vários tipos de propriedade. Cada tipo se adapta a uma tarefa específica. Esta lista dá
uma avaliação breve dos tipos de propriedades que você pode criar da interface de gerenciamento:

String

Uma string é uma sequência de comprimento arbitrária de caracteres. Strings são o tipo mais básico e
útil das propriedade no Zope.

Int

Uma propriedade int é um inteiro, que pode ser qualquer número positivo ou negativo que não é uma
fração. Um int é aproximadamente um inteiro longo de 32 bits.

Long

Um long é como um inteiro que não tem nenhuma gama de limitação.

Float

Um float é um ponto flutuante, ou número decimal. Por exemplo, valores monetários usam
freqüentemente floats.

Lines

Uma propriedade lines é uma sequência de strings.

Tokens

Uma propriedade tokens é uma lista de palavras separada por espaços.

Text

Uma propriedade text é apenas como uma propriedade string, a não ser pelo fato do Zope normalizar os
caracteres de fim de linha (browsers diferentes usam convenções de fim de linha diferentes).

selection

Uma propriedade selection é especial, ela é usada para executar um controle de entradas selecionadas
no HTML.

multiple selection

Uma propriedade multiple selection é especial, ela é usada para executar um controle de múltiplas
entradas de dados selecionadas no HTML.

Propriedades são ferramentas muito úteis para fazer a marcação de seus objetos do Zope com pequenos
bits de dados ou informações. Junto com métodos e scripts, propriedades estendem um simples objeto
como Pastas com uma técnica muito poderosa.

Codificando Lógica com Scripts


Em linguagem de programação tradicional, um script é um pedaço pequeno de código escrito em uma
linguagem de programação. A partir de versão 2.3, o Zope vem com dois tipos de objetos script: um que
o deixa escreve scripts em Python e um que o deixa escrever scripts em Perl.

35 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Ambas Python e Perl são linguagens de programação muito populares e poderosas. Python e Perl
compartilham muitas características semelhantes: ambas oferecem desenvolvimento poderoso e rápido,
sintaxe simples, muitas bibliotecas em módulo, muitos seguidores, e uma quantidade grande de
documentação grátis, on-line. Ambas as linguagens também são open source.

Pelo fato de os scripts serem tão poderosos e flexíveis, seu uso é infinito. Scripts são principalmente
usados para escrever o que é chamado de business logic. Lógica de aplicação é diferente da lógica de
apresentação. Lógica de apresentação é normalmente escrita em uma linguagem de apresentação, como
DTML, e seu objetivo é mostrar informação ao usuário. Lógica de aplicação é normalmente escrita em
uma linguagem script, e seu objetivo é manipular informação que vem de códigos fonte (como
documentos ou banco de dados) ou manipular outros objetos. Frequentemente, a lógica de
apresentação é baseada no topo da business logic.

Um simples exemplo do uso de scripts é a construção de um formulário para a web online para ajudar
seus usuários a calcular a quantia de juros acumulados em suas dívidas. Este tipo de cálculo envolve o
seguinte procedimento:

1. Você precisa das seguintes informações: seu saldo da conta corrente (ou dívida) chamada de
"principal", a taxa de juros anual expressa em decimal (como 0.095) chamado de "interest_rate",
o número de vezes por ano (em períodos, geralmente mensais), chamado de "periods" e o
número de anos a partir de agora que você quer calcular, chamado "years".
2. Divida seu "interest_rate" por "periods" (geralmente 12). Chamaremos este resultado de "i".
3. Pegue "periods" e multiplique-o por "years". Chamaremos este resultado de "n".
4. Eleve (1 + "i") à potência "n".
5. Multiplique o resultado por seu "principal". Este é o novo saldo (ou dívida).

Para este exemplo, você precisará de dois DTML Methods chamados interestRateForm e
interestRateDisplay para coletar a informação do usuário e exibi-la, respectivamente. Você também
precisará de um script baseado em Python chamado calculateCompoundingInterest que fará o cálculo
atual. O primeiro passo é criar um formulário web em interestRateForm que coleta "principal",
"interest_rate", "periods" e "years" de seus usuários. Aqui está um exemplo do DTML Method
interestRateForm:

<dtml-var standard_html_header>
<form action="interestRateDisplay" method="POST">
<p>Please enter the following information:</p>
Your current balance (or debt): <input name="principal:float"><br>
Your annual interest rate: <input name="interest_rate:float"><br>
Number of periods in a year: <input name="periods:int"><br>
Number of years: <input name="years:int"><br>
<input type="submit" value=" Calculate "><br>
</form>
<dtml-var standard_html_footer>

Este formulário coleta informações e chama o método interestRateDisplay. Agora, crie um script em
Python chamado calculateCompoundingInterest que aceita quatro parâmetros, "principal",
"interest_rate", "periods" e "years" com o seguinte código em python:

## Script (Python) "calculateCompoundInterest"


##parameters=principal, interest_rate, periods, years
##
"""
Calculate compounding interest.
"""

36 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

i = interest_rate / periods
n = periods * years
return ((1 + i) * n) principal

Entre com os parâmetros no campo Parameter List, e o código n o corpo da área de texto. Os
comentários mostrados no começo do código não são necessários quando editados pela web. (Porém
estes comentários são úteis para editar scripts por FTP).

Isto retornará o saldo ou dívida composta no percurso de "years". Depois, crie um DTML Method
interestRateDisplay que chama calculateCompoundingInterest e retorna os resultado:

<dtml-var standard_html_header>
<p>Your total balance (or debt) including compounded interest over
<dtml-var years> years is:</p>
<p><b><dtml-var expr="calculateCompoundingInterest(principal,
interest_rate,
periods,
years)" ></b></p>
<dtml-var standard_html_footer>

Primeiro veja o DTML Method interestRateForm. Agora, digite um pouco de informação sobre seu saldo
ou dívida e clique em Calculate. Isto fará com que interestRateForm submeta a coleta de informação
para interestRateDisplay, que chama o script em Python calculateCompoundingInterest. O método de
exibição usa o valor retornado pelo script na exibição resultante.

Como dissemos anteriormente, as possibilidades para usar scripts são quase infinitas. Porém, este
exemplo lhe dá uma boa idéia do padrão mais comum para apresentação de objetos para coletar e exibir
informação, e usando objetos lógica de aplicação para fazer cálculos.

Usando Métodos
Métodos são objetos no Zope que armazenam conteúdos executáveis especiais. O nome "Method" é
realmente usado impropriamente, e seu uso no Zope está sendo aos poucos substituído por termos
mais comuns como Scripts e Templates.

Zope vem com dois tipos de métodos, DTML Methods e SQL Methods. DTML Methods são usados para
definir modelos de apresentação que você pode aplicar a objetos de conteúdo como DTML Documents e
Files (Arquivos). Um modo muito comum e popular para usar DTML Methods é definir um layout de
apresentação separado de seu conteúdo.

SQL Methods são usados para conter consultas do banco de dados que você pode reusar em toda sua
aplicação web. SQL Methods são explicados no Capítulo 10, Conectividade com Banco de dados
Relacional, onde um exemplo de criação de uma aplicação para a web usando um banco de dados
relacional é dado.

Todos os vários objetos no Zope podem ser manipulados chamando métodos nesses objetos. Por
exemplo, objetos Folder têm um método objectValues que retorna os objetos contidos no Folder. DTML
Methods podem ser usados para escrever simples scripts que chamam estes métodos API do Zope.
Estes métodos são documentados no Sistema de Ajuda (Help System), após a Documentação do API.

Antes do Zope 2.3, DTML Methods eram o único modo para escrever scripts no Zope com seu browser.
Apesar do DTML ser útil para escrever scripts muito simples e por apresentar informação com
templates, esta aproximação teve muitas limitações porque o DTML não é tão flexível quanto outras
linguagens de programação.

37 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Zope 2.3 introduz dois novos tipos de objetos Script baseado em duas linguagens de programação
muito populares, Python (no qual Zope é escrito) e Perl. Você deveria usar scripts baseados em Python e
Perl para escrever scripts mais complexos ao invés de um DTML Method. Olhando a documentação
anterior do Zope, arquivos de listas de email, e outros recursos no "Zope.org" http://www.zope.org,
você pode achar muitas referências a scripts DTML muito complexos. Estes antecedem os scripts
baseados em Python e Perl. Em geral, scripts complexos deveriam ser escritos tanto em Python como
em Perl. Scripts baseados em Python e Perl são descritos mais tarde neste capítulo, e muitos exemplos
de seu uso é dado no Capítulo 6.

Um exemplo simples do uso de DTML Methods é criar um DTML Method no folder raiz chamado
objectList:

<dtml-var standard_html_header>
<ul>
<dtml-in objectValues>
<li><dtml-var getId></li>
</dtml-in>
</ul>
<dtml-var standard_html_footer>

Quando você visualizar este método, ele chamará o método objectValues no folder raiz e será mostrado
uma lista simples em HTML de todos os objetos no folder raiz, como mostra a Figura 3.7.

Figura 3.7 - Resultados do DTML Method objectList

Todas as pastas implementam o método objectValues. O método de objectValues é parte de uma


interface que todos os implementos dos folders chamam ObjectManager.

Além de chamar métodos API em objetos, os DTML Methods podem também ser usados de um certo
modo para estender qualquer objeto do Zope. Isto será explicado com mais detalhes no próximo
capítulo. Em efeito, isto lhe permite estender o Zope API simplesmente criando DTML Methods.

Você apenas viu o método objectList, que está no folder raiz que faz uma lista simples dos conteúdos do
folder raiz. Pelo fato do método estar no folder raiz, ele é usado agora por qualquer objeto que está no
ou abaixo do folder raiz. Este método estende o Zope API para estes objetos considerando que lhes
proporciona outro método de chamada.

Para demonstrar, vamos criar um subfolder chamado Primates e adicionar três documentos, Monkeys,
Apes, Humans. Você pode chamar o método objectList na pasta Primates visitando a URL
Primates/objectList. Você pode ver o efeito de chamar o método objectList na pasta Primates que difere
do efeito de chamá-lo no folder raiz. O método objectList está definido no folder raiz, mas aqui nós

38 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

estamos usando-o para mostrar os conteúdos da pasta Primates. Este mecanismo de reuso de objetos é
chamado de aquisição e será explicado mais no Capítulo 4.

DTML Methods servem principalmente como modelos de apresentação. DTML Methods podem agir
como modelos (templates) que enlaçam pedaços reutilizáveis de conteúdo em páginas dinâmicas para a
web. As características do template dos DTML Methods serão discutidas com mais detalhes no próximo
capítulo.

Comparando Documentos e Métodos DTML


DTML Methods têm a mesma interface de usuário dos DTML Documents, o que pode ser um pouco
confuso para quem está começando. Todos os procedimentos que você aprendeu no último capítulo
para adicionar, editar, visualizar e atualizar os DTML Documents são idênticos para os DTML Methods.

Uma fonte de confusão freqüente para novatos do Zope é a pergunta de quando usar um DTML
Document versus quando usar um DTML Method. Na fachada, estas duas opções parecem
idênticas.Ambas guardam DTML e outros conteúdos, ambas as duas executam código DTML, e ambas
têm uma interface de usuário semelhante e um API semelhante, assim qual é a diferença?

DTML Documents são requeridos para armazenar documentos como conteúdo. Por exemplo, os vários
capítulos de um livro podem ser armazenados em um DTML Document. Uma regra geral é: se seu
conteúdo é principalmente documento e você quer apresentá-lo em seu site, então ele deveria entrar em
um DTML Document.

DTML MEthods são requeridos para manipular outros objetos. DTML MEthods não armazenam muito
conteúdo, a menos que o conteúdo seja necessário para mudar ou manipular outros Conteúdos.

Não preocupe se você ainda tiver dúvidas quanto às diferenças entre DTMl Documents e DTML
Methods. Até mesmo os programadores mais experientes do Zope precisam pensar um pouco antes de
decidir qual tipo de objeto usar, e este livro clareará qualquer confusão que você possa ter. Aqui estão
algumas regras gerais para lhe ajudar a decidir entre DTML Documents e Methods:

1. Se ele é conteúdo, use um DTML Document.


2. Se for lógica simples, use um DTML Method.
3. Se é requerido para ser apresentado por outros objetos, use DTML Document.
4. Se é requerido para apresentar outros objetos, use DTML Method.
5. Se for um comportamento complexo, use um script baseado em Python ou Perl.

Como você viu DTML Methods são uma ferramenta útil para apresentação e scripts rápidos, mas
eventualmente você vai querer dar maior poder ao DTML Method com uma linguagem de programação
completamente expressiva, e é aqui que os Scripts entram.

Usando Seções
Seções permitem a você manter o rastro dos visitantes do seu site. Browsers web usam um protocolo
chamado HTTP para trocar dados com um servidor tal como o Zope. HTTP não oferece uma forma do
servidor manter o rastro de um pedido do usuário; cada pedido é considerado completamente
independente.

Seções superam estas limitações do HTTP. O termo "session" significa uma série de pedidos HTTP
relacionados que vêm do mesmo cliente durante um dado período de tempo. O sistema de seção do
Zope usa cookies e/ou elementos de formulário HTTP "em segundo plano" para manter o rastro do
usuário das seções. O sistema de seção do Zope permite que você evite o gerenciamento manual de

39 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

seções de usuários.

Você pode usar seções para manter o rastro de usuários anônimos bem como aqueles quem têm contas
no Zope.

Dados associados com uma seção são chamados de "session data". Dados de seção são válidos somente
na duração de uma visita ao site como determinado pelo valor configurável do tempo de inatividade.
Dados de seção são usados para manter o rastro de informação sobre uma visita do usuário como os
itens que um usuário colocou em um "shopping cart", ou que páginas um usuário viu na sua visita ao
seu site.

É importante perceber que manter dados sensíveis em um objeto de dados da seção não é seguro a
menos que a conexão entre os browsers e o Zope sejam codificados de algum modo. Não armazene
informações sensíveis como números de telefone, endereços, números de conta, números de cartão de
crédito ou qualquer outra informação pessoal sobre seu visitante a menos que você tenha uma conexão
segura entre o Zope e os visitantes do site via SSL.

Configuração da Seção

AS versões do Zope depois da 2.5 vêm com um ambiente de seção default configurada "pronta para
usar", assim não há necessidade de mudar estes objetos a menos que você esteja curioso ou queira
mudar a maneira como as seções estão configuradas. Para informação sobre a mudança na configuração
da seção, use o sistema de ajuda do Zope.

O Zope usa vários tipos diferentes de objetos para gerenciar dados de seção, e explicações breves sobre
seus seguintes propósitos.

Browser ID Manager

Este objeto gerencia como os browsers do visitante são identificados de pedido a pedido, e
permite que você configure se isto acontece via cookies ou variáveis de formulário, ou via uma
combinação entre ambos.A configuração de seção default oferece um Browser Id Manager como
o objeto /browser_id_manager.

Transient Object Container

Este objeto contém dados de seção. Ele permite que você sete quantos dados de seção
permanecem depois que ele expira. A configuração default da seção oferece um Transient Object
Container chamado /temp_folder/session_data. Os objetos de dados de seção no Transient
Object container session_data default são perdidos cada vez que o Zope é reiniciado.

Session Data Manager

Este objeto conecta-se ao id do browser e informação de dados de seção. Quando uma pasta que
contém um gerenciador de dados da seção é cruzada, o objeto REQUEST é preenchido com a
SESSION, que é um objeto de dado da seção. A configuração default da seção oferece um Session
Data Manager chamado /session_data_manager.

Usando Dados da Seção

Você vai tipicamente acessar dados de seção através do atributo SESSION do objeto REQUEST.

Aqui está um exemplo de como trabalhar com uma seção usando um Script baseado em Python:

40 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

## Script (Python) "lastView"


secs_per_day=246060
session=context.REQUEST.SESSION
if session.has_key(last view):
# The script has been viewed before, since the last view
# has been previously set in the session.
then=session['last view']
now=context.ZopeTime()
session['last view']=now # reset last view to now
return Seconds since last view %.2f % ((now − then) * secs_per_day)
# The script hasn't been viewed before, since there's no last
# view in the session data.
session['last view']=context.ZopeTime()
return This is your first view

Visualize este script, e então recarregue-o algumas vezes. Isto mantém o rastro de quando você
visualizou pela última vez o script e calcula quanto tempo ele foi visto desde que você o visualizou pela
última vez. Observe que se você sair do seu browser e voltar ao script ele esqueceu de você. Entretanto,
se você simplesmente visita alguma outra página e então retorna, ele ainda lembra a última vez que você
o visualizou.

Este exemplo mostra as características básicas de trabalhar com dados de seção: objetos de dados de
seção agem como dicionários Python. Você quase sempre usará dados de seção que consistem de listas
normais em Python, dicionários, strings, e números. A única coisa ruim sobre seções é que quando
trabalhamos com dados de seção mutáveis (por exemplo dicionários e listas) você precisa salvar os
dados da seção reinstalando-os. Aqui temos um exemplo:

## Script (Python) "sessionExample"


session=context.REQUEST.SESSION
# l is a list
l=session['myList']
l.append(spam)
# If you quit here, your changes to the list won't
# be saved. You need to save the session data by
# reassigning it to the session.
session['myList']=l

Para maiores informações sobre persistência e dados mutáveis, veja o Guia do Desenvolvedor do Zope.

Você pode usar seções nos Page Templates e DTML Documents, também. Por exemplo, Aqui está um
pedaço do modelo que mostra as cores favoritas dos usuários (armazenados em uma seção):

<p tal:content="request/SESSION/favorite_color">Blue</p>

Aqui está como fazer a mesma coisa no DTML:

<dtml-with SESSION mapping>


<p><dtml-var favorite_color></p>
</dtml-with>

Seções têm um pletora de parâmetros de configuração adicional e padrões de uso. Para informações
futuras sobre a interface de programação da aplicação de seção, veja o sistema de ajuda do Zope. Para
um exemplo adicional de uso de seção. veja o exemplo do "shopping cart" que vem com o Zope 2.5 e
acima (na pasta Exemplos).

Usando Versões
Objetos Version (Versão) ajudam a coordenar o trabalho de muitas pessoas no mesmo conjunto de
objetos. Enquanto você está editando um documento, alguém pode estar editando outro documento ao

41 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

mesmo tempo. Em um site grande no Zope centenas ou até mesmo milhares de pessoas podem estar
usando o Zope simultaneamente. A maior parte do tempo isso trabalha bem, mas problemas podem
ocorrer. Por exemplo, duas pessoas poderiam editar o mesmo documento ao mesmo tempo. Quando a
primeira pessoa termina suas modificações elas são salvas no Zope. Quando a segunda pessoa termina
suas modificações elas sobrescrevem as modificações da primeira pessoa. Você pode trabalhar sempre
com este problema usando Undo e History, mas isto pode continuar sendo um problema. Para resolver
este problema, o Zope tem objetos Version.

Outro problema que você pode encontrar é que você pode querer fazer algumas mudanças, mas você
pode não querer que elas fiquem públicas até que elas estejam terminadas. Por exemplo, suponha que
você queira mudar a estrutura do menu do seu site. Você não quer trabalhar nestas mudanças enquanto
as pessoas estiverem usando seu site porque isto pode quebrar o sistema de navegação
temporariamente enquanto você estiver trabalhando.

Versões são um modo de fazer mudanças privadas no Zope. Você pode fazer mudanças em muitos
documentos diferentes sem que outras pessoas as vejam. Quando você decide que terminou tudo você
pode escolher publicar as suas mudanças, ou descartá-las. Você pode trabalhar em uma Versão quanto
tempo você quiser. Por exemplo, pode levar uma semana para pôr os toque finais em seu novo sistema
de menu. Quando você terminar você pode publicar todas as suas mudanças liberando (commiting) a
versão.

Crie uma Versão escolhendo Version da lista de adição de produtos. Você deveria ser levado a um
formulário de adição. Dê para sua Versão o id MyChanges e clique o botão Add. Agora você criou uma
versão, mas você ainda não está usando-a. Para usar sua versão Clique nela. Você deve estar na tela
Join/Leave de sua versão como mostra a Figura 3.8.

Figura 3.8 - Ativando uma Versão

A Versão está lhe dizendo que você não está usando-a atualmente. clique no botão Start Working in
MyChanges. Agora o Zope deveria lhe falar que você está trabalhando em uma versão. Agora volte ao
folder raiz. Observe que em todos os lugares que você vai você vê uma mensagem pequena no topo da
tela que diz You are currently working in version /MyChanges. Esta mensagem faz você ver que
qualquer mudança que você faça neste ponto não será publicada, mas será armazenada em sua versão.
Por exemplo, crie um novo DTML DOcument chamado new. Note como ele tem um pequeno diamante
vermelho depois de seu id. Agora edite seu método standard_html_header. Adicione uma linha nele
como esta:

<HTML>
<HEAD>
<TITLE><dtml-var title_or_id></TITLE>
</HEAD>

42 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<BODY BGCOLOR="#FFFFFF">
<H1>Changed in a Version</H1>

Qualquer objeto que você cria ou edita enquanto estiver trabalhando em uma versão serão marcados
com um diamante vermelho. Agora volte para sua versão e clique no botão Quit working in MyChanges.
Agora tente retornar ao documento new. Observe que o documento que você criou enquanto estava em
sua versão desapareceu. Qualquer outra mudança que você fez na versão também desapareceu. Note
como seu método standard_html_header tem agora um pequeno diamante vermelho e um símbolo de
fechadura depois dele. Isto indica que este objeto foi mudado em uma versão. Mudar um objeto em uma
versão deixa-a trancada, assim ninguém mais pode mudá-la até que você libere (commit) ou descarte as
mudanças que você fez em sua versão. Trancar assegura que suas mudanças de versão não
sobrescrevam mudanças que outras pessoas fizeram enquanto você estava trabalhando em uma versão.
Assim, por exemplo, se você quer ter certeza de que só você está trabalhando em um objeto em um
determinado momento você pode mudá-lo em uma versão. Além de proteger você de mudanças
inesperadas, trancar uma versão também faz coisas inconvenientes se você quiser editar algo que está
trancado por outra pessoa. É uma boa idéia limitar seu uso de versões para evitar trancar outras
pessoas impossibilitando-as de fazer mudanças nos objetos.

Agora retorne para sua versão dando um click nela e então clicando no botão Start working in
MyChanges. Note como tudo retorna para o jeito que estava quando você deixou a Versão. Neste
momento vamos deixar suas mudanças permanentes. Vá até a tela Save/Discard como mostra a Figura
3.9.

Figura 3.9 - Liberando Mudanças da Versão

Entre com um comentário como este This is a test no campo de comentário e clique o botão Save. Suas
mudanças estão públicas agora, e todos os objetos que você mudou em sua Versão estão agora
destrancados. Note que você ainda está trabalhando em sua Versão. Vá para a tela Join/Leave e clique
no botão Quit Working in MyChanges. Agora verifique se o documento que você criou em sua versão
está visível. Sua mudança no standard_html_header deverá também estar visível. Como qualquer outra
coisa no Zope você pode escolher desfazer estas mudanças se você quiser. Vá à aba Undo. Note que em
vez de muitas transações uma para cada mudança, você tem só uma transação para todas as mudanças
que você fez em sua versão. Se você desfizer a transação, todas as mudanças que você fez na versão
serão desfeitas.

Versões são uma poderosa ferramenta para colaboração de grupo. Você não precisa rodar um servidor
ativo e um servidor de teste visto que suas versões o deixam fazer experiências, avalie-as e então
deixe-as públicas quando você decidir que está tudo bem. Você não está limitado a trabalhar em uma
versão sozinho. Muitas pessoas podem trabalhar na mesma versão. Deste modo você pode colaborar
junto nas mudanças da versão, enquanto mantém as mudanças escondidas do público geral.

43 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Versões e ZCatalog

Versões não funcionam bem com ZCatalog.É por isso que versões trancam objetos quando eles são
modificados em uma versão, prevenindo mudanças fora da versão. Isto funciona bem quando as
mudanças são isoladas.

ZCatalog tem uma maneira de conectar mudanças feitas para objetos muito diferentes. É por isso que
catalogar um objeto deve, necessariamente mudar o catálogo. Objetos que automaticamente catalogam
a si mesmos quando eles são mudados propagam suas mudanças para o catálogo. Se um objeto é
mudado em uma versão, então o catálogo é mudado na versão também, trancando assim o catálogo.
Esta propriedade faz com que o catálogo e a versão se tornem inconsistentes. Como regra, versões não
deveriam ser usadas em aplicações que usam o catálogo.

Aumentando a Performance com o Cacheamento


Uma cache é um lugar temporário para armazenar informações que você freqüentemente acessa. A
razão para usar uma cache é a velocidade. Qualquer tipo de conteúdo dinâmico, como uma página
DTML ou um Script Python, deve ser avaliado cada vez que ele for chamado. Para páginas simples ou
scripts rápidos, isto não é normalmente um problema. Para páginas em DTML muito complexas ou
scripts que fazem muitos cálculos ou chamadas a servidores remotos, o acesso àquelas páginas ou aos
scripts poderia levar mais do que uma quantia trivial de tempo. Ambos DTML e Python podem adquirir
este complexo, especialmente se você usa muitos loops (como a tag in ou loops for em Python) ou se
você chama muitos scripts, que em troca chamam muitos scripts, e assim por diante. Procesamentos
que consomem muitos ciclos de CPU são chamados de caros.

A cache pode adicionar muita velocidade a seu site, chamando uma página cara ou script uma vez e
armazenando o resultado daquela chamada de forma que possa ser reusada. A primeira pessoa a
chamar aquela página terá o tempo de resposta lento habitual, entretanto uma vez o valor do cálculo
sendo armazenado na cache, todos os usuários subsequentes que chamarão aquela página terão um
tempo muito rápido de resposta porque eles estão obtendo a cópia cacheada do resultado e não
realmente indo ao mesmo cálculo caro do primeiro usuário.

Para dar-lhe uma idéia de como as caches podem melhorar a velocidade do seu site, imagine que você
está criando www.zopezoo.org, e que a primeira página do seu site é muito complexa. Suponhamos que
esta página tenha cabeçalhos complexos, rodapés, buscas em diversas tabelas de banco de dados
diferentes, e chame vários scripts especiais que analisam gramaticalmente os resultados das buscas no
banco de dados de maneira complexa. Toda vez que um usuário vem ao www.zopezoo.org, Zope deve
executar esta página muito complexa. Com a finalidade de demonstração, suponhamos que esta página
complexa leve meio segundo, ou 500 milissegundos, para computar.

Levando em consideração que leva a metade de um segundo para executar esta página principal fictícia
complexa, sua máquina só pode servir realmente 120 hits por minuto. Na realidade, este número seria
provavelmente ainda mais baixo do que isto, porque o Zope tem que fazer outras coisas além de apenas
servir esta página principal. Agora, imagine que você configurou esta página para ser cacheada.
considerando que nenhum dos cálculos caros precisem ser feitos para mostrar a cópia cacheada da
página, muito mais usuários podem ver a página principal. Se ela leva, por exemplo, 10 milésimos de
segundo para mostrar a página cacheada, então esta página está sendo servida 50 vezes mais rápida
para os visitantes da sua página. O desempenho atual da cache e do Zope depende muito de seu
computador e sua aplicação, mas este exemplo lhe dá uma idéia de como cachear pode acelerar bastante
o seu site na web. Há algumas desvantagens para cachear:

Tempo de vida da cache

44 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Se páginas forem cacheadas por muito tempo, elas podem não refletir a informação mais atual em seu
site. Se você tiver informação que muda muito depressa, cachear pode esconder a informação nova de
seus usuários porque a cópia cacheada contém a informação velha. O tempo que um resultado
permanece cacheado é chamado de tempo de vida da informação da cache.

Informação pessoal

Muitas páginas da web podem ser personalizadas por um usuário particular. Obviamente, cachear esta
informação e mostrá-la a outro usuário seria ruim devido a preocupação com a privacidade, e porque o
outro usuário não estaria adquirindo informações sobre eles, eles estariam adquirindo isto por outra
pessoa. Por isto, cachear não é usado para informação personalizada.

O Zope lhe permite passar por estes problemas setando uma política de cache. A política de cache lhe
permite controlar como o conteúdo consegue ser cacheado. Políticas de cache são controladas através
de objetos Cache Manager (Gerenciador de Cache).

Adicionando um Gerenciador de Cache

Os Gerenciadores de Cache podem ser adicionados como qualquer outro objeto do Zope. Atualmente o
Zope vem com dois tipos de Gerenciadores de Cache:

Acelerador de Gerenciador de Cache HTTP

Um Acelerador de Gerenciador de Cache HTTP lhe permite controlar um servidor de cache HTTP que é
externo ao Zope, por exemplo, Squid. O HTTP Acelerador de Gerenciador de Cache HTTP não faz o
cacheamento, mas de preferência configura cabeçalhos especiais HTTP que dizem a um servidor de
cache externo o que cachear. Configurar um servidor de cache externo como o Squid está além do alvo
deste livro, veja o site do Squid para mais detalhes.

(RAM) Gerenciador de Cache

O Gerenciador de Cache da RAM é um gerenciador de cache do Zope que cacheia o conteúdo dos
objetos na memória do seu computador. Ele faz isto muito rápido, mas também faz com que o Zope
consuma mais da memória do seu computador. O Gerenciador de Cache de RAM não requer nenhum
recurso externo como um servidor Squid, para trabalhar.

Para este exemplo, crie um Gerenciador de Cache de RAM no folder raiz chamado CacheManager. Este
vai ser o objeto gerenciador de cache para todo o seu site.

Agora, você pode clicar no CacheManager e ver sua tela de configuração. Há vários elementos nesta
tela:

Title

O title (título) do gerenciador da cache. Isto é opcional.

Variáveis REQUEST

Esta informação é usada para armazenar a cópia cacheada de uma página. Esta é uma característica
avançada, agora, você pode deixar isto setado para apenas "AUTHENTICATED_USER".

Threshold Entries

Quantos objetos serão cacheados pelo gerenciador da cache em uma vez.

Intervalo de Cleanup

45 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

O tempo de vida dos resultados cacheados.

Por enquanto, deixe todas estas entradas como estão, elas estão boas, padões razoáveis. Isto é tudo
para setar um gerenciador da cache!

Há algumas abas no gerenciador da cache que você pode achar útil. A primeira é a aba Statics. Esta aba
mostra a você o número de "ganhos" e "perdas" da cache para mostrar como a sua cache é eficiente.

Existe também uma aba Associate que lhe permite associar um tipo específico ou tipos de objetos do
Zope com um particular gerenciador da cache. Por exemplo, você pode querer que o seu gerenciador da
cache cacheie somente DTML Documents. Você pode mudar estas configurações na aba Associate.

Neste ponto, nada é cacheado ainda, você apenas criou um gerenciador da cache. A próxima seção
explica como você pode cachear os conteúdos de documentos atuais.

Cacheando um Documento

Cachear um documento é muito fácil. Primeiro, antes de você cachear um documento você deve ter um
gerenciador da cache como aquele que você criou na seção anterior.

Para cachear um documento, crie um novo objeto DTML Document no folder raiz chamando Weather.
Este objeto conterá um pouco de informação sobre o tempo. Por exemplo, vamos dizer que ele contém:

<dtml-var standard_html_header>
<p>Yesterday it rained.</p>
<dtml-var standard_html_footer>

Agora, clique no DTML Document Weather e clique em sua aba Cache. Esta aba o deixa associar este
documento com um gerenciador da cache. Se você olhar na caixa de seleção no topo da aba, você verá o
gerenciador da cache que você criou na seção anterior, CacheManager. Selecione isto como o
gerenciador da cache para Weather.

Agora, todos que visitarem o documento Weather, adquirirão a cópia cacheada. Para um documento tão
trivial quanto nosso exemplo Weather, não há muito proveito. Mas imagine por um momento que
Weather contivesse algumas buscas no banco de dados. Por exemplo:

<dtml-var standard_html_header>
<p>Yesterday's weather was <dtml-var yesterdayQuery></p>
<p>The current temperature is <dtml-var currentTempQuery></p>
<dtml-var standard_html_footer>

Suponhamos que aquele yesterdayQuery e currentTempQuery são SQL Methods que pesquisam um
banco de dados para a previsão de ontem e a temperatura atual, respectivamente (para mais informação
sobre SQL Methods, veja Capítulo 10). Também suponhamos que a informação no banco de dados só
muda uma vez a cada hora.

Agora, sem cachear, o documento Weather pesquisaria o banco de dados toda vez que ele fosse visto. Se
o documento Weather fosse visto centenas de vezes em uma hora, então todas essas centenas de
pesquisas sempre conteriam a mesma informação.

Se você especificar que o documento deve ser cacheado, então o documento fará somente a pesquisa
quando a cache expirar. O tempo padrão da cache é 300 segundos (5 minutos), assim setar este
documento para ser cacheado economizará 91% de suas pesquisas ao banco de dados, fazendo somente
um doze avos de freqüência. Há um problema com este método, há uma chance que os dados podem
ficar obsoletos cinco minutos, mas isto é normalmente um termo aceitável.

46 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Para mais informação sobre cachear e usar as opções mais avançadas de cacheamento, veja o Guia do
Administrador do Zope.

Hospedagem Virtual de um Objeto


O Zope vem com três objetos que o ajudam a fazer hosting virtual, SiteRoot, Set Access Rule, e Virtual
Host Monster. Hospedagem Virtual é uma maneira de servir muitos sites da web com um servidro Zope.
Hospedagem virtual é uma função de administração avançada, que está além do escopo deste livro. Veja
o Guia do Administrador do Zope para mais informação sobre hospedagem virtual.

Enviando mail com MailHost


O Zope vem com um objeto que é usado para enviar e-mail, geralmente junto com a tag sendmail dae
DTML, melhor descrita no Capítulo 7.

Mailhosts podem ser usados tanto do Python ou DTML para enviar uma mensagem de e-mail pela
Internet. Eles são úteis como gateways para o mundo. Cada objeto mailhost é associado a um servidor
de email, por exemplo, você pode associar um objeto mailhost com yourmail.yourdomain.com que seria
seu servidor de email SMTP. Quando você associa um servidor com um objeto mailhost, o objeto
mailhost sempre usará aquele servidor para enviar mensagens.

Para criar um objeto mailhost selecione MailHost da lista de adição. Você pode ver que o id padrão é
"MailHost" e o servidor SMTP padrão e porta são "localhost" e "25". Certifique-se que sua máquina
localhost está rodando um servidor de email, ou mude localhost para ser o nome de seu servidor SMTP
de partida.

Agora você pode usar o novo objeto MailHost de uma tag sendmail da DTML. Isto é explicado com mais
detalhes no Capítulo 7. O API para objetos MailHost também lhe permite enviar email de scripts
Python. Para mais informação, veja o sistema de ajuda on-line.

5. Conteúdo Dinâmico com DTML


Este capítulo introduz DTML, linguagem de script baseada em tags do Zope. Nele
descrevemos o uso da DTML em modelos e scripts e seu lugar em relação a outras
maneiras de utilizar script no Zope. Mostraremos a sintaxe DTML e as três tags básicas,
var, if e in. Depois de ler este capítulo você será capaz de criar páginas dinâmicas para a
web.

DTML (Document Template Markup Language) é a linguagem de apresentação e script baseada em tag
do Zope. A DTML gera dinamicamente, controla e formata o conteúdo. DTML é geralmente usada para
construir interfaces modulares e dinâmicas para suas aplicações para a web.

DTML é uma linguagem script do lado do servidor, como SSI, PHP, ASP, e JSP. Isto significa que os
comandos DTML são executados pelo Zope no servidor, e o resultado daquela execução é enviada para
seu browser. Ao contrário, as linguagens script do lado do cliente como Javascript não são processadas
pelo servidor, mas são, ao contrário, enviadas e executadas por seu browser.

Você pode usar scripts DTML em dois tipos de objetos no Zope, DTML Documents e DTML Methods.

Para Quem é o DTML?


DTML é designada para pessoas familiarizadas com o HTML e scripts básicos para a web, não para

47 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

programadores de aplicação. De fato, se você quer programar com o Zope você não deveria usar DTML.
No Capítulo 8, "Scripts Avançados no Zope", mostraremos programação avançada usando Python e
Perl.

DTML é para apresentação e deveria ser gerenciada por web designers. O Zope encoraja você a manter
sua apresentação e lógica separadas oferecendo diferentes objetos para apresentação (DTML), e lógica
(Python, Perl, e outras). Você encontrará muitos benefícios resultantes da criação de sua apresentação
em DTML e sua lógica em outros tipos de objetos do Zope. Alguns desses benefícios incluem:

Manter a lógica e a apresentação separadas faz com que seja fácil modificar componentes sem
interromper outros.
Frequentemente você vai ter diferentes pessoas responsáveis para manter a lógica e a
apresentação. Usando diferentes objetos para estas tarefas você faz isto ficar mais fácil para as
pessoas colaborarem sem interromper outros.
É fácil de reusar componentes de apresentação e lógia existentes se eles não estiverem
misturados.

Para Que o DTML é Bom?


DTML é bom para criação dinâmica de interfaces para a web. Suporta reuso de conteúdo e layout,
formatação de dados heterogêneos, e separação da apresentação da lógica e dados.

Por exemplo, com DTML você pode reusar cabeçalhos e rodapés compartilhados de páginas da web:

<dtml-var standard_html_header>
<p>Hello world.</p>
<dtml-var standard_html_footer>

Esta página da web mistura HTML e DTML. Comandos DTML são escritos como tags que começam com
dtml-. Este exemplo constrói uma página para a web inserindo um cabeçalho e rodapé padrão em uma
página HTML. A página HTML resultante deveria se parecer com algo assim:

<html>

<body bgcolor="#FFFFFF">

<p>Hello world.</p>

<hr>

<p>Last modified 2000/10/16 by AmosL</p>

</body>

</html>

Como você pode ver o cabeçalho padrão definiu uma cor branca de fundo e o rodapé padrão adicionou
uma observação na parte inferior da página dizendo quando a página foi modificada pela última vez e
por quem.

Além disso, para reusar o conteúdo, a DTML deixa você facilmete e poderosamente formatar todos os
tipos de dados. Você pode usar DTML para chamar métodos, pesquisas a banco de dados, inserir
objetos no Zope, processar formulários, e mais.

Por exemplo, quando você pesquisa em um banco de dados com um SQL Method ele tipicamente
retorna uma lista de resultados. Aqui está a maneira como você poderia usar a DTML para formatar
cada resultado da pesquisa ao banco de dados:

48 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<ul>

<dtml−in frogQuery>

<li><dtml−var animal_name></li>

</dtml−in>

</ul>

A tag DTML in interage nos resultados da pesquisa ao banco de dados e formata cada resultado.
Suponha que quatro resultados são retornados pelo frogQuery. Aqui está a maneira como o HTML
resultante deveria se parecer:

<ul>

<li>Fire-bellied toad</li>

<li>African clawed frog</li>

<li>Lake Nabu reed frog</li>

<li>Chilean four-eyed frog</li>

</ul>

Os resultados da pesquisa ao banco de dados são formatados como uma lista em HTML.

Observe que você não tem que dizer a DTML que você está pesquisando um banco de dados e você não
tem que dizer a ela onde achar os argumentos para chamar a pesquisa do banco de dados. Você apenas
diz a ela qual objeto chamar, ela fará o trabalho de compreender como chamar o objeto e passar a ele
argumentos apropriados. Se você recolocar o SQL Method frogQuery com algum outro tipo de objeto,
como um Script, um ZCatalog, ou até mesmo outro DTML Method, você não terá que mudar a maneira
que você formata os resultados.

Esta capacidade de formatar todos os tipos de dados faz da DTML uma poderosa ferramenta de
apresentação, e deixa você modificar sua lógica de aplicação sem mudar sua apresentação.

Quando não se Deve Usar o DTML


DTML não é uma linguagem de programação com objetivo comum. Por exemplo, DTML não permite
que você crie variáveis muito facilmente. Embora seja possível implementar algoritmos complexos em
DTML, isto é penoso e não recomendado. Se você quer implementar lógica de programação, use Python
ou Perl (para mais informação sobre estes assuntos, veja o Capítulo 8).

Por exemplo, vamos supor que você escreveu uma simples página para a web para um grupo de
estudantes de matemática, e naquela página você quis ilustrar um cálculo simples. Você não queria
escrever o programa que faz este cálculo em DTML. Isto pode ser feito em DTML, mas seria difícil de
entender. DTML seria perfeita para descrever a página que este cálculo está inserido, mas seria terrível
fazer este cálculo em DTML, enquanto que isto pode ser mais simples e trivial em Python ou Perl.

Processamento de string é outra área onde o DTML não é a melhor escolha. Se você quer manipular
entradas de um usuário de uma maneira complexa, mas usando funções que manipulam strings, seria
melhor fazer isto em Python ou Perl, ambos têm muito mais habilidades poderosas com o
processamento de string que a DTML.

DTML é uma ferramenta entre muitas disponíveis no Zope. Se você acha que você se escabelaria
tentando compreender algumas construções complicadas em DTML, aqui está uma boa chance de que

49 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

coisas trabalhariam melhor se você quebrasse seu script DTML em uma coleção de Scripts baseados em
DTML e Python ou Perl.

Sintaxe da Tag DTML


A sintaxe da DTML é similar a do HTML. DTML é uma linguagem de marcação baseada em tag. Em
outras palavras DTML usa tags para fazer seu trabalho. Aqui temos um simples fragmento de DTML:

<dtml-var standard_html_header>

<h1>Hello World!</h1>

<dtml-var standard_html_footer>

Este código DTML contém duas tags var da DTML e algum HTML. As tags h1 são HTML, não DTML.
Você geralmente mistura a DTML com outra linguagem de marcação como o HTML. Normalmente a
DTML é usada para gerar HTML, mas não há nada segurando você para gerar outros tipos de texto.
Como você verá mais tarde você pode também usar DTML para gerar mensagens de email e outras
informações textuais.

DTML Contém dois tipos de tags, tags simples e blocos. Tags simples consistem de uma tag entre
símbolos de menor que (<) e maior que (>). symbols. A tag var é um exemplo de uma tag simples:

<dtml-var parrot>

Não há necessidade de fechar a tag var.

Tags em blocos consistem de duas tags, uma que abre o bloco e outra que fecha o bloco, e o conteúdo
que vai entre elas:

<dtml-in mySequence>

<!-- this is an HTML comment inside the in tag block -->

</dtml-in>

A tag de abertura começa o bloco e a tag de fechamento termina-a. A tag de fechamento tem o mesmo
nome da tag de abertura precedida de uma linha. Esta é a mesma convenção que o HTML e XML usam.

Usando os Atributos da Tag DTML

Todas as tags da DTML têm atributos. Um atributo oferece informação sobre como a tag trabalha.
Alguns atributos são opcionais. Por exemplo, a tag var insere o valor de uma variável. Ela tem um
atributo missing que especifica um valor padrão no caso da variável não ser encontrada:

<dtml-var wingspan missing="unknown wingspan">

Se a variável wingspan não for encontrada então unknown wingspan é inserido no lugar.

Alguns atributos não têm valores. Por exemplo, você pode converter uma variável inserida para
maiúsucla com o atributo upper.

<dtml-var exclamation upper>

50 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Observe que o atributo upper, ao contrário do atributo missing não precida de um valor.

Diferentes tags têm diferentes atributos. Veja o Apêndice A, "Referência ao DTML", para mais
informação sobre a sintaxe de diferentes tags DTML.

Inserindo Variáveis com DTML


Inserir uma variável é a tarefa mais básica que você pode executar com a DTML. Você já viu como a
DTML insere cabeçalho e rodapé nas páginas web com a tag var. Muitas tags DTML inserem variáveis, e
elas tabém fazem isto de uma maneira parecida. Vamos olhar mais de perto o modo como o Zope insere
variáveis.

Suponha que você tem um folder cujo id é Feedbags que tem o title (título) "Bob's Fancy Feedbags".
Dentro do folder crie um DTML Method com o id pricelist. Então mude o conteúdo do DTML Method
para o seguinte:

<dtml-var standard_html_header>
<h1>Price list for <dtml-var title></h1>
<p>Hemp Bag $2.50</p>
<p>Silk Bag $5.00</p>
<dtml-var standard_html_footer>

Agora visualize o DTML Method clicando na aba View. Você deveria ver uma página HTML cujo código
se parece com isto:

<html>
<body>
<h1>Price list for Bob's Fancy Feedbags</h1>
<p>Hemp Bag $2.50</p>
<p>Silk Bag $5.00</p>
</body>
</html>

Isto é o que você deveria basicamente esperar. O Zope insere um cabeçalho, um rodapé, e um título na
página da web. A DTML obtém os valores destas variáveis de vários lugares diferentes. Primeiro, a tag
var tenta achar uma variável no objeto corrente. Então ela olha no repositório do objeto corrente. Então
ela olha no pedido da web (formulários e cookies). Se o Zope não pode achar uma variável então ele cria
uma excessão, e ele pára de executar a DTML.

Vamos seguir passo a passo este código DTML para ver onde as variáveis são encontradas. Primeiro o
Zope olha para o standard_html_header no objeto corrente, que é o DTML Method pricelist. Depois,
Zope olha para o caceçalho no repositório do objeto corrente. O folder Feedbags não tem nenhum
método ou propriedade ou sub-objetos com aquele nome. Depois o Zope exemina o repositório do
folder Feedbags, e assim por diante até que ele obtenha do folder raiz. O folder raiz tem um sub-objeto
chamado standard_html_header. O objeto cabeçalho é um DTML Method. Assim o Zope chama o
método cabeçalho e insere os resultados.

Depois o Zope olha para a variável title. Aqui, a pesquisa é um pouco pequena. Primeiro, ele olha no
DTML Method pricelist, que não tem um título, assim o Zope foi adiante e achou o título do folder
Feedbags e inseriu-o.

Finalmente o Zope olha para a variável standard_html_footer. Ele tem que pesquisar todo o caminho
acima até o folder raiz para achá-lo, somente ai que ele olha para standard_html_header.

51 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Este exercício pode parecer um pouco tedioso, mas enter como o Zope olha para cima é muito
importante. Por exemplo, algumas noções importantes de como o Zope olha para as variáveis incluem
como os objetos do Zope podem obter conteúdo e comportamento de seus pais, e como o conteúdo
definido em um local pode ser reusado por muitos objetos.

Processando Entradas Através dos Formulários


É fácil processar formulários com o Zope. A DTML procura variáveis para inserir em vários locais,
incluindo informação que vem da ação submit dos formulários HTML. Você não precisa de nenhum
objeto especial, DTML Documents e DTML Methods farão o trabalho.

Crie dois DTML Documents, um com o id infoForm e outro com o id infoAction. Agora edite os
conteúdos dos documentos. Aqui está os conteúdos do documento infoForm:

<dtml-var standard_html_header>
<p>Please send me information on your aardvark adoption program.</p>
<form action="infoAction">
name: <input type="text" name="user_name"><br>
email: <input type="text" name="email"><br>
<input type="submit">
</form>
<dtml-var standard_html_footer>

Agora visualize este documento. Ele é um formulário web que pede informação e envia-a para o
documento infoAction quando você dá um submit no formulário.

Agora edite os conteúdos do documento infoAction para fazer com que ele processe o formulário:

<dtml-var standard_html_header>
<h1>Thanks <dtml-var user_name></h1>
<p>We received your request for information and will send you
email at <dtml-var email> describing our aardvark adoption
program as soon as it receives final governmental approval.
</p>
<dtml-var standard_html_footer>

Este documento mostra uma mensagem de agradecimento que inclui a informação do nome e email
recolhidas do formulário web.

Agora volte ao documento infoForm, visualize-o, preencha o formulário e dê um submit nele. Se tudo
correr bem você poderia ver uma mensagem de agradecimento que inclui o nome e o endereço de email.

O documento infoAction encontra a informação do formulário do request da web que aconteceu quando
você clicou no botão submit no infoForm. Como mencionamos na última sessão, a DTML procura
variáveis em alguns lugares, um destes é o request da web, assim não há nada de especial que você
precise para abilitar seus documento para processar formulários web.

Vamos fazer uma experiência. O que acontece se você tentar visualizar o documento infoAction
diretamente, como oposto para recebê-lo do documento infoForm. Clique no documento infoAction e
então clique na aba View como mostra a Figura 4.1.

52 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 4.1 - Erro da DTML resultante da falha na procura de uma variável.

O Zope não poderia achar a variável user_name considerando que ela não estava no objeto corrente, seu
repositório ou o request da web. Este é um erro que você provavelmente vê frequentemente quando
aprende Zope. Não tenha medo, isto apenas significa que você tentou inserir uma variável que o Zope
não pode encontrar. Neste exemplo, você precisa inserir uma variável que o Zope pode encontrar, ou
usar o atributo missing na tag var como descrito acima:

<h1>Thanks <dtml-var user_name missing="Anonymous User"></h1>

Entender onde o Zope procura as variáveis ajudará você a compreender como determinar este tipo de
problema. Neste caso, você visualizou um documento que precisa ser chamado de um formulário HTML
como infoForm para oferecer variáveis a serem inseridas na saída.

Adquirindo Conteúdo Dinamicamente


O Zope procura as variáveis da DTML no repositório do objeto corrente se ele não encontra a variável
primeiro no objeto corrente. Este comportamento permite que seus objetos achem e usem comteúdo e
comportamento definidos em seus pais. O Zope usa o termo aquisição para se referir a este uso
dinâmico de conteúdo e comportamento.

Agora que você viu como a estrutura do site se ajusta à maneira que os nomes são procurados, você
pode começar a entender que é muito importante saber onde você coloca os objetos para procurá-los
depois.

Um exemplo de aquisição que você já viu é como as páginas da web usam os cabeçalhos e rodapés
padrão. Para adquirir o cabeçalho padrão apenas peça ao Zope par inserí-lo com a tag var:

<dtml-var standard_html_header>

Não importa onde seu DTML Method ou Document está localizado. O Zope irá procurar para cima até
encontrar o standard_html_header que é definido no folder raiz.

Você pode levar vantagem na maneira como o Zope procura as variáveis para adaptar seu cabeçalho em
diferentes partes de seu site. Apenas crie um novo standard_html_header em um folder e it will ele irá
se impor ao cabeçalho global em todas as páginas web em seu folder e abaixo dele.

Crie um folder no folder raiz com um id Green. Entre no folder Green e crie um DTML Document com
um id welcome. Edite o documento welcome para ter este conteúdo:

<dtml-var standard_html_header&glt;

53 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<p>Welcome</p>
<dtml-var standard_html_footer>

Agora visualize o documento welcome. Ele deveria se parecer como uma simples página web com a
palavra welcome, como mostra a Figura 4.2.

Figura 4.2 - Documento Welcome.

Agora vamos adaptar o cabeçalho para o folder Green. Crie um DTML Method no folder Green com o id
standard_html_header. Então edite o conteúdo do cabeçalho para o seguinte:

<html>
<head>
<style type="text/css">
body {color: #00FF00;}
p {font-family: sans-serif;}
</style>
</head>
<body>

Observe que esta não é uma página web completa. Este é apenas um fragmento do HTML que pode ser
usado como um cabeçalho. Este cabeçalho usa CSS (Cascading Style Sheets) para fazer algumas
mudanças ao layout da sua página web.

Agora volte ao documento welcome e visualize-o novamente, como mostra a Figura 4.3.

Figura 4.3 - Documento Welcome com o cabeçalho adaptado.

O documento agora se parece bem diferente. Isto é porque ele está usando agora o novo cabeçalho que

54 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

introduzimos no folder Green. Este cabeçalho será usado por todas as páginas da web no folder Green e
em seus sub-folders.

Você pode continuar este processo de overriding conteúdo padrão criando outro folder dentro do folder
Green e criando um DTML Method standard_html_header aqui. Agora as páginas no sub-folder usarão
seus cabeçalhos padrão ao invés do cabeçalho do folder Green. Usando este padrão você pode mudar
rapidamente o layout de diferentes partes do seu site. Se você decidir mais tarde que uma área do site
precisa de um cabeçalho diferente, apenas crie um. Você não tem que mudar a DTML em nenhuma das
páginas; elas automaticamente acharão o cabeçalho mais perto e usá-lo.

Usando Expressões Python pelo DTML


Anteriormente olhamos simples tags DTML. Aqui temos um exemplo:

<dtml-var getHippo>

Esta tag irá inserir o valor da variável chamada getHippo, seja o que for. DTML cuidará
automaticamente dos detalhes, como achar a variável e chamá-la. Chamamos esta básica sintaxe da tag
name para diferenciá-la da sintaxe expression.

Expressões DTML lhe permitem ser mais explícito sobre como achar e chamar variáveis. Expressões são
atributos da tag que contêm pedaços de código na linguagem Python. Por exemplo, ao invés de deixar a
DTML achar e chamar o getHippo, podemos usar uma expressão para explicitamente passar
argumentos:

<dtml-var expr="getHippo(with a large net)">

Aqui usamos uma expressão em Python para explicitamente chamar o método getHippo com o
argumento string, with a large net. Para saber mais sobre sintaxe do Python, veja o Tutorial do Python
no site Python.org. Muitas tags DTML podem usar atributos de expressão.

Expressões fazem com que o DTML seja poderoso. Por exemplo, usando expressões em Python, vcê
pode facilmente testar condições:

<dtml-if expr="foo < bar">


Foo is less than bar.
</dtml-if>

Sem expressões, esta tarefa simples teria que ser quebrada em um método separado e teria que
adicionar muita sobrecarga para algo trivial.

Antes de você usar as expressões, tome cuidado. Expressões podem deixar seu DTML difícil de
entender. Código que é difícil de entender é mais passível de conter erros e é mais difícil de fazer
manutenção. Expressões também podem levar a misturar lógica em sua apresentação. Se você se pegar
olhando para uma expressão mais que cinco segundos, pare. Reescreva a DTML sem a expressão e use
um Script para fazer sua lógica. Somente porque você pode fazer coisas complexas com DTML isto não
significa que você poderia.

Pegadinhas das Expressões DTML

Usar expressões Python pode ser traiçoeiro. Um erro comum é confundir expressões com a sintaxe
básica da tag. Por exemplo:

<dtml-var objectValues>

55 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

e:

<dtml-var expr="objectValues">

no final darão a você dois resultados completamente diferentes. O primeiro exemplo da tag var da
DTML irá automaticamente passar variáveis. Em outras palavras ele vai tentar fazer a coisa certa para
inserir sua variável, não importando o que a variável pode ser. No geral isto significa que se a variável é
um método ele será chamado com os argumentos apropriados. Este processo é mostrado mais a fundo
no Capítulo 8, "Variáveis e Avançado DTML".

Em uma expressão, você tem completo controle sobre a variável passada. No caso do nosso exemplo,
objectValues é um método. Assim:

<dtml-var objectValues>

chamará o método. Mas:

<dtml-var expr="objectValues">

não chamará o método, ele vai apenas inserí-lo. O resultado não será uma lista de objetos mas uma
string como <Python Method object at 8681298>. Se você já viu resultados como este, há uma boa
chance de você estar retornando um método, ao invés de estar chamando-o.

Para chamar um método de uma expressão, você deve usar a sintaxe de chamada padrão do Python
usando parênteses:

A lição é que se você usa expressões Python você deve saber que tipo de variável você está inserindo e
deve usar a própria sintaxe do Python para apropriadamente passar a variável.

Antes de deixarmos o subject das expressões da variável deveriamos mencionar que há um formulário
deprecated da sintaxe da expressão. Você pode tirar a parte "expr=" em uma tag de expressão da
variável. Mas por favor não faça isto. É muito fácil confundir:

<dtml-var aName>

com:

<dtml-var "aName">

e obter dois resultados completamente diferentes. Estes modos suscintos foram construídos em DTML
a um tempo atrás, mas nós não encorajamos você a usá-los agora a menos que você esteja preparado
para aceitar a confusão e o debug dos problemas que advêm desta sutil diferença na sintaxe.

A Tag Var
A tag var insere variáveis em DTML Methods e Documents. Nós já vimos muitos exemplos de como a
tag var pode ser usada para inserir strings dentro de páginas para a web.

Como você já viu, a tag var procura variáveis primeiro no objeto corrente, depois em seu repositório e
finalmente no request da web.

A tag var pode também usar expressões do Python para oferecer mais controle na localização e
chamada das variáveis.

Atributos da Tag Var

56 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Você pode controlar o comportamento da tag var usando seus atributos. A tag var tem muitos atributos
que ajudam você em situações comuns de fomatação. Os atributos estão resumidos no Apêndice A. Aqui
temos uma amostra dos atributos da tag var.

html_quote

Este atributo faz com que os valores inseridos sejam postos entre aspas. Isto significa que <, > e & são
aproveitados.

missing

O atributo missing lhe permite especificar um valor padrão para usar no caso do Zope não poder achar a
variável. Por exemplo:

<dtml-var bananas missing="We have no bananas">

fmt

O atributo fmt lhe permite controlar o formato da saída das tags var. Existem muitos formatos possíveis
que são detalhados no Apêndice A.

Um uso do atributo fmt é formatar valores monetários. Por exemplo, crie uma propriedade float em seu
folder raiz chamada adult_rate. Esta propriedade representará o custo que um adulto terá para visitar
o Zoo. Dê a esta propriedade o valor 2.2.

Você pode mostrar este custo em um DTML Document ou Method assim:

One Adult pass: <dtml-var adult_rate fmt=dollars-and-cents>

Isto fará com que imprima corretamente "$2.20". Ele arredondará mais precisamente números
decimais ao centavo mais próximo.

Sintaxe de Entidade da Tag Var

Zope oferece uma sintaxe suscinta da DTML apenas para a simples tag var. Porque a tag var é um
acontecimento singular, ela pode ser representada com uma entidade HTML como a sintaxe:

&dtml-cockatiel;

Isto equivale a :

<dtml-var name="cockatiel" html_quote>

A principal razão em usar a sintaxe de entidade é permitir a colocação de tags DTML dentro de tags
HTML. Por exemplo, ao invés de escrever:

<input type="text" value="<dtml-var name="defaultValue">">

Você pode usar a sintaxe de entidade para fazer coisas mais legíveis para você e seu editor de texto:

<input type="text" value="&dtml-defaultValue;">

A sintaxe de entidade da tag var é muito limitada. Você não pode usar expressões do Python e alguns
atributos da tag com ela. Veja o Apêndice A para mais informação sobre a sintaxe de entidade da tag
var.

57 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

A Tag If
Um dos importantes benefícios da DTML é deixar que você adapte sua página web. Frequentemente
adaptação significa testar se as condições estão respondendo apropriadamente. Esta tag if deixa você
avaliar uma condição e transmitir diferentes ações baseadas no resultado.

O que é uma condição? Uma condição é tanto um valor falso como um verdadeiro. Em geral todos os
objetos são considerados verdadeiros a menos que eles sejam 0, None, uma sequência vazia ou uma
sring vazia.

Aqui está um Exemplo da Condição

objectValues

Verdadeiro se a variável objectValues existe e é verdadeira. Isto é, quando o processo de achar e passar
objectValues não for 0, None, uma sequência vazia, ou uma string vazia.

Com a tag var, você pode usar ambas as sintaxe do name quanto da expression. Aqui estão algumas
condições ditas como expressões DTML.

expr="1"

Sempre verdadeiro.

expr="rhino"

Verdadeiro se a variável rhino for verdadeira.

expr="x < 5"

Verdadeiro se x for menor que 5.

expr="objectValues(File)"

Verdadeiro se chamando o método objectValues com um argumento de File é retornado um valor


verdadeiro. Este método é explicado com mais detalhes neste capítulo.

A tag if é uma tag com bloco. O bloco dentro da tag if é executado se a condição for verdadeira.

Aqui temos como você poderia usar uma expressão da variável com a tag if para testar uma condição:

<p>How many monkeys are there?</p>

<dtml-if expr="monkeys > monkey_limit">

<p>There are too many monkeys!</p>

</dtml-if>

No exemplo acima, se a expressão em Python monkeys > monkey_limit for verdadeira quando você
então verá o primeiro e o segundo parágrafos do HTML. Se a condição for falsa, você verá somente o
primeiro.

Tags if podem ser postas em qualquer profundidade, por exemplo, você pode ter:

58 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<p>Are there too many blue monkeys?</p>

<dtml-if "monkeys.color == 'blue'">

<dtml-if expr="monkeys > monkey_limit">

<p>There are too many blue monkeys!</p>

</dtml-if>

</dtml-if>

Tags if dentro de outras trabalham com a avaliação da primeira condição, e se aquela condição for
verdadeira, então a segunda é avaliada. Em geral, tags DTML if trabalham como Python se forem
expressões.

Diferenças da Sintaxe de Nomes e Expressões

A sintaxe do name verifica a existência de um nome, bem como seu valor. Por exemplo:

<dtml-if monkey_house>

<p>There <em>is</em> a monkey house Mom!</p>

</dtml-if>

Se a variável monkey_house não existe, então esta condição é falsa. Se há uma variável monkey_house
mas ela é falsa, então esta condição também é falsa. A condição só é verdadeira se houver uma variável
monkey_house e ela não for 0, None, uma sequência vazia ou uma string vazia.

A sintaxe da expressão em Python não verifica a existência da variável. Isto é porque a expressão deve
ser válida em Python. Por exemplo:

<dtml-if expr="monkey_house">

<p>There <em>is</em> a monkey house, Mom!</p>

</dtml-if>

Isto funcionará como esperado assim que monkey_house existir. Se a variável monkey_house não
existe, o Zope imprimirá uma excessão KeyError quando ele tentar achar a variável.

Tags Else e Elif

A tag if somente realiza algo se a condição for verdadeira. Você poderia querer uma ação diferente se a
condição fosse falsa. Isto pode ser feito com a tag else do DTML. O bloco if pode também conter uma tag
simples else. Por exemplo:

<dtml-if expr="monkeys > monkey_limit">

<p>There are too many monkeys!</p>

<dtml-else>

<p>The monkeys are happy!</p>

</dtml-if>

A tag else divide o bloco da tag if em dois blocos, o primeiro é executado se a condição for verdadeira, o

59 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

segundo é executado se a condição não for verdadeira.

Um bloco da tag if pode também conter uma tag simples elif. A tag elif especifica outra condição apenas
como uma tag if de adição. Isto faz com que você possa especificar múltiplas condições em um bloco:

<dtml-if expr="monkeys > monkey_limit">

<p>There are too many monkeys!</p>

<dtml-elif expr="monkeys < minimum_monkeys">

<p>There aren't enough monkeys!</p>

<dtml-else>

<p>There are just enough monkeys.</p>

</dtml-if>

Um bloco da tag if pode conter várias tags elif mas somente uma tag else. A tag else sempre deve vir
deppois das tags elif. Tags elif podem testar condições usando tanto a sintaxe nome quanto a sintaxe
expressão.

Usando Cookies com a Tag If


Vamos dar uma olhada melhor no exemplo da tag if. Muitas vezes quando você recebe visitantes em seu
site você quer dar a eles um cookie para identificá-los com algum tipo de valor especial. Cookies são
usados frequentemente em toda a Internet, e quando eles são usados corretamente eles são muito
úteis.

Suponha que queremos diferenciar novos visitantes de pessoas que já estiveram em seu site. Quando
um usuário visita seu site podemos setar um cookie. Então podemos testar o cookie quando as páginas
são mostradas. Se o usuário já esteve no site ele terá o cookie. Se ele não tem o cookie ainda, isto
significa que eles são novos.

Suponha que estamos executando um especial. Primeira vez no zoo o visitante paga meia entrada. Aqui
temos um fragmento do DTML que testa o cookie usando a variável hasVisitedZoo e mostra o preço de
acordo se o usuário é novo ou um visitante repetido:

<dtml-if hasVisitedZoo>

<p>Zoo admission <dtml-var adult_rate fmt="dollars-and-cents">.</p>

<dtml-else>

<b>Zoo admission for first time visitors

<dtml-var expr="adult_rate/2" fmt="dollars-and-cents"></p>

</dtml-if>

Este fragmento testa a variável hasVisitedZoo. Se o usuário já visitou o zoo antes ele mostra o preço
normal da entrada. Se o visitante está aqui pela primeira vez eles pagam metade da entrada.

Apenas por segurança, aqui está uma implementação do método hasVisitedZoo como um Script em
Python:

60 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

## Script(Python) "hasVisitedZoo"

##parameters=REQUEST, RESPONSE

##

"""

Returns true if the user has previously visited

the Zoo. Uses cookies to keep track of zoo visits.

"""

if REQUEST.has_key(zooVisitCookie):

return 1

else:

RESPONSE.setCookie(zooVisitCookie, 1)

return 0

No Capítulo 10, "Scripts Avançados em Zope" veremos mais de perto como fazer um scrpt com lógica de
aplicação com Python e Perl. Agora isto é suficiente ver como o método procura um cookie e retorna um
valor verdadeiro ou falso dependendo se o cookie é encontrado ou não. Observe como o Python usa as
expressões if e else bem como a DTML usa as tags if e else. As tags if e else da DTML são baseadas nas
expressões do Python. De fato o Python também tem uma expressão elif, como a DTML.

A Tag In
A tag in DTML interage em uma sequência de objetos, conduzindo um bloco de execução para cada item
na sequência. Na programação, isto é frequentemente chamado interação, ou looping.

A tag in é uma tag de bloco como a tag if. O conteúdo do bloco da tag in é executado uma vez para cada
interação no loop da tag in. Por exemplo:

<dtml-in todo_list>
<p><dtml-var description></p>
</dtml-in>

Este exemplo faz um loop sobre uma lista de objetos chamada todo_list. Para cada item, ela insere um
parágrafo em HTML com uma descrição do item.

Interação é muito útil em muitas tarefas para a web. Considere que um site mostre casas para vender.
Usuários vão procurar em seu site por casas que se adaptem a certos critérios. Você vai querer formatar
todos estes resultados de uma forma consistente na página, então, você precisará interagir sobre cada
resultado e criar um bloco HTML para cada resultado.

De certa forma, os conteúdos de um bloco da tag in são um tipo de template que é aplicado uma vez
para cada item em uma sequência.

Interagindo Sobre os Conteúdos do Diretório

Aqui temos um exemplo de como interagir sobre o conteúdo de um folder. Este DTML fará um loop
sobre todos os arquivos em um folder e mostrará um link para cada um. Este exemplo mostra a você
como imprimir todos os objetos "File" em um folder, assim para executar este exemplo você vai precisar
atualizar alguns arquivos dentro do Zope como explicado no capítulo anterior:

61 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>
<ul>
<dtml-in expr="objectValues(File)">
<li><a href="&dtml-absolute_url;"><dtml-var title_or_id></a></li>
</dtml-in>
</ul>
<dtml-var standard_html_footer>

Este código mostrou a seguinte lista de arquivos, como mostra a Figura 4.4.

Interagindo sobre uma lista de arquivos.

Vamos olhar passo a passo este exemplo em DTML. Primeiro, a tag var é usada para inserir seu
cabeçalho padrão no documento. Depois, para indicar que você quer o browser para desenhar uma lista
ordenada em HTML, você tem que usar a tag ul HTML.

Então tem a tag in. A tag tem uma expressão que está chamando o método API do Zope chamado
objectValues. Este método retorna uma sequência de objetos de um folder corrente que se adapta a um
critério dado. Neste caso, os objetos devem ser files (arquivos). Este método call retornará uma lista de
arquivos em um folder corrente.

A tag in fará um loop sobre cada item nesta sequência. Se houver quatro objetos arquivo no folder
corrente, então a tag in executará o código em seu bloco quatro vezes; uma vez para cada objeto na
sequência.

Durante cada interação, a tag in procura por variáveis no object corrente, primeiro. No Capítulo 8,
"variáveis e DTML Avançada" veremos melhor como a DTML procura variáveis.

Por exemplo, esta tag in interage sobre uma coleção de objetos File e usa a tag var para procurar
variáveis em cada arquivo:

<dtml-in expr="objectValues(File)">
<li><a href="&dtml-absolute_url;"><dtml-var title_or_id></a></li>
</dtml-in>

A primeira tag var é uma entidade e a segunda é uma tag var da DTML normal. Quando a tag in faz um
loop sobre o primeiro objeto suas variáveis absolute_url e title_or_id serão inseridas no primeiro item
da lista:

<ul>
<li><a href="http://localhost:8080/FirstFile">FirstFile</a></li>

62 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Durante a segunda interação as segundas variáveis do objeto absolute_url e title_or_id são inseridas na
saída:

<ul>
<li><a href="http://localhost:8080/FirstFile">FirstFile</a></li>
<li><a href="http://localhost:8080/SecondFile">SecondFile</a></li>

Este processo continuará até que a tag in tenha interagido sobre cada arquivo dentro do folder corrente.
Depois da tag in você finalmente fecha a sua lista ordenada com fechamento da tag ul HTML e o
standard_html_footer é inserido para fechar o documento.

Variáveis Especiais da Tag In

A tag in oferece a você alguma indormação útil que lhe deixa adaptar seu HTML enquanto você estiver
interagindo sobre uma sequência. Por exemplo, você pode fazer sua biblioteca de arquivo facilmente
para ler colocando-a em uma tabela HTML e fazendo com que cada linha da tabela tenha uma cor
altenanda, como mostra a Figura 4.5.

Figura 4.5 - Lista de Arquivos com cores alternantes nas linhas.

A tag in torna isto fácil. Mude um pouco o seu método da biblioteca de aquivo para se parecer com este:

<dtml-var standard_html_header>

<table>
<dtml-in expr="objectValues(File)">
<dtml-if sequence-even>
<tr bgcolor="grey">
<dtml-else>
<tr>
</dtml-if>
<td>
<a href="&dtml-absolute_url;"><dtml-var title_or_id></a>
</td></tr>
</dtml-in>
</table>

<dtml-var standard_html_footer>

63 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Aqui uma tag if é usada para testar uma variável especial chamada sequence-even. A tag in seta esta
variável para um valor verdadeiro ou falso cada vez através do loop. Se o número de interação corrente é
even, então o valor é verdadeiro, se o número da interação é odd, ele é falso.

O resultado deste teste é que a tag tr tanto com um fundo cinza ou sem fundo é inserida dentro do
documento para qualquer outro objeto na sequência. Como você deveria esperar, há um sequence-odd
que sempre tem o valor oposto do sequence-even.

Existem muitas variáveis especiais que a tag in define para você. Aqui estão as mais comuns e úties:

sequence-item

Esta variável especial é o item corrente na interação.

No caso do exemplo da biblioteca de arquivo, cada vez através do loop o arquivo corrente da interação é
determinado ao sequence-item. É geralmente útil para ter uma referência para o objeto corrente na
interação.

sequence-index

o número corrente, começando do 0, de interações completadas. Se este número é even, sequence-even


é verdadeiro e sequence-odd é falso.

sequence-number

O número corrente, começando do 1, de interações completadas. Pode ser como uma posição cardinal
(primeiro, segundo, terceiro, etc.) de objetos correntes no loop. Se este número é even, sequence-even é
falso e sequence-odd é verdadeiro.

sequence-start

Esta variável é verdadeira para a primeira interação.

sequence-end

Esta variável é verdadeira para a última interação.

Estas variáveis especiais são mais detalhadas no Apêndice A.

DTML é uma poderosa ferramenta para criação de conteúdo dinâmico. Ela lhe permite executar
corretamente cálculos complexos. No Capítulo 8, "Variáveis e DTML Avançada", você verá mais sobre
muitas outas tags DTML, e mais maneiras poderosas para usar as tags que você já viu. Depois disso,
você poderia resistir a tentação de usar DTML para scripts complexos. No Capítulo 10, "Avançado Script
em Zope" você saberá como usar Python e Perl para construir scripts para lógica de aplicação.

6. Usando Modelos de Páginas do Zope


Este capítulo introduz o Modelo de Páginas para o Zope, uma nova ferramenta para criar
um HTML dinâmico. Este capítulo mostra como você pode criar e editar modelos de
páginas. Também introduz modelos básicos que capacitam você a inserir conteúdo
dinâmico.

Modelos de Páginas é uma ferramenta de criação de páginas para web (web page). Elas ajudam
programadores e designers colaborando no desenvolvimento de web pages dinâmicas para aplicações
em Zope. Designers podem usá-las para a manutenção das páginas sem ter que abandonar esta

64 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

ferramenta, preservando o trabalho requerido para encaixar aquelas páginas na aplicação. No capitulo,
vocês aprenderam o básico sobre Modelos de Páginas inclusive como vocês poderão usá-las em seus
web sites para criar web pages dinâmicas facilmente. No capitulo 9, "Modelos de Páginas Avançados",
vocês aprenderão sobre as vantagens do Modelo de Páginas avançados.

O objetivo dos Modelos de Página é permitir que designers e programadores trabalhem facilmente ao
mesmo tempo. Um designer pode usar um editor de html WYSIWYG (o que você vê é o que você terá)
para criar um modelo, na mesma hora um programador pode editar isso para fazer parte da aplicação.
Se solicitado, o designer pode carregar o modelo back dentro do seu editor e promover mudanças na
estrutura e aparência. Por tomada de providência razoável para preservar as mudanças feitas por um
programador, o designer não podera interomper a aplicação.

Modelos de Páginas direcionam-se para este objetivo por adotar três princípios:

1. Se relaciona melhor com ferramentas de edição.


2. Oque você vê é muito similar com o que você terá.
3. Guardar códigos fora dos modelos, a não ser uma estrutura logica.

Modelos de Páginas do Zope Versus DTML

Zope já tem DTML, porque precisa outro modelo de linguagem? Primeiro de tudo, DTML não é dirigido
para designers de HTML. Sempre que uma página foi e deixou de ser convertida em um modelo, ela é
um inválido HTML, ficando difícil de trabalhar fora da aplicação. Segundo, DTML sofre por uma
deficiênicia para separar apresentação, lógica e satisfação (dados). Tanto o decrescimo quanto a
escalabilidade sobre o gerenciamento satisfatório e desenvolvimento de website empenham-se para que
usem estes sistemas.

DTML pode fazer coisas que Modelos de Páginas não podem como por exemplo gerar mensagens de
e-mail dinamicamente (Modelos de Páginas podem somente gerar HTML e XML). Portanto DTML não
irá longe. De qualquer forma, nós veremos Modelos de Página adotadas sobre quase todas as
apresentações HTML/XML inseridas em Zope.

Como os Modelos de Páginas Funcionam


Modelos de Páginas usam Atributos de Modelos de Linguagem (TAL - Template Attribute Language).
TAL consciste em atributosd de caracteres especiais. Por exemplo, um título de página dinamica deveria
se parecer assim:

<title tal:content="here/title">Page Title</title>

O atributo tal:content é uma instrução TAL. Visto que ele tem um namespace XML (the tal : part) a
maioria das ferramentas de edição não conseguem entendê-la, e não a removerão. Ele não mudará a
estrutura ou aparência do modelo quando caregado um editor WYSIWYG ou um navegador. O nome
content indica que ele colocará o conteúdo da tag title e do valor "here/title" numa expressão com a
condição do texto inserido dentro da tag.

Todas instruções TAL consistem de atributos tag começando com tal: e todas instruções tal tem valores
associados a elas. O valor de uma instrução TAL é mostrado dentro de aspas. Veja Apêndice C.
"Referências sobre modelos de Páginas Zope", para mais informações sobre TAL.

Para o uso de uma ferramenta WYSIWYG por um designer, o título dinâmico é um perfeito exemplo
válido de HTML, e mostra no seu editor o que realmente sera visto.

65 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

O exemplo também mostra o princípio que, " O que você vê é o que você terá." Quando você observa um
modelo de editor, o título do texto é usado como um placeholder para um título de texto dinâmico. O
modelo fornece um exemplo de como gerar os documentos que serão vistos.

Quando o modelo é salvado no Zope para ser visto pelo usuário, o objetivo do Zope é imitar o seu
conteudo dinâmico, recolocando "Page Title" como qualquer determinação "here/title." No caso,
"here/title" determina o título para o qual o modelo sera aplicado. Esta substituição funcionará
dinamicamente, quando o modelo é observado.

Há modelos para recolocar instruções tags inteiras, o conteúdo delas, ou somente alguns de seus
atributos. Você pode repetir uma tag em vários momentos ou omití-las inteiramente. Você pode juntar
partes de vários modelos, e especificar normas de reparações de erros. Todas estas capacidades são
usadas para gerar estruturas de documentos. A respeitos destas capacidades, você não pode crear
subrotinas ou classes, executar sistemas complexos de controle de fluxo, ou expressar facilmente
complexos algorítmos. Para estas tarefas, você deveria usar Phyton-based Scripts ou componentes da
aplicação.

A linguagem do modelo de página é deliberadamente não poderosa e propósito-geral como poderia ser.
Ela tinha a intenção de usar dentro de um framework (assim como Zope) no qual outro objeto
logicamente negociável e não próximo da tarefa para esboço de página.

Por exemplo, linguagem de modelo seria útil para traduzir uma página invoice, criando uma ordem para
cada item da linha, e inserindo a descrição, qualidade, custo, e asssim por diante para cada linha do
texto.

Criando um Modelo de Páginas


Se você projeta páginas, você provavelmente usará FTP ou WebDAV no lugar de ZMI (Zope
Management Interface - Interface de Gerenciamento Zope) para criar e editar modelos de páginas.
Veremos mais tarde na seção "Uso de FTP e WebDAV" nesse capítulo informações sobre edição de
modelos de páginas remotamente. No o pequeno exemplo nesse capítulo, ZMI é facilmente usado.

Use seu web browser para logar dentro Zope Management Interface - ZMI - como um gerente. Escolha
um Folder para inserir (o root esta bem) e escolha "Page Template" na lista de adição do drop-down
(janela de escolha). Selecione "simple_page" no campo ld do formulário de adição, então pressione o
botão "Add and Edit".

Você deveria agora ver a página de edição principal para o novo modelo de página. O título está em
branco, o content-type é text/html, e o modelo de texto por definição é uma area de edição.

Agora criaremos uma página dinâmica simples. Selecione a palavra "Simple Page" no campo Title.
Então, o editor do modelo de página terá esta aparencia.

<html>

<body>

<p>

This is <b tal:replace="template/title">the Title</b>.

</p>

</body>

</html>

66 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Agora pressione o botão Save Changes. O Zope deveria mostrar uma mensagem confirmando que suas
mudanças foram salvas.

Se um comentário HTML começar com <-- Diagnóstica de Modelo de Página esta adicionando a um
modelo de texto, então verifique para garantir que você selecionou o exemplo corretamente e salve
novamente. Este comentário é uma mensagem de erro explicando que alguma coisa esta errada. Você
não precisa apagar a mensagem de erro, uma vez que o erro é corrigido ele desaparece.

Clique na tab Test. Você verá uma página com, "This is a Simple Page." no topo. Note que o texto é
simples, nada é arrojado.

Depois disto, click no link Browse HTML source abaixo do campo content-type. Isto mostrará para você
a origem unrendered do modelo. Você deverá ver, "This is the Title." Apos isto, você estará preparado
para editar o modelo mais tarde.

O campo Content-Type permitira a você especificar o tipo de conteúdo da sua página. Geralmente você
usará o tipo de conteúdo text/html para HTML ou text/xml para XML.

Se você escolher o tipo text/html então o Zope analisará a compatibilidade do seu modelo com o modo
de marcação HTML. Se você escolher qualquer outro tipo de conteúdo que não seje o text/html o Zope
supõe que o modelo seja XML. Além disso o Zope requer um nome TAL e METAL XML declaração para
o formato XML.

A Edição de expanção de macros é explicada no capítulo 9, "Modelos de páginas avançadas".

Expressões Simples
A expressão, "template/title' é um caminho do Madelo de Página. Este é um dos mais comuns tipo de
expressão. Existem vários outros tipos de expressões definidos pelo padrão da Sintaxe de Expressão
TAL (TALES). Para mais informações do padrão de expressão TAL veja o apêndice C, "Referências de
Modelos de Páginas Zope".

O "template/title" produz um title proprietário do modelo. Nele há algumas expressões comuns.

* request/URL: A URL da requisição de pedido corrente.


* user/getUserName: A autentificação do login de usuário.
* container/objectIds: A lista de Ids de objetos da mesma pasta do modelo.

Todos os caminhos começarão com um nome de variável. Se a variável conter o nome que você quer,
você para. Senão, você adiciona uma barra (´/´) ao nome do sub-objeto ou propriedade. Talves você
precise realisar seus camilhos através de vários sub-objetos para alcançar oque você buscou.

O Zope define um pequeno grupo de variáveis embutidas (built-in) assim como request and user, como
será descrito no capítulo 9, "Modelos de Páginas Avançado". Você também aprenderá como definir suas
variáveis neste capítulo.

Inserindo Texto
No modelo "simple_page", você usará uma instrução tal:replace ligada a um caracter destacado.
Quando você testar isto, o Zope colocará um caracter completo como título do modelo. Apesar do seu
codigo de origem, você verá um modelo de texto destacado. Nós usamos um outro caracter destacado
para sublinhar algo diferente.

67 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Para colocar uma parte dinamica de um texto em outro texto, você usa tal:replace ou um caracter span,
de preferência o mesmo caracter destacado. Por exemplo, adicionar depois de umas linhas o exemplo:

<br>

The URL is <span tal:replace="request/URL">URL</span>.

O caracter sapn é strutural, não visual, assim você somente verá que "The URL is URL." quamdo você
abrir o código em um editor ou browser. Quando você ver a versão pronta, talvez seja possível ver isto:

<br>

The URL is http://localhost:8080/simple_page.

Se você precesar inserir um caracter no text mas largar ele sozinho, você usará a instruçao tal:content.
Para agrupar o título do exemplo de página ao título do modelo proprietário, acrescente as linhas
aseguir no meio do codigo html e o caracter body:

<head>

<title tal:content="template/title">The
Title</title>

</head>

Se você abrir o indicador "Test" em um novo browser do windows, ele terá como título "a Simple Page".
Se você olhar o código da página verá alguma coisa assim:

<html>

<head>

<title>a
Simple Page</title>

</head>

...

O Zope inseriu ao títul odo seu modelo o caracter title.

Estruturas de Repetição
Agora vamos adicionar alguns contextos a suas páginas, da forma de listas de objetos na mesma pasta
do modelo. Você criará uma tabela que terá numerado linhas para cada objeto e colunas para id,
meta-type e títulos. Adicione estas linhas ao seu exemplo:

68 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<table border="1" width="100%">


<tr>
<th>Number</th>
<th>Id</th>
<th>Meta-Type</th>
<th>Title</th>
</tr>
<tr tal:repeat="item container/objectValues">
<td tal:content="repeat/item/number">#</td>
<td tal:content="item/getId">Id</td>
<td tal:content="item/meta_type">Meta-Type</td>
<td tal:content="item/title">Title</td>
</tr>
</table>

A instrução tal:repeat, na linha da tabela significa "repeta esta linha para cada item da lista com este
valor". A Instrução repeat coloca o objeto da lista dentro da variável item um de cada vez(esta é chavada
de repeat variable), e faz um copia da linha usando esta variável. O valor de "item/getId" em cada linha
de Id é o objeto para aquela linha, e da mesma forma que "item/meta_type" e "item/title".

Você pode usar qualquer nome para a variável repeat ("item" é apenas um exemplo), enquanto ele
começar com alguma letra e conter somente letras, números e sobrelinhas ("_"). A variável repeat é
apenas um caracter de repetição. Se você tentar usar acima ou abaixo de um caracter tr, terá um erro.

Você pode usar o nome da variável repeat para ter informações sobre uma repetição corrente. Coloque
após a variável built-in no caminho repeat, você pode acessar a repetição se o contador for zero
(´index´), for um-1 (´número´), for A (´letra´), e várias outras formas. Portanto, a axpressão fica
repeat/item/number é 1 na primeira linha, 2 na segunda, etc.

Desde então, um laço tal:repeat pode ser inserido em outro, mais que um pode ser ativado ao mesmo
tempo. Este é o motivo pelo qual deve ser escrito repeat/item/number no lugar de repeat/number.
Você precisa especificar qual laço lhe interesará e incluir no nome do laço.

Neste momento observe a página e repare como esta lista de objetos está na mesma pasta do modelo.
Tente adicionar ou remover objetos desta pasta e repare quais os efeitos destas mudanças.

Elementos Condicionais
Usando o modelo de páginas você pode dinamicamente inserir um texto no seu meio seletivamente
dependendo da condição. Por exemplo, você poderia exibir informações especiais para responder a um
cookie:

<p tal:condition="request/cookies/verbose | nothing">


Here's the extra information you requested.
</p>

Este paragrafo poderia ser incluido em apenas uma saída se havia uma verbose cookie set. A expressão,
"request/cookies/verbose | somente será verdadeira se houver um nome verbose cookie set. Você
aprenderá mais sobre esta especia de expressão no capítulo 9, "Modelo de Página Avançado".

Usando uma instrção tal:condition você pode verificar todos os tipos de condições. Uma instrução
tal:condition não faz nada se esta expressão não tiver um valor verdadeiro, mas remove as instruções de
caracteres inteiras, incluindo os conteúdos, se o valor for falso. Zope considera o número zero como
uma sequencia vazia, uma lista vazia, e uma variável built-in nothing to be de valor falso. Quase
qualquer outro valor é verdadeiro, incluido números não-zero, e sequencias com alguma coisa (inclusive
espaços!).

69 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Outro simples uso de condição para testar uma sequencia é ver se esvazia antes da loping terminar. Por
exemplo é a ultima seção vendo como puxar uma tabela para repetir uma coleçaõ de objetos. Neste
ponto é como adicionar uma verificação de página assim que a lista de objetos é esvaziada sem a tabela
ser puxada.

<table tal:condition="container/objectValues" border="1" width="100%">

<tr>

<th>Number</th>

<th>Id</th>

<th>Meta-Type</th>

<th>Title</th>

</tr>

<tr tal:repeat="item container/objectValues">

<td tal:content="repeat/item/number">#</td>

<td tal:content="item/getId">Id</td>

<td tal:content="item/meta_type">Meta-Type</td>

<td tal:content="item/title">Title</td>

</tr>
</table>

Se esta expressão, conteiner/objectValues é falsa, então a tabela inteira é omitida.

Mudando Atributos
A maioria, se não todos, os objetos registrados pelo seu modelo tem uma propriedade icon, que contem
um caminha para o icone do genero do objeto. Para mostrar este icone numa coluna meta-type, você
precisa inserir este caminha no atributo src do caracter img. Editando a coluna meta-type em ambas as
linhas você verá isto:

<td><img src="/misc_/OFSP/Folder_icon.gif"
tal:attributes="src item/icon">
<span tal:replace="item/meta_type">Meta-Type</span>
</td>

A instrução tal:attributes são trocadas no atributos src do caracter img com o valor de item/icon. O
atributo src="/misc_/OFSP/Folder_icon.gif" no modelo atua como um placeholder.

Repare que nós temos trocado o atributo tal:content da tabela cela com a instrução tal:replace de um
caracter span. Esta mudança permite você ter imagens e textos, ambos juntos na mesma tabela.

Criando uma Biblioteca de Arquivos com Modelos de


Páginas
Neste exemplo de uas de Modelo de Página com Zope para criar uma simples biblioteca de arquivos
com um modelo, um pouco de código Phyton, e alguns arquivos.

Primeiro, crearemos um simulador de uma página de biblioteca de arquivos usando o editor HTML. O
exemplo neste capítulo foi feito com Amaya. Este simulador não precisa exagerar, ele apenas mostrará

70 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

algumas imitações de informações. Simulará uma biblioteca de arquivos que contem um arquivo:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"


"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>File Library</title>
<style type="text/css">
.header {
font-weight: bold;
font-family: helvetica;
background: #DDDDDD;
}
h1 {
font-family: helvetica;
}
.filename {
font-family: courier
}
</style>
<meta name="GENERATOR" content="amaya 5.1">
</head>

<body>
<h1>File Library</h1>

<p>Click on a file below to download it.</p>

<table border="1" cellpadding="5" cellspacing="0">


<tbody>
<tr>
<td class="header">Name</td>
<td class="header">Type</td>
<td class="header">Size</td>
<td class="header">Last Modified</td>
</tr>
<tr>
<td><a href="Sample.tgz" class="filename">Sample.tgz</a></td>
<td>application/x-gzip-compressed</td>
<td>22 K</td>
<td>2001/09/17</td>
</tr>
</tbody>
</table>
</body>
</html>

Agora, log em seu Zope e crie um folder chamado FileLib. Neste folder, crie um modelo de página
chamado index_html pelo selecionador Page Template do adicionador de menu, especificando o Id
index_html no formulário, e clicando Add.

Agora, com seu editor HTML, salve o HTML citado acima para a URL do Modelo de Página index_html
seguido por /source.html, por exemplo, http://localhost:8080/FileLib/index_html/source.html.
Repare que a URL para save a página index_html termina com source.html. Porque modelos de páginas
são dinâmicos, você precisa um caminho para editar uma linha da origem do modelo, unrendered por
linguagens de modelos de páginas. Anexa-se source.html à um modelo de página seu código puro. Note,
se o content_type de sua pagina é text/xml então você terá que usar source.xml, no lugar de
source.html.

Agora você terá que salvar o modelo, precisa voltar para o Zope e clicar em index_html e também clicar
na tabela Test para observar o modelo. Este aspecto é exatamente o da simulação, portanto, tudo dará
certo.

Agora pegaremos o trecho de HTML citado acima e adicionaremos algumas mágicas dinâmicas.
Primeiro, precisaremos de um modelo de título dinâmico. No Zope, você podera notar que existe no
Modelo de Página um campo tilte que você podera preenche-lo. No lugar do estático HTML, você
podera inserir dinamicamente um título do Modelo de Página dentro da versao do modelo. Como aqui:

71 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<head>

...

<title tal:content="template/title">File Library</title>

...

<body>

<h1 tal:content="template/title">File Library</h1>

...

Agora iremos para as mudanças do título do modelo de página index.html. Após salvar estas mudanças,
click no botão Test. Como você pode ver, o Modelo de Página inseriu dinamicamente o título do modelo
de objeto na saída do modelo.

Note o novo caracter content atribuido na tal xml namespace. Este atributo diz para "colocar o content
do caracter com a variável 'template/tilte'". Neste caso, template/title é um títul odo modelo de página
index_html.

O próximo pedaço da mágica é construir uma lista de arquivos dinâmicos mostrando todos os Arquivos
na pasta FileLib.

Para começar, você precisa escrever apenas uma linha em Phyton. Vá para a pasta FileLib e crie um
Script (Phyton) com esta pasta. Prepare tanto o arquivo script quanto o id e click Add and Edit. Edite a
conteúdo do script com o seguinte código em Phyton:

## Script (Python) "files"


##
return container.objectValues(File)

Isto retornará uma lista de alguns objetos File da pasta FileLib. Agora, edite seu Modelo de Página e
adicione mais alguns atributos tal em seu simulador.

...
<tr tal:repeat="item container/files">
<td><a href="Sample.tgz" class="filename"
tal:attributes="href item/getId"
tal:content="item/getId">Sample.tgz</a></td>
<td tal:content="item/content_type">application/x-gzip-compressed</td>
<td tal:content="item/getSize">22 K</td>
<td tal:content="item/bobobase_modification_time">2001/09/17</td>
</tr>
...

O interessante é a parte do atributo tal:repeat no ligado ao caracter tr do HTML. Este atributo ordena o
modelo para reinterar novamente o valor retornado por "continer/files" (o script Phyton creado por
você) e criar uma nova tabela ordenada por cada arquivo. Durante esta interação, o arquivo objeto
corrente recebe o nome item.

Todas as cells de cada linha tem o atributo tal:content que descreve a data que deveria entrar cada cells.
Durante cada interação através da tabela de grupos de linhas, o id, o content type, o tamanho, e
modificações de tempo recolocam os dados na tabela. Além disso, note como o archor link
dinamicamente aponta para o arquivo corrente usando atributos tal para reescrever o atributo href.

Estes dados chegam do objeto item por chamadas de métodos Zope API do qual você conhecera este
objeto do arquivo. O método item/getId, item/content_type, item/bobobase_modification_time são

72 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

todos padrões de funções API que são documentadas no sistema de ajuda online do Zope.

Vamos para o Zope e testamos estes scripts por primeiro uploading de alguns arquivos da pasta FileLib.
Isto refere-se a selecionar o arquivo para adicionar menu clicando no botão upload na proxima tela.
Após o uploading do seu arquivo, você apenas precisa clicar em Add. Se você não especificar um id,
então o nome do arquivo sera o do udloading que foi usado.

Apos o uploading de alguns arquivos, vamos para o Modelo de Página index.html e clicamos na tabela
Test. Agora, você poderá ver o Modelo de Página criando uma biblioteca de arquivos muito simples com
apenas algumas mudanças de atributos tag HTML.

Existe algums problemas cosmetic o comportamento da biblioteca de arquivos. O tamanho e a data de


exibição não são os mais bonitos e não são compativeis com o formato do conteudo dummy.
Gostariamos tanto que o tamanho do arquivos fosse mostrado particularmente em K ou MB do que
bytes. Aqui um script baseado em Phyton que você pode usar para isto:

## Script (Python) "file_size"


##
"""
Return a string describing the size of a file.
"""
bytes=context.getSize()
k=bytes/1024.0
mb=bytes/1048576.0
if mb > 1:
return "%.2f MB" % mb
if k > 1:
return "%d K" % k
return "%d bytes" % bytes

Creado este script com o id file_size em sua pasta FileLib. Ele calculará um tamanho de arquivo em K ou
MB e retornará uma string apropriada descrevendo o tamanho do arquivo. Agora podemos usar o script
no lugar da expressão item/getSize.

...
<td tal:content="item/file_size">22 K</td>
...

Também podemos consertar o problema do formato da data com um pequeno código Phyton. Creando
um script nomeado file_date na pasta FileLib.

## Script (Python) "file_date"

##

"""

Return modification date as string YYYY/MM/DD

"""

date=context.bobobase_modification_time()

return "%s/%s/%s" % (date.year(),date.mm(), date.day())

Agora recoloque a expressão item/bobobase_modification_time com uma colocação no script:

73 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

...

<td tal:content="item/file_date">2001/09/17</td>

...

Parabéns, você teve sucesso pegando um mock-up e tornando-o um Modelo de Página dinâmico. Este
exemplo ilustrado com Modelo de Página funciona bem como "presentation layer" para suas aplicações.
O Modelo de Página apresenta a aplicação lógica (script baseado em Phyton) e a aplicação lógica
trabalhando com os dados do seu site (os arquivos).

Edição Remota com FTP e WebDav


Podemos editar páginas remotamente com FTP e WebDAV, e também publicações HTTP PUT. Usando
este métodos, poderemos usar Modelos de Páginas sem deixar editores avançados WYSIWYG assim
como DremWeaver.

A seção anterior mostrou como editar uma página remotamente usando Amaya, no qual usa HTTP PUT
para o upload de páginas. Podemos fazer o mesmo com FTP e WebDAV fazendo os mesmos passos.

1. Cria um Modelo de Página com o Gerenciador de Interface Zope. Podemos nomear com qualquer
extensão de arquivo que desejamos. Muitas pessoas preferem .html, enquanto outras preferem .zpt.
Note, alguns nomes como por exemplo index.html tem sentido especial para o Zope.
2. Resgatar o arquivo usando a URL do modelo de página adicional /source.html ou /source.xml. Isto
dá a você a origem do seu Modelo de Página.
3. Edite seu arquivo com o seu editor e então salve-o. Qaundo você salvá-lo deverá usar o mesma URL
usada para resgatá-lo.
4. Opcionalmente caregue novamente sua página após editá-la, para conferir erros. Veja a próxima
seção para mais detalhes sobre debugging.

Na versãoanterior do Zope você provavelmente seria capaz de criar Modelos de Páginas sem usar o
Gerenciador de Interface Zope.

Debugando e Testando
Nos helps do Zope você encontrará e corrigirá problemas de seus Modelos de Páginas. O Zope notifica
os problemas em dois diferentes momentos: quando você esta editando o Modelo e quando você
visualiza o Modelo de Página. O Zope pega diferentes tipos de erros quando estamos editando do que
quando estamos visualizando um Modelo de Página.

Você provavelmente já se familiarizou com os comentários trouble-shooting que o Zope insere em seu
Modelo de Página quando ele se depara com problemas. Este comentários conta-lhe sobre problemas
que o Zope encontra enquanto esta editando o seu modelo. O tipo de problema que o Zope encontra
enquanto estamos editando são na maioria das vezes erros no seu enunciado tal. Por exemplo:

<!-- Page Template Diagnostics Compilation failed

TAL.TALDefs.TALError: bad TAL attribute: contents, at line 10, column 1

-->

Estas mensagens de diagnosticos permitem a você saber que você por engano usou tal:contents do que
tal:content na linha 10 do seu modelo. Outro mensagem diagnóstico contadas serão sobre problemas
com expressões e macros do seu modelo.

74 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Quando estiver usando o Gerenciador de Interface Zope para editar Modelos de Páginas ele facilmente
localizará estas mensagens de erros. De qualquer forma, se estivermos usando o WebDav ou FTP eles
tranquilamente perderão estas mensagens. Por exemplo, se você salvar um modelo para Zope com FTP,
você não receberá uma descrição do erro FTP sobre o problema. De fato, você terá que recarregar o
modelo de Zope para ver a mensagem de diagnóstico. Enquanto usar FTP e WebDAV é uma boa idéia
recarregar os modelos após sua edição para ter certeza de que eles não contém mensagens de
diagnósticos.

Se você não notar mensagens de diagósticos e tentar reverter um modelo com problemas verá uma
mensagem deste modo:

Error Type: RuntimeError


Error Value: Page Template hello.html has errors.

Isto é um sinal para recarregar o modelo e checar as mensagens de diagnósticos.

Em acréscimo as mensagens de diagnósticos enquanto estiver editando, ocasionalmente receberá


regulares erros de Zope quando vizualizar um Modelo de Página. Estes problemas são frequentemente
impostos por problemas em suas expressões no modelo. Por exemplo, você talvez receberá um erro se
uma expressão não localizar uma variável:

Error Type: Undefined


Error Value: "unicorn" not found in "here/unicorn"

Esta mensagem de erro mostrará que não consegue encontrar a variável unicorn no qual a expressão se
refere, here/unicorn. Para ajudar você a compreender o qual estava errado, o Zope inclui informações
sobre o ambiente do traceback. O traceback incluirá informações sobre o ambiente:

...

'here': <Application instance at 01736F78>,

'modules': <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter
instance at 016E77FC>,

'nothing': None,

'options': {'args': ()},

'request': ...

'root': <Application instance at 01736F78>,

'template': <ZopePageTemplate instance at 01732978>,

'traverse_subpath': [],

'user': amos})

...

Esta informação é um bit oculto, mas com uma pequena palavra de detecção que podera ajudar você a
compreender o que esta errado. Neste caso, ele nos mostrará que a variável here é um "Application
instance". Isto significa que ele é o top-level (nível mais alto) do Zope (note como a variável root é o
mesmo que "Application instance"). Talves o problema seja que você esta aplicando o modelo para uma
pasta/diretório que tem uma propriedade unicorn. O traceback não forneceu bastante ajuda, mas ele
pode ajudar você as vezes.

Modelos XML

75 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Outro exemplo da flexibilidade do Modelo de Página é que ele pode fazer dinamicamente XML assim
como HTML. Por exemplo, no Capítulo 5, "Criando Aplicacões Básicas Zope", vamos criar o seguinte
XML:

<guestbook>

<entry>

<comments>My comments</comments>

</entry>

<entry>

<comments>I like your web page</comments>

</entry>

<entry>

<comments>Please no blink tags</comments>

</entry>

</guestbook>

Este XML foi criado por um lopping que abrange todos Documentos DTML no diretório e introduz o
código fonte dentro do elemento comment. Nesta seção, veremos como usar Modelos de Páginas para
gerar este mesmo XML.

Criamos um novo Modelo de Página chamado "entries.xml" em sua pasta guest book com o seguinte
conteúdo:

<guestbook xmlns:tal="http://xml.zope.org/namespaces/tal">

<entry tal:repeat="entry python:here.objectValues(DTML Document)">

<comments tal:content="entry/document_src">Comment goes here...</comments>

</entry>

</guestbook>

Garantimos nosso conteúdo colocando o gênero para text/xml. Agora, click em Save Changes e click na
tabela Test. Se estiver usando Netscape, ele lhe mostrará um documento XML para download, se
estiver usando MSIE 5 ou superior, você sera capaz de ver seu documento XML no browser.

Note como a instrução tal:repeat abrange todos os Documentos DTML. A instrução tal:content é
inserida no código fonte de cada documento dentro do elemento comments. O atributo xmlns:tal é uma
declaração XML. Ele sabe que nomes começados com tal em Zope são comandos de Modelos de
Páginas. Veja o Apêndice C, "Referências de Modelos de Páginas Zope" para mais informações sobre
TAL e TALES XML namespaces.

Criação de XML com Modelos de Páginas é quase tão satisfatório quanto criação de HTML. A diferençã
mais importante é que você precisa usar namespace declarações explícitas XML. Outra diferença é que
você precesaria colocar o gênero do conteúdo para text/xml ou qualquer content-type que seu XML
deveria ter. A diferença final é que você pode navegar na fonte de um modelo XML source.xml através
do source.html.

Usando Modelos com Conteúdo

76 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Em geral o Zope suporte conteúdo, apresentações e componetes lógicos. Modelos de Páginas são
componentes de apresentação e eles podem ser usados para exibição de componetnes de conteúdos.

O Zope 2.5 vem com muitos componentes de conteúdos: ZSQL Methods, Files, and Images. DTML
Documents e métodos realmente não claros desde de que eles possam guardar conteúdos e executar
código DTML. Desta vez o Zope não veio com um bom propósito geral de objetos de conteúdo. Podemos
usar Files para conteúdo textual desde que possamos editar o conteúdo de Files se o arquivos é menor
que 64K e contem texto. De qualqeur forma o objeto File é basicamente elegante.

O Zope's Contents Management Framework (CMF) resolve este problema pela classificação de ricos
componetes de conteúdo. o CMF é um gerenciador de conteúdo adicionado ao Zope. Ele introduz todo o
tipo de melhoramentos incluindo o work-flow, skins e objetos de conteúdos. O CMF faz um monte de
uso de Modelos de Páginas. Uma ultima versão do Zope provavelmente incluirá o CMF.

Conclusão
Modelos de Páginas do Zope ajudam você a construir web pages para suas aplicações de web. Modelos
conseguem facilitar para você o uso normal de ferramentas normais HTML e técnicas de contrução de
web pages. Eles também fornecem "ganchos" para permitir você liga-los as suas aplicações. Modelos de
Páginas ajudam designers e programadores a trabalhar juntos para produzir aplicações web. No
capítulo 9, "Modelos de Páginas Avançados" aprenderemos sobre poderosas técnicas de modelos como
expressões Phyton e macros.

7. Criando Aplicações Básicas com o Zope


Este capítulo leva o leitor através de vários exemplos reais para construção de aplicações
em Zope. Oferece muitos exemplos que mostram como usar os objetos do Zope e como
eles podem trabalhar juntos para fazerem aplicações básicas.

No Capítulo "Usando Objetos Básicos do Zope" e no Capítulo "Conteúdos Dinâmicos com DTML" você
aprendeu sobre objetos básicos do Zope, e DTML. Neste capítulo você verá como você pode construir
simples mas poderosas aplicações web, usando essas ferramentas. Nos capítulos posteriores deste livro
você irá descobrir mais objetos complexos e mais DTML complexa. Entretanto, as técnicas mostradas
neste capítulo são ainda relevantes.

Observe que: no capítulo 3, "Objetos Básicos do Zope", explicamos como os Templates das páginas do
Zope são novas para o Zope e poderiam ser usadas para apresentação. Nós ainda não adaptamos este
capítulo para usar Templates das Páginas ao invés de DTML. Reescreveremos este capítulo em breve
para refletir novas metodologias baseadas em templates de páginas.

Construindo Aplicações com Pastas


Pastas são "blocos básicos de construção" de aplicações do Zope. As pastas permitem que você organize
seus objetos no Zope, e participe ativamente em suas aplicações web. São dados comportamentos às
pastas adicionando scripts a elas.

Scripts e pastas trabalham juntos para construir simples aplicações. Pastas oferecem estrutura para sua
informação e também oferece um framework para os comportamentos do seu site. Mais adiante neste
capítulo, um exemplo de uma aplicação de um simples livro de visitas baseadas no conceito deste
projeto será dado. A pasta é usada para reter os métodos, scripts e dados da aplicação do livro de
visitas, os scripts oferecem comportamento que define como as aplicações trabalham, e os métodos
oferecem apresentação para a aplicação.

77 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Por exemplo, suponha que você possui uma pasta Invoices para reter faturas. Você poderia criar objetos
dentro daquela pasta chamados addInvoice e editInvoice para lhe permitir adicionar e editar faturas.
Agora sua pasta Invoices torna-se uma aplicação pequena.

As URLs simples e expressivas do Zope são usadas para trabalhar com aplicações de fatura. Como você
viu, você pode exibir um objeto do Zope indo a sua URL em seu browser. Assim por exemplo, a URL
http://localhost:8080/Invoices/addInvoice chama o objeto addInvoice no folder Invoices. Esta URL
poderia levar você a uma tela que deixa você adicionar uma fatura. Da mesma forma, a URL
http://localhost:8080/Invoices/editInvoice?invoice_number=42 chama o objeto editInvoice no folder
Invoices e passa para ele o argumento invoice_number com o valor 42. Esta URL pode permitir você
editar o número 42 da fatura.

Chamando Objetos em Pastas com URLs

Os exemplos de faturas demonstram uma poderosa característica do Zope. Você pode chamar um
objeto em uma pasta indo para a URL que consiste na URL da pasta seguido do id do objeto. Esta
facilidade é usada por todo o Zope e é um padrão de design universal. Na realidade você não está
apenas restrito a chamar objetos nas pastas. Você verá mais tarde como você pode chamar objetos em
todos os tipos de objetos do Zope usando a mesma técnica de URL.

Por exemplo, suponha que você quer chamar um objeto chamado viewFolder em uma das suas pastas.
Talvez você possui diferentes objetos viewFolder em diferentes locais. O Zope entende que o objeto que
você quer é o que ele acha primeiro na pasta que você está chamando o objeto. Se ele não pode achar o
objeto lá, ele sobe um nível e olha na pasta que contém esta pasta. Se o objeto não for achado lá ele sobe
outro nível. Este processo continua até o Zope achar o objeto ou ir para o folder raiz. Se o Zope, não
pode achar o objeto na raiz ele sobe e alcança uma exceção.

Você verá este tipo de comportamento dinâmico em muitos lugares diferentes no Zope. Esta técnica é
chamada aquisição. É dito que uma pasta adquire um objeto procurando pelo objeto em seus
repositórios.

O Objeto Especial index_html da Pasta

Como você já viu, pastas podem adquirir todos os tipos de objetos. Há um objeto especial que o Zope
usa para exibir uma pasta. Este objeto é chamado index_html.

O objeto index_html oferece uma visualização padrão da pasta. Isto se parece com a maneira de como
um arquivo index_html oferece uma visualização default para um diretório no Apache e outros
servidores web.

Por exemplo, se você criar um objeto index_htm em sua pasta Invoices e visualizar a pasta clicando na
aba View ou visitando a URL http://localhost:8080/Invoices/, o Zope chamará o objeto index_html em
sua pasta Invoices.

Uma pasta também pode adquirir um objeto Index_html de suas pastas pai da mesma maneira que
pode adquirir qualquer objeto. Você pode usar esse comportamento para criar uma visualização default
para um grupo de pastas todas em um lugar. Se você quer uma visualízação default diferente da dada
pelo Zope, apenas crie um objeto adaptado index_html naquela pasta. Deste modo você pode anular o
objeto index_html definido acima.

Construindo o Website Zoo no Zope


Nesta seção, você criará um simples web site para o Zope Zoo. Como webmaster do Zoo, é seu trabalho

78 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

fazer o site fácil de usar e administrar. Aqui estão algumas coisas que você precisará:

Usuários do Zoo devem se mover facilmente pelo site, da mesma maneira como se estivessem
caminhando por um Zoo real.
Todas as suas ferramentas de layout para web compartilhadas, como Folhas de Estilo
Encadeadas (CSS - Cascading Style Sheet), devem estar em uma local fácil de administrar.
Você deve oferecer simples bibliotecas de arquivos com vários documentos que descrevem os
animais.
Você precisa de um mapa do site de forma que usuários possam rapidamente ter uma idéia do
layout inteiro do Zoo.
Um livro de visitas deve ser criado de forma que os visitantes do Zoo possam dar a você um
feedback e comentários sobre seu site.
Uma sessão what's new deve ser adicionada a seu livro de visitas de forma que você possa ver
qualquer comentário recente que foi adicionado.

Navegação do Zoo

Para que seu sistema de navegação trabalhe, seu site precisará de alguma estrutura básica através da
qual você pode navegar. Crie algumas pastas no sistema do Zope que representam a estrutura do seu
site. Vamos usar uma estrutura do zoo, com o seguinte layout, como mostra a Figura 5.1.

Figura 5.1 - Estrutura da pasta zoo

A principal estrutura do Zope Zoo contém três pastas de níveis superiores, Reptiles, Mammals e Fish.
Para navegar em seu site, os usuários deveriam ir primeiro a sua página principal e clicar em uma das
pastas deste nível para entrar na parte particular do Zoo. Eles também deveriam ser capazes de usar
uma interface bem parecida, para guardar as características; isto é, a sessão snakes. Também, o usuário
deveria ser capaz de sair da sessão e ir para a sessão pincipal.

Você pode efetuar isto facilmente com o Zope. Em sua pasta ZopeZoo, crie um DTML Method chamado
navegation:

<ul>
<dtml-in expr="objectValues(Folder)">
<li><a href="&dtml-absolute_url;"><dtml-var title_or_id></a></li><br>
</dtml-in>
</ul>

O método que você acabou de criar mostra uma lista de links para as várias sub-seções do Zoo. É
importante observar que este método pode trabalhar em qualquer pasta desde que não faça nenhuma
suposição sobre a pasta. Também desde que colocamos este método na pasta ZopeZoo, todas as pastas

79 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

zoo podem adquiri-lo.

Agora, você precisa incorporar este método no site. Vamos colocar uma referência nele no objeto
standard_html_header de forma que o sistema de navegação esteja disponível em cada página do site.
Seu standard_html_header poderia se parecer com este:

<html>
<head><title><dtml-var title></title></head>
<body>
<dtml-var navigation>

Logo nós precisaremos adicionar uma página inicial para o site do Zoo e então nós podemos ver o site e
verificar se a navegação trabalha corretamente.

Adicionando uma Página Inicial para o Zoo

Agora, você precisa de uma página inicial que sirva como tela de recepção para os visitantes do Zoo.
Vamos criar um DTML Method na pasta do ZopeZoo chamada index_html com o seguinte conteúdo:

<dtml-var standard_html_header>
<h1>Welcome to the Zope Zoo</h1>

<p>Here you will find all kinds of cool animals. You are in
the <b><dtml-var getId></b> section.</p>

<dtml-var standard_html_footer>

Dê uma olhada em como seu site se parece clicando na aba View na pasta da raiz, como mostra a Figura
5.2.

Figura 5.2 - Página Inicial do Zope Zoo.

Aqui você começa a ver como as coisas estão juntas. No topo da sua página principal, você vê uma lista
de links para várias sub-sessões. Estes links são criados por um método navegação que é chamado pelo
método standard_html_header.

80 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Você pode usar os links de navegação para navegar pelas várias seções do Zoo. Use esta interface de
navegação para achar a sessão dos reptiles (répteis).

O Zope constrói esta página para mostrar uma pasta que é procurada pelo método padrão de
visualização de pastas, index_html. Ele sobe pelas pastas do site do Zoo até encontrar o método
index_html na pasta ZopeZoo. Ele então chama este método na pasta Reptiles. O método index_html
chama o método standard_html_header, que por sua vez chama o método navegation. Finalmente, o
método index_html exibe uma mensagem de saudação e chama o standard_html_footer.

Você quer que a página dos répteis mostre algo além da mensagem de saudação? Você pode repor o
método index_html na seção répteis com um método mais apropriado e ainda tirar vantagem do
cabeçalho e do rodapé incluindo a navegação.

Na pasta Reptile crie um DTML Method chamado index_html. Dê a ele algum conteúdo mais
apropriado aos répteis:

<dtml-var standard_html_header>

<h1>The Reptile House</h1>

<p>Welcome to the Reptile House.</p>

<p>We are open from 6pm to midnight Monday through Friday.</p>

<dtml-var standard_html_footer>

Agora dê uma olhada na página dos répteis indo a pasta Reptile, e clicando na aba View.

Considerando que o método index_html na pasta Reptile inclui um cabeçalho e rodapé padrão, a página
do réptil ainda inclui o seu sistema de navegação.

Clique sobre o link Snakes na página do réptil para ver como a sessão Snakes se parece. A página Snakes
se parece com a página Reptiles, porque a pasta Snakesadquire o método de exibição index_html da
pasta Reptiles.

Melhorando a Navegação

O sistema de navegação para o zoo funciona muito bem, mas tem um grande problema. Quando você vai
mais fundo no site, você precisa usar o botão back do seu browser para voltar atrás. Não existem links
de navegação para permitir que você navegue nas hierarquias das pastas. Vamos adicionar links para
permitir que você suba nas hierarquias. Mude o método navegation no folder raiz:

81 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<a href="..">Return to parent</a><br>

<ul>
<dtml-in expr="objectValues(Folder)">
<li><a href="&dtml-absolute_url;"><dtml-var title_or_id></a><br></li>
</dtml-in>
</ul>

Agora navegue no site do Zoo para ver como o novo link trabalha, como mostra a Figura 5.3.

Figura 5.3 - Controle de Navegtação do Zoo Melhorado.

Como você pode ver, o link Return to parent permite que você retorne de uma sessão do site para seu
pai. De qualquer forma alguns problemas permaneceram; quando você está no nível mais alto do site
você ainda obtem um link Return to parent que o leva para lugar nenhum. Vamos concertar isto
mudando o método navegation para esconder o link pai quando você estiver na pasta ZopeZoo:

<dtml-if expr="_.len(PARENTS) > 2">


<a href="..">Return to parent</a><br>
</dtml-if>

<ul>
<dtml-in expr="objectValues(Folder)">
<li><a href="&dtml-absolute_url;"><dtml-var title_or_id></a><br></li>
</dtml-in>
</ul>

Agora o método testa para ver se o objeto corrente possui algum parent antes dele exibir um link para o
parent. PARENTS é uma lista de parents do objeto corrente, e len é uma função de utilidade que retorna
o comprimento de uma lista. Veja o Apêndice A para mais informações sobre funções de utilidade da
DTML. Agora veja o site. Observe que agora não há link para parent quando você visualiza a página
principal do zoo.

Ainda há algumas coisas que poderiam ser melhoradas a respeito do sistema de navegação. Por
exemplo, é importante avisar em que sessão do Zoo você está. Você mudou a sessão répteis, mas o resto
do site está bonito, com exceção de possuir diferentes links de navegação. Seria legal ter em cada página
em qual sessão do Zoo você está.

82 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Vamos mudar o método navigation mais uma vez para mostrar onde você está:

<dtml-if expr="_.len(PARENTS) > 2">


<h2><dtml-var title_or_id> Section</h2>
<a href="..">Return to parent</a><br>
</dtml-if>

<ul>
<dtml-in expr="objectValues(Folder)">
<li><a href="&dtml-absolute_url;"><dtml-var title_or_id></a><br></li>
</dtml-in>
</ul>

Agora veja o site novamente.

Figura 5.4 - Página do Zoo com informação da sessão

Como você pode ver na Figura 5.4, o método navegation agora informa em que sessão você está com
links para ir a diferentes sessões do zoo.

Fabricando Folhas de Estilo

As páginas do Zoo são construídas através de coleções de métodos que operam nas pastas. Por
exemplo, o método header chama o método navegation para mostrar os links de navegação em todas as
páginas. Além disso para fabricar um comportamento compartilhado como controles de navegação,
você pode usar diferentes objetos do Zope para fabricar o conteúdo compartilhado.

Suponha que você gostaria de usar CSS (Cascading Style Sheets) ajeitar o layout do site do zoo. Um
modo para fazer isto seria incluir as tags CSS no método standard_html_heade. Deste modo cada
página do site teria a informação do CSS. Este é um bom método para reusar conteúdo, entretanto, esta
não é uma solução flexível considerando que você poderia querer um diferente layout em diferentes
partes do seu site. Suponha que você quer que o fundo da página snakes seja verde, enquanto o resto do
site deveria ter um fundo branco. Você teria que anular o standard_html_header na pasta Snakes e
fazê-lo exatamente igual ao cabeçalho normal com exceção do estilo da informação. Esta é uma solução
flexível considerando que você não possa variar a informação do CSS sem mudar o cabeçalho inteiro.

Você pode criar um modo mais flexível para definir as informações do CSS fatorando-o em um objeto
separado que o cabeçalho irá inserir. Crie um DTML Documento na pasta ZopeZoo chamada
style_sheet. Mude o conteúdo do documento para incluir algum estilo de informação:

83 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<style type="text/css">
h1{
font-size: 24pt;
font-family: sanserif;
}
p{
color: #220000;
}
body{
background: #FFFFDD;
}
</style>

Este é o estilo de folha CSS que define como exibir h1, p e o body das tags HTML. Agora vamos incluir
este conteúdo no nosso web site inserindo-o no método standard_html_header:

<html>
<head>
<dtml-var style_sheet>
</head>
<body>
<dtml-var navigation>

Agora, quando você olhar os documentos em seu site, todos os parágrafos serão vermelho escuro, e os
cabeçalhos estarão com uma fonte sans-serif.

Para mudar o estilo da informação em uma parte do site do zoo, apenas crie um novo documento
style_sheet e coloque-o em um folder. Todas as páginas naquela pasta e suas sub-pastas usarão um
novo estilo de folha.

Criando uma Biblioteca de Arquivos

As bibliotecas de arquivos são comuns nos site da web, considerando que muitos sites distribuem
arquivos de algum tipo. A maneira mais antiga para criar bibliotecas de arquivos é atualizar seus
arquivos, então crie uma página que contenha links para aqueles arquivos. Com o Zope você pode
dinamicamente criar links para arquivos. Quando você atualizar, mudar ou deletar arquivos, os links das
bibliotecas de arquivos podem mudar automaticamente.

Crie uma pasta na pasta ZopeZoo chamada Files. Esta pasta contém todos os arquivos que você precisa
para distribuir para seus visitantes da web.

Na pasta Files crie alguns objetos arquivo vazios com nomes como DogGrooming ou
HomeScienceExperiments, apenas para dar-lhe alguns dados para trabalhar. Adicione algum título
descritivo para estes arquivos.

A DTML pode ajudar você economizar tempo fazendo a manutenção desta biblioteca. Crie um DTML
Method index_html na pasta Files para listar todos os arquivos na biblioteca:

84 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<h1>File Library</h1>

<ul>
<dtml-in expr="objectValues(File)">
<li><a href="&dtml-absolute_url;"><dtml-var title_or_id></a></li>
</dtml-in>
</ul>

<dtml-var standard_html_footer>

Visualize agora a pasta Files. Você deveria ver uma lista de links para os arquivos na pasta Files como
mostra a Figura 5.5.

Figura 5.5 - Página contendo a biblioteca de arquivos

Se você adicionar outro arquivo o Zope irá automaticamente ajustar a página da biblioteca de arquivo.
Você também poderia querer tentar mudar os títulos dos arquivos, atualizando novos arquivos, ou
deletando alguns dos arquivos.

A biblioteca de arquivos à medida que é colocada está funcional mas simples. A biblioteca não deixa você
saber quando um arquivo foi criado, e ela não deixa você ordenar os arquivos de qualquer forma. Vamos
fazer a biblioteca ficar melhor apresentada.

A maioria dos objetos do Zope tem o método bobobase_modification_time que retorna a última vez que
o objeto foi modificado. Podemos usar este método no método index_html da biblioteca de arquivo:

85 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<h1>File Library</h1>

<table>
<tr>
<th>File</th>
<th>Last Modified</th>
</tr>

<dtml-in expr="objectValues(File)">
<tr>
<td><a href="&dtml-absolute_url;"><dtml-var title_or_id></a></td>
<td><dtml-var bobobase_modification_time fmt="aCommon"></td>
</tr>
</dtml-in>

</table>

<dtml-var standard_html_footer>

O novo método da biblioteca de arquivo usa uma tabela HTML para mostrar os arquivos e suas
modificações.

Finalmente vamos adicionar a habilidade de classificar esta lista pelo nome do arquivo ou pela data da
modificação. Mudemos o método index_html de novo:

86 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<h1>File Library</h1>

<table>
<tr>
<th><a href="&dtml-URL0;?sort=name">File</a></th>
<th><a href="&dtml-URL0;?sort=date">Last Modified</a></th>
</tr>

<dtml-if expr="_.has_key(sort) and sort=='date'">


<dtml-in expr="objectValues(File)"
sort="bobobase_modification_time" reverse>
<tr>
<td><a href="&dtml-absolute_url;"><dtml-var title_or_id></a></td>
<td><dtml-var bobobase_modification_time fmt="aCommon"><td>
</tr>
</dtml-in>
<dtml-else>
<dtml-in expr="objectValues(File)" sort="id">
<tr>
<td><a href="&dtml-absolute_url;"><dtml-var title_or_id></a></td>
<td><dtml-var bobobase_modification_time fmt="aCommon"><td>
</tr>
</dtml-in>
</dtml-if>

</table>

<dtml-var standard_html_footer>

Agora visualize a biblioteca de arquivo e clique sobre os links File e Last Modified para classificar os
arquivos. Este método funciona com dois loops de classificação. Um usa a tag in para classificar um id
do objeto. O outro faz a classificação inversa em um método bobobase_modification_time do objeto. O
método index_html decide qual laço usar para procurar a variável sort. Se houver uma variável sort e se
ela possuir um valor date, então os arquivos são classificados pelo tempo de modificação. Fora isso os
arquivos são classificados por id.

Construindo um Livro de Visitas

Um livro de visitas é uma aplicação web comum e útil que permite que os visitantes no seu site deixem
mensagens. A Figura 5.6 mostra como o livro de visitas que você vai escrever se parecerá.

87 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 5.6 - Livro de visitas do Zoo.

Comece criando uma pasta chamada GuestBook na pasta raiz. Dê a esta pasta o título de Zope Zoo
Guest Book. A pasta GuestBook reterá as entradas e os métodos do livro de visitas para visualizar e
adicionar entradas. A pasta reterá tudo o que o livro de visitas precisa. Depois que o livro de visitas
estiver pronto você será capaz de copiar e colar ele em outro lugar do seu site para criar novos livros de
visitas.

Você pode usar o Zope para criar livros de visitas de várias formas, mas para este exemplo, você usará
uma das mais simples formas. A pasta GuestBook reterá muitos DTML Documents, um documento para
cada entrada do livro de visitas. Quando uma nova entrada é adicionada ao livro de visitas, um novo
documento é criado na pasta GuestBook. Para deletar uma entrada não desejada, apenas entre na pasta
GuestBook e delete o documento não desejado usando a interface de gerenciamento.

Vamos criar um método que mostra todas as entradas. Chame este método de index_html sendo esta a
visualização defualt da pasta GuestBook.

88 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<h2><dtml-var title_or_id></h2>

<!-- Provide a link to add a new entry, this link goes to the
addEntryForm method -->

<p>
<a href="addEntryForm">Sign the guest book</a>
</p>

<!-- Iterate over each DTML Document in the folder starting with
the newest documents first. -->

<dtml-in expr="objectValues(DTML Document)"


sort="bobobase_modification_time" reverse>

<!-- Display the date, author and contents of each document -->

<p>
<b>On <dtml-var bobobase_modification_time fmt="aCommon">,
<dtml-var guest_name html_quote null="Anonymous"> said:</b><br>

<dtml-var sequence-item html_quote newline_to_br>

<!-- Make sure we use html_quote so the users can't sneak any
HTML onto our page -->

89 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Este método varre todos os documentos na pasta e mostra cada um. Observe que este método assume
que cada documento terá uma propriedade guest_name. Se aquela propiedade não existe ou está vazia,
então o Zope usa Anonymous como o nome do visitante. Quando você cria um documento de entrada
você terá que ter certeza de setar esta propriedade. garantir que a propriedade pertença a esse grupo.

Depois, vamos criar um formulário que os visitantes do seu site usarão para adicionar uma nova entrada
no livro de visitas. No método index_html acima nós já criamos um link para este formulário. Na sua
pasta GuestBook crie um novo DTML Method chamado addEntryFor :

<dtml-var standard_html_header>

<p>Type in your name and your comments and we'll add it to the
guest book.</p>

<form action="addEntryAction" method="POST">


<p> Your name:
<input type="text" name="guest_name" value="Anonymous">
</p>
<p> Your comments: <br>
<textarea name="comments" rows="10" cols="60"></textarea>
</p>

<p>
<input type="submit" value="Send Comments">
</p>
</form>

<dtml-var standard_html_footer>

Agora quando você clica no link Sign Guest Book na página do livro de visitas você verá um formulário
permitindo que você digite um comentário. Este formulário coleta o nome do usuário e comenta e
submete esta informação a um método chamado addEntryAction.

Crie agora DTML Method addEntryAction na pasta GuestBook para lidar com o formulário. Este
formulário criará uma nova entrada de documento e retornará uma mensagem de confirmação:

90 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<dtml-call expr="addEntry(guest_name, comments)">

<h1>Thanks for signing our guest book!</h1>

<p><a href="<dtml-var URL1>">Return</a>


to the guest book.</p>

<dtml-var standard_html_footer>

Este método cria uma nova entrada chamando o método addEntry e retorna uma mensagem que avisa
o usuário que sua entrada foi adicionada.

A última parte restante do quebra-cabeça é escrever o script que criará um documento e setará seus
conteúdos e propriedades. Nós faremos isto em Python, considerando que é mais claro do que fazê-lo
em DTML. Crie um Script baseado em Python na pasta GuestBook chamado addEntry com parâmetros
guest_name e comments:

## Script (Python) "addEntry"


##parameters=guest_name, comments
##
"""
Create a guest book entry.
"""
# create a unique document id
id=entry_%d % len(context.objectIds())

# create the document


context.manage_addProduct['OFSP'].manage_addDTMLDocument(id,
title="", file=comments)

# add a guest_name string property


doc=getattr(context, id)
doc.manage_addProperty(guest_name, guest_name, string)

Esse script usa chamadas API do Zope para criar um DTML Document e criar uma propriedade naquele
documento. Este script executa o mesmo tipo de ação em script que você poderia fazer manualmente;

91 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

ele cria um documento, edita-o e seta uma propriedade.

O livro de visitas está quase terminado. Para usar o simples livro de visitas, apenas visite
http://localhost:8080/GuestBook/.

Uma coisa final é necessária para tornar o livro de visitas completo. Muito provavelmente sua política de
segurança não permitirá que visitantes anônimos do site criem documentos. Entretanto a aplicação do
livro de visitas deveria ser capaz de ser usado por visitantes anônimos. No Capítulo 7, Usuários e
Segurança, exploraremos este cenário mais completamente. A solução é conceder permissão especial
para o método addEntry para permitir que ele faça seu trabalho de criação de um documento. Você
pode fazer isto configurando o Proxy role do método para Manager. Isto significa que quando o método
roda ele funciona como se fosse rodado por um administrador sem ligação com quem está atualmente
rodando o método. Para mudar o proxy roles vá até a aba Proxy do método addEntry, como mostra a
Figura 5.7.

Figura 5.7 - Setando o proxy roles para o método addEntry.

Agora selecione Manager da lista proxy roles e clique Change.

Parabéns, você terminou uma aplicação web funcional. O livro de visitas está completo e pode ser
copiado para diferentes sites se você quiser.

Estendendo o Livro de Visitas para Gerar XML

Todos os objetos do Zope podem criar XML.É muito fácil criar XML com DTML. XML é apenas uma
maneira de descrever a informação. O poder do XML é que ele deixa você facilmente trocar informação
através da rede. Aqui está uma maneira simples que você poderia representar seu livro de visitas em
XML:

<guestbook>
<entry>
<comments>My comments</comments>
</entry>
<entry>
<comments>I like your web page</comments>
</entry>
<entry>
<comments>Please no blink tags</comments>
</entry>
</guestbook>

Este documento XML pode não ser complexo mas é fácil de gerar. Crie um DTML Method chamado
"entries.xml" na sua pasta livro de visitas com o seguinte conteúdo:

92 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<guestbook>
<dtml-in expr="objectValues(DTML Document)">
<entry>
<comments><dtml-var document_src html_quote></comments>
</entry>
</dtml-in>
</guestbook>

Como você pode ver, DTML é igualmente perita em criar XML porque está criando HTML.
Simplesmente encaixe tags DTML entre as tags XML e você está setado. A única coisa complicada que
você pode desejar fazer é setar o tipo do conteúdo da resposta para text/xml, que pode ser feito com
este código DTML:

<dtml-call expr="RESPONSE.setHeader(content-type, text/xml)">

O ponto da geração XML está em produzir dados em um formato que pode ser compreendido por
outros sistemas. Conseqüentemente você irá provavelmente querer criar XML em um formato existente
compreendido pelos sistemas que você quer se comunicar. No caso do livro de visitas um formato
razoável pode ser o formato XML RSS (Rich Site Summary). RSS é um formato desenvolvido pela
Netscape para seu site my.netscape.com, que tornou-se popular entre outros web logs e novos sites. O
site Zope.org usa DTML para construir um documento dinâmico RSS.

Parabéns! Você abilitou o XML do seu livro de visitas em apenas alguns minutos. Se você quiser crédito
extra, pesquise sobre RSS para compreender como mudar entries.xml para gerar RSS.

O Próximo Passo
Este capítulo mostra como simples aplicações web podem ser feitas.O Zope possui muito mais
características além dessas, mas estes simples exemplos devem ajudar você a começar a criar sites
complexos e bem gerenciados na web.

No próximo capítulo, nós veremos como o sistema de segurança faz com que o Zope trabalhe com
diferentes usuários ao mesmo tempo e permite que eles colaborem juntos nos mesmos projetos.

8. Usuário e Segurança
Este capítulo estuda como o Zope administra os usuários, autenticação, autorização, e
outros modos de segurança. Segurança é o centro do projeto no Zope e deve ser o centro
para as aplicações na web que você cria com o Zope.

Todas as aplicações para web precisam administrar a segurança. Administrar a segurança significa
controlar quem pode acessar sua aplicação, e determinar o que cada um pode fazer. Segurança não é
uma questão que pode ser adicionada para proteger o sistema. Pelo contrário, segurança deve ser um
importante elemento do projeto que você deve levar em conta quando constrói suas aplicações em
Zope.

Nesse capítulo você descobrirá como criar e administrar contas de usuários, e como controlar a maneira
que os usuários utilizam sua aplicação, criando políticas de segurança.

Introduzindo Segurança
Segurança controla o que os usuários do seu site podem fazer e como você e os outros podem manter

93 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

seu site. Se você considerar cuidadosamente a segurança você pode oferecer poderosos recursos para
seus usuários e permitir que um grande grupo de pessoas trabalhe conjuntamente com segurança para
manter seu site. Se você não levar em conta segurança, será difícil proporcionar aos seus usuários um
controle seguro e administrar seu site se tornará uma pesada e desorganizada tarefa. Seu site sofrerá
não somente com as coisas erradas que as pessoas normalmente não teriam intenção de fazer, mas será
difícil para você fornecer valor aos seus usuários e controle aos que administram seu site.

Zope entrelaça a segurança em quase todos aspectos da construção de aplicativos para web. Zope utiliza
o mesmo sistema de segurança para controlar o gerenciamento do Zope que você costuma usar para
criar usuários para sua aplicação.O Zope não faz distinção entre usar e gerenciar a aplicação. Isso pode
parecer confuso, mas na realidade isso permite que você possa alavancar o sistema de segurança do
Zope para as necessidades da sua aplicação.

Entrando e Saindo do Zope

Como vimos no Capítulo 2, "Usando o Zope" você loga no Zope através da URL de gerenciamento no seu
browser e digitando seu nome de usuário e senha. Nós também apontamos no Capítulo 2, "Usando o
Zope" que por causa de como a maioria dos web browsers funcionam, você deve fechar seu browser para
deslogar do Zope.

Se você tentar acessar um recurso protegido para o qual você não tem os privilégios de acesso, Zope
emitirá um aviso para logar. Isto pode acontecer mesmo se você já estiver logado. Em geral, não há
necessidade de logar no Zope se você apenas necessita utilizar os recursos públicos.

Autenticação e Autorização

Segurança no sentido amplo controla duas funções, autenticação e autorização. Autenticação significa
descobrir quem você é, e a autorização significa determinar o que você pode fazer.O Zope oferece
facilidades separadas para gerenciar o processo de reconhecimento de usuários e concessão de acesso a
ações controladas.

Quando você acessa recursos protegidos (por exemplo, visualizando uma página privada) o Zope pedirá
que você logue e procurará por sua conta de usuário. Este é o processo de autenticação. Note que o
Zope apenas autenticará você caso você queira acessar um recurso protegido; se você apenas acessar
recursos públicos o Zope e continuará assumindo que você é anônimo.

Uma vez autenticado, o Zope determina se você deve ou não ter acesso ao recurso protegido. Este
processo envolve duas camadas intermediárias entre você e o recurso protegido, roles (papéis) e
permissões. Usuários possuem papéis que descrevem o que podem fazer como "Author", "Manager", e
"Editor". Os objetos do Zope têm permissões que descrevem o que pode ser feito como, por exemplo
"Visualizar", "Apagar objetos", e "Gerenciar propriedades".

Políticas de segurança mapeiam os papéis para permissões; em outras palavras eles determinam quem
pode fazer o que. Por exemplo, uma política de segurança pode associar o papel "Manager" com a
permissão "Apagar objetos". Isso permite que os gerenciadores apaguem objetos. Neste caso Zope
autoriza usuário a executar ações protegidas.

Nas seguintes sessões examinaremos mais de perto a autenticação e a autorização e como efetivamente
setar as políticas de segurança. Primeiro você aprenderá sobre a autenticação utilizando usuários e User
Folders, e depois descobrirá como controlar a autorização com as políticas de segurança.

Autenticação e Gerenciamento de Usuários

94 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Um usuário Zope define uma conta de usuário. Um usuário Zope tem um nome, uma senha, e
opcionalmente, dados adicionais sobre quem utiliza o Zope. Para logar no Zope, você deve ter uma conta
de usuário. Vamos examinar como criar e gerenciar contas de usuários.

Criando Usuários em Pastas de Usuário

Para criar contas de usuários no Zope você adiciona usuários aos User Folders (Diretórios de Usuários).
No Capítulo 2, "Usando o Zope" você deveria já ter adicionado um usuário Manager no nível superior do
seu diretório de usuário.

Vamos criar um novo usuário para que seu colega possa ajudá-lo a administrar o seu site Zope. Vá para
a pasta raiz. Clique no user folder chamado acl_users. O user folder contém objetos usuários que
definem as contas dos usuários do Zope. Clique no botão Add para criar um novo usuário.

Figura 6.1 - Adicionando um usuário ao user folder

O formulário na Figura 6.1 permite que você defina o usuário. Digite um nome do usuário para o seu
colega no campo Name, por exemplo "michel". O nome do usuário pode conter letras, espaços e
números. O nome do usuário é case sensitive (sensível ao contexto).

Escolha uma senha para seu colega e digite-a nos campos Password e Confirm. Definiremos as coisas de
tal maneira que o seu colega poderá mudar a sua senha mais tarde quando logar. Você deverá usar uma
senha do tipo "mude-me" para ajudá-lo a lembrar de mudar sua senha.

O campo Domains possibilita que você restrinja domínios da Internet dos quais o usuário pode logar.
Isto lhe possibilita adicionar outro controle de segurança para sua conta. Por exemplo, se você deseja
que seu colega sempre logue do trabalho você poderá entrar com o seu domínio do trabalho, por
exemplo "myjob.com", no campo Domains. Você pode especificar múltiplos domínios separados por
espaços para permitir aos usuários logar de vários domínios. Por exemplo se você decide que seu colega
deveria ser capaz de gerenciar o Zope do domínio da sua casa também, você pode setar o campo
domains para "myjob.com myhome.net". Você também pode usar números de IP com asteriscos para
indicar os números nos quais esses endereços estão contidos, ao invés de nomes de domínios para
especificar domínios. Por exemplo, "209.67.167.*" englobará todos os endereços IP que começam com
"209.67.167".

A lista de seleção Roles indica que papéis o usuário deveria ter. Em geral, usuários que executam tarefas
de gerenciamento deveriam ter o papel Manager. No caso do seu colega, selecione o papel Manager. O
papel Owner não é apropriado na maioria dos casos porque um usuário é normalmente um proprietário
de um objeto específico, não um proprietário em geral. Analisaremos a propriedade mais tarde neste
capítulo. Nós também veremos mais tarde como você pode definir seus próprios papéis como Editor
and Reviewer.

95 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Para criar o novo usuário clique no botão Add. Você deveria ver um novo objeto usuário na user folder.

Editando Usuários

Você pode editar usuários existentes clicando neles. Isso mostra um formulário muito similar ao
formulário que você usou para criar um usuário. De fato você pode controlar as mesmas opções que
acabamos de discutir deste formulário. Depois que seu colega logar na conta que você criou para ele, ele
deve ir para esta tela de gerenciamento e mudar sua senha aqui.

Como todas as funções de gerenciamento do Zope, a função editar usuários está protegida pela política
de segurança. Um usuário pode apenas mudar a senha dele se ele tiver a permissão Manage Users, que
todos os administradores têm por default.

Então por default para um administrador no user folder dado, é possível mudar outras contas de
administradores se ambos foram definidos no mesmo user folder. ] Isto nem sempre é o que se deseja.
Mais tarde analisaremos um meio de evitar esse problema em potencial. Contudo, fique tranqüilo pois
não é possível alguém descobrir sua senha da interface de gerenciamento. Outro administrador pode ter
acesso para mudar sua senha, mas não pode descobrir sua senha atual sem alterá-la.

Em geral, os user folders funcionam como pastas normais do Zope; você pode criar, editar e apagar os
objetos contidos. Porém, os user folders não são tão poderosas como as pastas normais. Você não pode
recortar e colar uma pasta, você não pode criar nada a não ser um usuário numa pasta de usuários. Você
não pode recortar e colar em um user folder, e você não pode criar nada além de usuários em um user
folder.

Para apagar um usuário existente do user folder, selecione o usuário e clique no botão Delete. Lembre-se
que assim como todas as outras ações no Zope, isto pode ser desfeito se você cometeu um erro.

Definindo a Localização do Usuário

O Zope pode conter vários user folders em diferentes locais na hierarquia dos objetos. Um usuário do
Zope não pode acessar recursos acima do user folder no qual ele está definido. O local onde a conta do
usuário está definida determina quais recursos do Zope você pode acessar.

Se sua conta estiver definida no user folder no diretório raiz, você tem acesso ao folder raiz. É onde
provavelmente a sua conta atual está definida. No entanto, você pode definir usuários em qualquer
pasta do Zope.

Considere o caso de um user folder em /BeautySchool/Hair/acl_users. Suponha que o usuário Ralph


Scissorhands está definido nesta pasta. Ralph não pode logar no Zope acima da pasta /BeautySchool
/Hair. Efetivamente, a visualização do sitem do Zope de Ralph está limitada às coisas na pasta
BeautySchool/Hair e abaixo dela. Apesar dos papéis reservados a Ralph, ele não pode acessar recursos
protegidos acima da sua localização.

Utilizando essa técnica é fácil construir políticas de segurança simples. Um dos padrões de
gerenciamento mais comuns do Zope é colocar determinados objetos juntos numa pasta e então criar
um user folder naquela pasta para definir os responsáveis por aqueles objetos.

Por exemplo, suponha que as pessoas na sua organização usem uniformes. Você está criando uma
intranet que fornece informações sobre sua organização, inclusive informações sobre os uniformes.
Você poderia criar uma pasta uniforms em algum lugar no site Zope da intranet. Nessa pasta você
poderia colocar objetos como fotos dos uniformes e descrições de como os vestir e limpar. Depois você
poderia criar um user folder no folder uniforms e criar uma conta para o costureiro chefe. Quando um
novo estilo de uniforme ficar pronto o costureiro não precisará pedir ao webmaster para atualizar o site,

96 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

ele(a) mesmo(a) poderá atualizar sua pópria sessão do site sem incomodar ninguém. Além disso, o
costureiro chefe não pode logar em nenhuma pasta acima de uniforms, o que significa que o costureiro
chefe não pode gerenciar outros objetos a não ser os da pasta uniforms.

Este padrão de segurança é chamado de delegação, e é muito comum nas aplicações do Zope. Pela
delegação de diversas áreas do seu site Zope para diferentes usuários, você pode distribuir a
responsabilidade da administração do site a um pequeno grupo de administradores para diferentes
grupos de usuários específicos. Mais tarde nesse capítulo analisaremos outros padrões de segurança.

Trabalhando com Pastas de Usuário Alternativas

Pode ser que você não queira gerenciar sua conta de usuário através da web. Seja porque você já possui
um banco de dados de usuários, ou porque você deseja utilizar outras ferramentas para manter as
informações da sua conta.O Zope permite utilizar todos os tipos de técnicas de autenticação com user
folders alternativos. Você pode encontrar muitos user folders alternativos no web site do Zope
http://www.zope.org/Products/user_management. No momento em que este livro foi escrito havia 19
user folders alternativos. Aqui está uma exemplificação dos user folders alternativos mais populares
disponíveis.

LoginManager

Este é um flexível e poderoso user folder que lhe permite adicionar seus próprios métodos de
autorização. Por exemplo, você pode utilizar LoginManager para autenticar-se de um banco de dados.

etcUserFolder

Esse diretório de usuário autentica usando o padrão dos estilos de arquivos Unix /etc/password

LDAPAdapter

Esse ditetório de usuário lhe permite autenticar-se de um servidor LDAP.

NTUserFolder

Esse diretório de usuário autentica-se a partir de contas de usuários NT. Ele apenas funciona se você
está rodando o Zope em Windows NT ou Windows 2000.

Alguns diretórios de usuários oferecem controles alternados de logar e deslogar como logar em
formulários web, mais do que controles de autorizações HTTP do browser. Apesar desta variedade,
todos os diretórios de usuários usam o mesmo modo de logar no procedimento pedindo a você as
credenciais quando você acessa um recurso protegido.

Enquanto a maioria dos usuários são gerenciados com diretórios de usuários de um tipo ou de outro, o
Zope possui algumas contas especiais de usuário que não são gerenciadas com esse diretório de
usuário.

Contas Especiais do Usuário

O Zope oferece três contas especiais de usuários que não são definidas com diretórios de usuários, o
anonymous user(usuário anônimo), o emergency user(usuário de emergência) e o initial
manager(administrador inicial). O usuário anônimo é utilizado freqüentemente, enquanto as contas
do usuário de emergência e administrador inicial são raramente utilizadas mas é importante conhecer e
saber.

97 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Usuário Anônimo do Zope

O Zope tem embutida, uma conta de usuário para visitantes, o usuário anônimo. Se você não possui
uma conta de usuário no Zope, você será considerado como um usuário anônimo.

O usuário anônimo tem controle de segurança como qualquer outro, ele tem o papel Anonymous. Por
default o papel Anonymous apenas pode acessar recursos públicos, e não pode modificar nenhum
objeto do Zope. Você pode modificar essa política, mas ma maioria das vezes você achará as
configurações default da segurança do usuário anônimo adequadas.

Como já mencionamos anteriormente no capítulo, você deve tentar acessar um recurso protegido para
que o Zope autentique você. A conclusão é que mesmo você possuindo uma conta de usuário, o Zope
considerará você anônimo até que você se logue.

Usuário Emergencial do Zope

Zope possui uma conta de usuário especial para uso de emergência chamado emergency user. Nós
discutimos o usuário de emergência brevemente no Capítulo 2, "Usando o Zope". O usuário de
emergência não é restringido pelas configurações normais de segurança. No entanto, o usuário de
emergência não pode criar novos objetos com exceção de novos objetos de usuário.

O usuário de emergência é realmente útil para duas coisas: ordenar permissões, e criar contas de
administrador. Como vimos no Capítulo 2, "Usando o Zope" você pode logar como usuário de
emergência para criar a conta de administrador quando não existe nenhuma. Depois de criada a conta
de administrador você deveria deslogar como usuário de emergência e logar-se novamente como
administrador.

Outro motivo para utilizar a conta do usuário de emergência é se você ficou trancado fora do Zope por
remover permissões que precisava para gerenciar o Zope. Neste caso logue como usuário de emergência
e certifique-se que sua conta de administrador possui as permissões de Visualizar telas de
gerenciamento(View management screens) e 'Mudar permissões' (Change permissions). Então
deslogue e logue na sua conta de administrador e você deveria ter acesso suficiente para consertar
outras coisas que estão erradas.

Um problema comum com usuário de emergência é a tentativa de criar um novo objeto.

Figura 6.2 Erro causado pela tentativa de criar um novo objeto quando logado como Usuário de
Emergência.

O erro da Figura 6-2 notifica que o usuário de emergência não pode criar novos objetos. O motivo disso
é um pouco complexo mas se tornará mais claro no capítulo que falamos sobre posse. A versão mais

98 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

curta da história é que seria inseguro para o usuário de emergência criar objetos sem que eles sejam
submetidos à mesma segurança que os outros objetos.

Criando um Usuário de Emergência

Diferente da conta de usuário normal que é definida pela web, a conta de usuário de emergência é
definida no sistema de arquivos. Você pode mudar a conta de Usuário de Emergência editando o
arquivo access no diretório do Zope. Zope possui uma linha de comando útil, zpasswd.py para gerenciar
a conta de Usuário de Emergência. Rode zpasswd.py passando o caminho do arquivo access :

$ python zpasswd.py access

Username: superuser
Password:
Verify password:

Please choose a format from:

SHA - SHA-1 hashed password


CRYPT - UNIX-style crypt password
CLEARTEXT - no protection.

Encoding: SHA
Domain restrictions:

O script zpasswd.py guia você pelo processo de criação de uma conta de Usuário de Emergência. Note
que quando você digita a sua senha ela não é mostrada na tela. Você também pode rodar zpasswd.py
sem parâmetros para obter uma lista das opções de linhas de comando.

Administrador Inicial do Zope

A conta do Administrador Inicial é criada pelo instalador do Zope para que você possa logar no Zope
pela primeira vez. Quando você instala Zope pela primeira vez você deveria enxergar uma mensagem
como essa:

99 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

creating default inituser file


Note:
The initial user name and password are admin
and IVX3kAwU.

You can change the name and password through the web
interface or using the zpasswd.py script.

Assim são informados o nome do administrador inicial e a senha. Você pode usar essa informação para
logar no Zope pela primeira vez como administrador. A partir daí você cria contas de usuário adicionais.

Os usuários iniciais são definidos de modo similar ao usuário de emergência; ele são definidos num
arquivo no sistema de arquivos chamado inituser. O programa zpasswd.py pode ser utilizado para
editar esse arquivo do mesmo modo que é usado para editar o arquivo access do usuário de emergência:

$ python zpasswd.py inituser

Username: bob
Password:
Verify password:

Please choose a format from:

SHA - SHA-1 hashed password


CRYPT - UNIX-style crypt password
CLEARTEXT - no protection.

Encoding: SHA
Domain restrictions:

Isso criará um novo usuário inicial chamado "bob" e setará sua senha (a senha não é mostrada na tela
quando você a digita). Quando o Zope inicia, ele verifica o usuário neste arquivo e certifica-se que ele
pode logar no Zope. Normalmente, os usuários iniciais são criados para você pelo instalador do Zope, e
você não deve se preocupar em mudá-los. Se você deseja criar usuários adicionais, você o fará pela
interface de gerenciamento Zope da web.

Até aqui nós mostramos como usuário e diretórios de usuários controlam a autenticação. Depois
veremos como controlar autorização com as políticas de segurança.

100 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Autorização e Gerenciamento de Segurança


As políticas de segurança do Zope controlam a autorização; elas definem quem pode fazer o que.
Políticas de segurança descrevem os papéis e suas respectivas permissões. Papéis identificam classes de
usuários, e as permissões protegem objetos. Assim, políticas de segurança definem quais classes de
usuários (papéis) podem tomar quais tipos de ações (permissões) numa dada parte do site.

Mais do que afirmar qual usuário específico pode tomar qual ação específica em qual objeto específico, o
Zope lhe permite definir quais tipos de usuários podem tomar quais tipos de ação em quais áreas do
site. Esse tipo de generalização torna suas políticas de segurança mais simples e mais poderosas. É claro
que você pode fazer exceções às suas políticas para usuários específicos, ações e objetos.

Nas seguintes seções nós examinaremos mais de perto papéis, permissões a políticas de segurança com
a visão de construir políticas de segurança simples e eficazes.

Trabalhando com Funções

Os usuários do Zope possuem papéis (roles) que definem que tipo de ações eles podem tomar. Funções
definem classes de usuários como Manager, Anonymous, e Authenticated.

Funções são parecidas com grupos UNIX em que eles abstraem grupos de usuários. E como grupos
UNIX, usuários Zope têm mais de uma função.

Funções facilitam o gerenciamento da segurança.Ao invés de definir o que cada usuário pode fazer, você
pode simplesmente setar algumas políticas de segurança para diferentes funções de usuários.

O Zope vem com quatro funções embutidas:

Manager (Administrador)

Essa função é usada para usuários que executam funções padrões de gerenciamento do Zope, como
criar e editar pastas e documentos do Zope.

Anonymous (Anônimo)

O Usuário Anônimo do Zope tem essa função. Essa função deve ser autorizada para visualizar recursos
públicos. Em geral essa função não deve ter permissão para modificar objetos do Zope.

Owner (Proprietário)

Essa função é associada automaticamente aos usuários no contexto em que esses objetos são criados.
Falaremos de posse posteriormente neste capítulo.

Authenticated (Autenticado)

Essa função é associada automaticamente aos usuários que oferecem credenciais de autenticação
válidas. Essa função significa que o Zope "sabe" particularmente quem é o usuário.

Para sites básicos do Zope você pode usar Manager and Anonymous. Para sites mais complexos você
pode criar suas próprias funções para classificar seus usuários em diferentes grupos.

Definindo Funções

Para criar uma nova função vá para a aba Security e role a barra de rolagem para baixo até o fim da tela.

101 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Digite o nome da nova função no campo User defined Function e clique Add Role. Nomes de funções
devem ser curtos, descrição em uma ou duas palavras do tipo de usuário como "Author", "Site
Architect", ou "Designer". Você deve escolher os nomes para as funções relevantes para a sua aplicação.

Você pode verificar que sua função foi criada, percebendo que há uma nova coluna de função para a sua
função, no topo da tela. Você também pode deletar uma função selecionando a função da lista de
seleção no nível mais baixo da tela de segurança e clicando o botão Delete Role. Você apenas pode
deletar suas próprias funções definidas, você não pode deletar nenhuma das funções do "estoque"
(existentes) que vem com Zope.

Você deve reparar que as funções podem ser usadas no nível em que são definidas e abaixo dele na
hierarquia dos objetos. Por isso, se deseja criar uma função que é apropriada para seu site inteiro, crie-a
no folder raiz.

Em geral, funções devem ser aplicáveis para grandes seções do seu site. Se você tem a intenção de criar
uma função para restringir acesso a algumas seções de seu site, existem outras maneiras muito
melhores de alcançar o mesmo efeito. Por exemplo, você pode simplesmente mudar as propriedades de
segurança para as funções já existentes na pasta que você quer proteger, ou pode definir usuários
abaixo na hierarquia de objetos para limitar seu acesso. Mais tarde, no capítulo, examinaremos mais
exemplos de como definir políticas de segurança.

Entendendo Funções Locais

Local Roles (Funções locais) são uma característica avançada da segurança do Zope. Usuários podem
ganhar funções extra quando trabalham com certos objetos. Se um objeto tem uma função local
associada com um usuário então aquele usuário adquire aquelas funções adicionais enquanto trabalha
com aquele objeto.

Por exemplo, se um usuário possui um objeto então ele geralmente ganha a função local de Owner
enquanto estiver trabalhando com aquele objeto. Um usuário não poderia ter a possibilidade de editar
DTML Methods em geral, mas para DTML Methods que ele possui, o usuário poderia ter acesso para
editar DTML Methods através da função local Owner.

Funções locais são um controle de segurança muito mais avançado e não são sempre necessárias. O
controle automático do Zope da função local Owner é provavelmente o único lugar onde você encontra
funções locais.

A principal razão de você querer controlar manualmente as funções locais é para dar a um usuário
especial um acesso especial a um objeto. Em geral, você deve evitar setar segurança para um usuário
específico, se possível. É mais fácil gerenciar configurações de segurança que controlam grupos de
usuários ao invés de usuários individuais.

Entendendo Permissões

Permissões definem quais ações podem ser tomadas com objetos Zope. Assim como funções abstraem
usuários, permissões abstraem objetos. Por exemplo, muitos objetos do Zope, incluindo DTML
Methods e DTML Documents podem ser visualizados. Essa ação é protegida pela permissão View
(Visualizar).

Algumas permissões são apenas relevantes para um tipo de objeto, por exemplo, a permissões Change
DTML Methods (Mudar Métodos DTML) apenas protege DTML Methods. Outras permissões protegem
muitos tipos de objetos, como permissões FTP access (Acesso FTP) e WebDAV access (Acesso WebDAV)
que controlam se objetos estão disponíveis via FTP e WebDAV.

102 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Você pode descobrir que permissões estão disponíveis num dado objeto indo para a aba de
gerenciamento Security (Segurança).

Figura 6.3 - Configurações de segurança para um objeto mail host.

Como você pode ver na Figura 6.3, um mail host tem uma paleta limitada de permissões disponíveis.
Compare isso com as muitas permissões que você vê quando seta a segurança num folder.

Definindo Políticas de Segurança

Políticas de Segurança são onde as funções encontram permissões. Políticas de segurança definem
quem pode fazer o que numa dada parte do site.

Você pode setar políticas de segurança em quase todos os objetos do Zope. Para setar a política de
segurança, vá para a aba Security. Por exemplo, clique na aba de segurança do folder raiz.

Figura 6.4 - Políticas de segurança para o folder raiz

Há muito acontecendo na Figura 6.4. No centro da tela há uma grade de check boxes. As colunas
verticais da grade representam funções e as linhas horizontais da grade representam permissões.
Marcando um check box da interseção de uma permissão e uma função concede aos usuários com
aquela função a possibilidade de realizar ações protegidas por aquela permissão.

Você notará que Zope vem com a política de segurança default que permite aos administradores
executar a maioria das tarefas e aos usuários anônimos, executar apenar algumas. Você pode adaptar
essa política as suas necessidades, mudando as propriedades de segurança no folder raiz.

103 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Por exemplo, você pode tornar seu site privado desabilitando a permissão de usuários anônimos a
capacidade de visualizar qualquer página web. Para fazer isso desabilite a permissão View para todos os
usuários anônimos onde há intersessão com a função Anonymous. Você pode tornar seu site inteiro
privado mudando essa política de segurança no folder raiz. Se você quer que uma parte de seu site seja
privado, você pode fazer essa modificação no folder que deseja tornar privado.

O exemplo aponta um importante ponto sobre as políticas de segurança: elas controlam a segurança
para uma dada parte do site apenas. A única política de segurança global está no folder raiz.

Aquisição de Políticas de Segurança

Como interagir diferentes políticas de segurança? Nós vimos que você pode criar políticas de segurança
em objetos diferentes, mas o que determina quais políticas controlam quais objetos? A resposta é que os
objetos utilizam sua própria política de segurança se possuírem uma, além disso, eles adquirem as
políticas de segurança de seus pais num processo chamado de aquisição.

Aquisição é um mecanismo em Zope para compartilhar informações entre objetos contidos num folder
ou em seus subfolders. O sistema de segurança do Zope utiliza a aquisição para compartilhar políticas
de segurança para que o acesso possa ser controlado de folders de níveis superiores.

Você pode controlar a aquisição de políticas de segurança da aba Security. Note que há uma coluna de
check boxes na esquerda da tela rotulada Acquire permission settings (Adquirir propriedades de
permissões). Cada check box nessa coluna é marcado por default. Isto significa que a política de
segurança vai adquirir as propriedades dos pais para cada permissão das propriedades da função
adicionadas de qualquer propriedade especificada nessa tela. Tenha em mente que para o folder raiz
(que não possui um pai de onde possa adquirir propriedades) a coluna de check box mais da esquerda
não existe.

Então por exemplo, suponha que você quer tornar esse diretório privado. Como vimos antes, isso
apenas requere a negação da permissão View da função Anonymous. Mas como você pode ver na tela, a
função Anonymous não possui a permissão View, e ainda esse diretório não é privado. Por que isso? A
resposta é que a opção Acquire permission settings está marcada para a permissão View. Isto significa
que as propriedades atuais são aumentadas pelas políticas de segurança do pai deste diretório. Em
algum lugar, acima desse diretório a função Anonymous deve ser associada a permissão View . Você
pode verificar isso examinando as políticas de segurança dos pais deste folder. Para tornar o diretório
privado nós não devemos selecionar a opção Acquire permission settings . Isto assegurará que apenas
as propriedades explicitadas nessa política tenham efeito.

Em geral, você deveria sempre adquirir propriedades de segurança a não ser que possua uma razão
específica para não o fazer. Isso tornará o gerenciamento de segurança muito mais fácil, pois a maioria
do trabalho pode ser feita do folder raiz.

A seguir consideraremos alguns exemplos de como criar políticas de segurança eficazes usando as
ferramentas sobre as quais você aprendeu neste capítulo.

Padrões de Uso de Segurança


Os conceitos básicos da segurança Zope são simples: funções e permissões combinam para criar
políticas de segurança e as ações dos usuários são controladas por essas políticas. No entanto, essas
simples ferramentas podem ser utilizadas de diferentes maneiras. Isto pode tornar o gerenciamento de
segurança complexo. Vamos dar uma olhada em alguns padrões básicos para gerenciamento de
segurança que fornecem bons exemplos de como criar uma arquitetura de segurança fácil de gerenciar e
eficaz.

104 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Regras de Manuseio de Segurança

Aqui estão algumas simples linhas de direção para o gerenciamento de segurança do Zope. Esses
padrões de segurança que seguem oferecem receitas mais específicas, mas elas lhe darão algum
conselho quando você encontrar território desconhecido.

1. Defina usuários no seu nível mais alto de controle, mas não no mais alto de todos.
2. Agrupe objetos que deveriam ser gerenciados pelas mesmas pessoas juntas nos folders.
3. Mantenha isso simples.

As regras 1 e 2 possuem um forte relação. Ambas são partes de uma regra mais geral para arquitetura de
sites Zope. Em geral, você pode refazer seu site para localizar recursos e usuários relativos uns aos
outros. Garante-se que nunca é possível forçar recursos e usuários para uma severa hierarquia. No
entanto um arranjo bem planejado de recursos e usuários nas pastas e sub-pastas ajudam muito.

Apesar da arquitetura do seu site, tente manter as coisas simples. Quanto mais você complica suas
propriedades de segurança, mais tempo precisará para entendê-las, gerenciá-las e ter certeza de que
são eficazes. Por exemplo, restrinja o número de novas funções criadas e tente usar a aquisição de
políticas de segurança para limitar o número de locais de segurança dos quais terá que definir
explicitamente. Se achar que suas políticas de segurança, usuários e funções estão se tornando muito
complexos, você deve repensar o que estiver fazendo, provavelmente existe um jeito mais simples.

Políticas Global e Local

O padrão mais básico de segurança do Zope é definir uma política de segurança global no folder raiz e
adquirir essa política em todo o lugar. Então, conforme a necessidade, você pode adicionar políticas
adicionais mais a fundo na hierarquia de objetos para aumentar a política global. Tente limitar o número
de locais nos quais se ignora a política global. Se você achar que deve fazer mudanças no número de
locais, considere a consolidação de objetos naqueles, locais separados, para o mesmo folder para que
você possa modificar as propriedades de segurança num só lugar.

Você deveria optar por adquirir as configurações de permissões nas suas sub-políticas a não ser que sua
sub-política é mais restrita que a política global. Neste caso, você deveria desabilitar essa opção para a
permissão que deseja restringir.

O padrão simples tomará conta da maioria de segurança que você necessita. Suas vantagens são que é
fácil de gerenciar e entender.Estas são características extremamente importantes para qualquer
arquitetura de segurança.

Delegando Controle para Gerenciadores Locais

Esse padrão de segurança é bem central em Zope e é a parte que dá ao Zope um "gostinho único". Zope
encoraja você a coletar recursos semelhantes e juntar em pastas e então criar contas de usuários nesse
diretório para gerenciar seus conteúdos.

Digamos que você deseja delegar o gerenciamento da pasta Sales em seu site Zope para o novo
administrador de vendas da web, Steve. Primeiro você não quer que Steve mexa com nenhuma outra
pasta a não ser a pasta Sales, então você precisa adicionar ele na pasta acl_users no folder raiz. Ao invés
de criar um novo user folder na pasta Sales.

Agora você pode adicionar Steve no user folder em Sales e dar lhe a função de Manager. Steve pode
logar diretamente no diretório Sales, para gerenciar sua área de controle, direcionando seu browser
para: http://www.zopezoo.org/Sales/manage.

105 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 6.5 - Gerenciando o diretório Sales

Note na Figura 6.5, a árvore de navegação à esquerda, mostra que Sales é o folder raiz. O administrador
local definido nesse diretório nunca poderá logar em nenhum diretório acima de Sales e então ele é
mostrado como o diretório topo.

Esse padrão é muito poderoso visto que pode ser aplicado recursivamente. Por exemplo, Steve pode
criar um subdiretório para marketing de vendas multi-nível. Depois ele pode criar um user folder no
diretório de marketing de vendas multi-nível para delegar o controle desse diretório para administrador
de marketing de vendas multi-nível. E assim por diante. Essa é a receita para sites gigantes gerenciados
por milhares de pessoas.

A beleza desse padrão é que os administradores de níveis mais altos não necessitam se preocupar muito
com o que seus subordinados fazem. Se preferirem, podem prestar muita atenção, mas podem
seguramente ignorar detalhes desde que saibam que seus subordinados não podem fazer modificações
fora da sua área de controle e eles sabem que as suas propriedades de segurança serão adquiridas.

Diferentes Níveis de Acesso com Funções

O padrão de administrador local é poderoso e escalável, mas ele fornece uma boa visão da segurança.
Ou você possui acesso ou não. Algumas vezes você precisa de um controle mais delineado. Muitas vezes
você terá recursos que precisam ser usados por mais de um tipo de pessoa. Funções irão lhe oferecer
uma solução para este problema. Funções permitem a você definir classes de usuários e setar as
políticas de segurança para eles.

Antes da criação de novas funções certifique-se que você realmente precisa delas. Suponha que você
tem um site que publica artigos. O público lê artigos e os administradores editam e publicam artigos,
mas há uma terceira classe de usuários que são autores de artigos, mas não os editam, nem os publicam.

Uma solução seria criar um diretório de autores onde a conta do autor é criada e lhe é dada função
Manager. Este diretório seria privado e por tanto visualizado apenas por administradores. Artigos
poderiam ser escritos nesse diretório e os administradores poderiam mover artigos para fora do
diretório para publicá-los. Essa é uma solução razoável, mas ela exige que o autor trabalhe apenas numa
parte do site e isso exige um trabalho extra dos administradores para mover artigos dos diretórios dos
autores. Também, considere que estes problemas que resultam em o autor querer atualizar um artigo
que foi movido do seu diretório.

A melhor solução é adicionar uma função Autor. Adicionar uma função nos ajuda porque permite
acessar controles não baseados na localização. Então no nosso exemplo, nós tornamos possível,
adicionando uma função de autor, a elaboração, edição e publicação de qualquer lugar do site. Nós

106 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

podemos determinar uma política global de segurança que dá ao autor a habilidade de criar e escrever
artigos, mas não garante a permissão para publicar ou editá-los.

Funções lhe permitem controlar o acesso baseado em quem é o usuário, não apenas baseado em onde
ele é definido.

Controlando Aceesso a Locais com Funções

Funções podem lhe ajudar a superar um outro sutil problema com o padrão de administrador local. O
problema é que o padrão do administrador local necessita de uma severa hierarquia de controle. Não há
condições de permitir dois diferentes grupos de pessoas acessarem os mesmos recursos sem um deles
ser administrador do outro grupo. Por outro lado, não há como usuários definidos numa parte do site
gerenciar recursos de uma outra parte do site.

Vejamos um exemplo para ilustrar a segunda limitação do padrão de administrador local. Suponha que
você está rodando um grande site para uma companhia farmacêutica. Você tem duas classes de
usuários, cientistas e vendedores Em geral, os cientistas e os vendedores gerenciam diferentes recursos
do site. Porém, suponha que há alguma coisa que ambos os tipos de pessoas necessitam gerenciar, como
anúncios de propaganda que contêm complexas advertências cientificas. Se definirmos nossos
cientistas no diretório Science e vendedores no diretório Sales, onde então deveremos colocar o
diretório AdsWithComplexWarnings? A não ser que o diretório Science esteja dentro do diretório Sales
e vice versa, não há lugar para o diretório AdsWithComplexWarnings, em que ambos os cientistas e
vendedores possam gerenciá-lo. Isso não é uma boa solução política ou prática ter os vendedores
gerenciando os cientistas e vice versa; o que pode ser feito?

A solução é utilizar funções. Você deve criar duas funções num nível acima dos diretórios Science e
Sales, chamadas de Scientist e SalesPerson. Então, invés de definir cientistas e vendedores em seus
próprios diretórios, defina-os acima na hierarquia de objetos, para que ambos possam ter acesso ao
diretório AdsWithComplexWarnings.

Quando você cria usuários nesse nível mais alto, você não deveria lhes dar a função de Manager, mas
sim, Scientist ou SalesPerson como apropriado. Então deve setar as políticas de segurança. No diretório
Science, a função de Scientist deve ser equivalente ao controle do Manager. No diretório Sales , o
SalesPerson deve ter as mesmas permissões que o Manager. Finalmente, no diretório
AdsWithComplexWarnings, você deve dar para ambos Scientist e SalesPerson as permissões
adequadas. Desta forma, as funções são usadas não para determinar diferentes níveis de acesso, mas
para fornecer diferentes localizações baseadas em quem você é.

Outra situação comum, quando você poderia quere empregar esse padrão é quando você não pode
definir seus administradores localmente. Por exemplo, você pode estar usando um user folder
alternativo que exige que todos os usuários sejam definidos no folder raiz. Neste caso, você poderia
querer tornar amplo o uso de funções para limitar o acesso a diferentes localizações baseadas nas
funções.

Isso traz à tona a discussão sobre padrões de segurança. Por agora, você deveria te uma razoável
compreensão de como utilizar user folders, funções e políticas de segurança para delimitar uma
arquitetura de segurança razoável para a sua aplicação. A seguir, veremos dois fluxos de segurança
avançados, como executar checagem de segurança e proteger o conteúdo executável.

Executando Controle de Segurança


Na maioria das vezes, você não precisa executar nenhuma checagem de segurança. Se um usuário tentar
executam uma operação protegida, Zope o avisará para logar. Se usuário não possui as permissões

107 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

adequadas para acessar um recurso protegido, Zope lhe negará o acesso. Porém, algumas vezes você
pode querer executar manualmente checagem de segurança. A principal razão disso é para limitar as
opções que você oferece a um usuário para o que eles são autorizados. Isso não previne que um usuário
mal intencionados tentem acessar ações protegidas, mas reduz as frustrações do usuário não lhe
disponibilizando as opções que não irão funcionar.

A pergunta mais comum da pesquisa de segurança é se o usuário atual possui uma dada permissão. Por
exemplo, suponha que sua aplicação permite alguns usuários atualizar arquivos. Essa ação deve ser
protegida pela permissão padrão do Zope "Add Documents, Images, and Files". Você pode testar vendo
no DTML se o usuário possui essa permissão ou não:

<dtml-if expr="_.SecurityCheckPermission(
Add Documents, Images, and Files, this())">

<form action="upload">
...
</form>

</dtml-if>

A função SecurityCheckPermission pega dois argumentos, um nome de permissão e um objeto. Nesse


caso, nós passamos this() como o objeto que é a referência para o objeto atual. Passando o objeto
corrente, nós asseguramos que funções locais são levadas em conta quando testado se o usuário possui
a permissão dada.

Você pode encontrar sobre o usuário atual acessando o usuário em DTML. O usuário atual é um objeto
Zope como qualquer outro e você pode executar ações nele, usando métodos definidos na
documentação API.

Suponha que você queira mostrar o nome do usuário atual numa página web para personalizar a página.
Você pode fazer isto facilmente em DTML:

<dtml-var expr="_.SecurityGetUser().getUserName()">

Você pode perceber (retrieve) o usuário atual logado com a função DTML SecurityGetUser. Esse
fragmento DTML testa o usuário atual chamando o método getUserName no atual objeto usuário. Se o
usuário não está logado retornará o nome de usuário anônimo, que é Anonymous User.

A seguir veremos outro fluxo avançado que afeta a segurança de DTML e scripts.

Fluxo de Segurança Avançado: Posse e Conteúdo


Executável
Até agora nos vimos o básico da segurança Zope. O que resta são conceitos avançados de Posse e
conteúdo executável. Zope usa posse para associar objetos com usuários que os criaram, e o conteúdo
executável refere-se a objetos como scripts, DTML Methods e Documents que executam o código do
usuário.

108 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Para sites pequenos com usuários confiáveis você pode ignorar com segurança esse fluxos avançados de
segurança. Porém, para sites grandes, onde se autoriza usuários não confiáveis a criar e gerenciar
objetos Zope, é importante compreender a posse e o conteúdo executável.

O Problema: Ataque do Cavalo de Tróia

O cenário básico que motiva tanto a posse quanto o controle de conteúdo executável é o ataque do
Cavalo de Tróia. Cavalo de Tróia é um ataque em um sistema que opera enganando o usuário para que
este tome uma ação potencialmente danosa. Um Cavalo de Tróia típico se mascara como um programa
benigno que causa danos quando você despreocupadamente o roda.

Todas as plataformas baseadas na web, incluindo Zope a muitas outras, estão sujeitas a ataques deste
tipo. Tudo que é necessário é instigar um usuário a visitar uma URL que executa uma ação danosa.

Esse é um tipo de ataque do qual é muito difícil se proteger. É muito fácil induzir alguém a clicar num
link, ou é possível usar técnicas mais avançadas, como Javascipt para fazer com que o usuário visite a
URL maliciosa.

Zope oferece alguma proteção deste tipo de Cavalo de Tróia. Zope ajuda a proteger seu site de ataques
do Cavalo de Tróia limitando o poder dos recursos web, baseado em quem são seus autores. Se um
usuário não confiável é autor de uma página web, então o poder das páginas web de causar males aos
usuários não atentos será limitado. Por exemplo, suponha que um usuário não confiável cria um
documento DTML ou um script Python que apaga todas as páginas de seu site. A tentativa dos usuários
de visualizar a página falhará, pois eles não têm as permissões adequadas para isso. Se um
administrador visualiza a página, também falhará, porque o administrador não terá permissões
adequadas para executar a ação perigosa.

Zope utiliza a informação da posse e controle de conteúdo executável para fornecer essa proteção
limitada.

Gerenciamento de Posses

Quando um usuário cria um objeto Zope, ele possui esse objeto. Um objeto não tem proprietário é
chamado unowned (não possuído). A informação da posse é armazenada no próprio objeto. Isso é
similar como UNIX mantém um registro no arquivo do proprietário do arquivo.

Você descobre como um objeto é possuído visualizando a aba de gerenciamento Ownership, como
mostra a Figura 6.6.

Figura 6.6 - Gerenciando as propriedades de posse.

109 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Essa tela mostra que se o objeto é possuído, se é, por quem. Se o objeto é possuído por mais alguém, e
você possui a permissão Take ownership(Tomar posse), você pode tomar a posse do objeto. Você
também tem a opção de tomar a posse de todos os sub-objetos, marcando o box Take ownership of all
sub-objects (Tomar posse de todos os objetos). Tomar a posse é muito útil se o proprietário da conta foi
apagado ou se objetos lhe foram concedidos para que você os gerenciasse daqui em diante.

Como mencionamos anteriormente no capítulo, posse afeta políticas de segurança porque um usuário
terá uma função local Owner para objetos que possui. Contudo, a posse também afeta a segurança
porque controla o conteúdo executável das funções.

Funções do Conteúdo Executável

Pela web você pode editar scripts de alguns objetos Zope. Esses objetos, incluindo DTML Methods e
Documents, SQL Methods, scripts baseados em Python e scripts baseados em Perl. Esses objetos são
ditos executáveis desde que eles rodem scripts que são editados pela web.

Quando você visita um objeto executável indo para a sua URL ou chamando do o do DTML ou um
script, Zope roda o script do objeto. O script é restringido pelas funções do proprietário do objeto e
pelas suas funções. Em outras palavras, um objeto executável pode apenas executar ações que ambos, o
dono e o visualizador, são autorizados. Isto impede os usuários sem permissões de escrever um script
danoso e fazer com que o usuário que possui permissões de executá-lo. Você não pode fazer com que
mais alguém execute a ação se você não está autorizado para executá-la. É como Zope utiliza posse para
proteger-se do ataque do Cavalo de Tróia.

Funções de Solicitação

Algumas vezes o sistema do Zope de limitar acesso aos objetos executáveis não é exatamente o que você
quer. Algumas vezes você pode querer suprimir a segurança no objeto executável apesar de quem possa
possuir ou executá-lo, como uma forma extra de segurança. Outras vezes você pode querer fornecer um
objeto executável com acesso extra para permitir que o usuário que não tem permissão executar ações
protegidas. Funções de Solicitação lhe fornecem um meio de driblar as funções dos objetos executáveis.

Suponha que você deseja criar um formulário de email que permita aos usuário anônimos enviar email
para o webmaster de seu site. Mandar email é protegido pela permissão Use mailhost services. Usuários
anônimos normalmente não têm essa permissão e por uma boa razão. Você não quer que qualquer um
mande um email anônimo com seu servidor Zope.

O problema desse arranjo é que o seu DTML Method que manda email falhará para usuários anônimos.
Como contornar esse problema? A resposta é determinar a função de solicitação no DTML Method que
envia email que quando executa terá a função de "Manager". Visite a aba de gerenciamento Proxy do seu
DTML Method, como mostra a Figura 6.7

110 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 6-7 - Gerenciamento da função de Solicitação

Selecione Manager e clique em botão Change. Isso modificará as funções de solicitação do método de
envio de email para Manager. Note que você mesmo deve possuir a função Manager para modificar a
função de solicitação. Agora que cada um, anônimo ou não roda seu método de envio de email, ele
executará com a função Manager o que dará a autorização de enviar email.

Funções de Solicitação definem um conjunto fixo de permissões de conteúdo executável. Portanto, você
também pode os utilizar para restringir a segurança. Por exemplo, se você determina a Funções de
Solicitação do script para função Anônimo então o script nunca executará nenhuma outra função além
de Anonymous das funções do proprietário e daquele que está visualizando.

Use as Funções de Solicitação com cuidado, porque elas podem ser usadas para driblar as restrições
default de segurança.

Resumo
Segurança consiste de dois processos, autenticação e autorização. User Folders controlam a
autenticação, e as políticas de segurança controlam a autorização. A segurança do Zope está
intimamente ligada com o conceito de localização; usuários possuem localização; políticas de segurança
possuem localização; até as funções podem ter localização. Criar uma arquitetura de segurança eficaz
requer atenção para a localização. Quando surgir dúvida retorne ao uso de padrões de segurança
discutidos neste capítulo.

No próximo capítulo nós mudaremos de assunto e exploraremos o DTML avançado. DTML pode ser
uma ferramenta muito poderosa para apresentação e elaboração de scripts. Você descobrirá muitas tags
novas e verá alguns controles de segurança específicos da DTML que não vimos neste capítulo.

9. Variáveis e DTML Avançada


Este capítulo estuda mais de perto a DTML. Mostra a segurança com DTML e a
complicada edição de como as variáveis são procuradas na DTML. Também mostra usos
avançados das tags básicas mostradas no Capítulo 3 e as tags com objetivos especiais.
Este capítulo apresentará a você um programa DTML.

DTML é uma espécie de linguagem que "você faz o que pensa." Isto é bom, quando ele faz o que você
realmente quer que ele faça, mas quando ele faz algo que você não queria que ele fizesse, isto é ruim.
Este capítulo mostra a você como fazer com que o DTML faça o que você realmente quer.

111 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Não é mentira que a DTML tem reputação por ser complexa. E é verdade, a DTML é realmente simples
se o que você quer fazer é um simples layout, como você viu até agora. De qualquer forma, se você quer
usar DTML para tarefas mais avançadas, você tem que entender de onde vem as variáveis DTML.

Aqui está um erro muito comum que quase todos os usuários principiantes cometem. Imagine que você
possui um DTML Document chamado zooName. Este documento contém um formulário HTML como
este:

<dtml-var standard_html_header>
<dtml-if zooName>
<p><dtml-var zooName></p>
<dtml-else>
<form action="<dtml-var URL>" method="GET">
<input name="zooName">
<input type="submit" value="What is zooName?">
</form>
</dtml-if>
<dtml-var standard_html_footer>

Este exemplo parece simples o suficiente, a idéia é, esta é uma página HTML que chama ela mesma. Isto
é porque a ação do HTML é da variável URL, que vai se tornar a URL do DTML Document.

Se exister uma variável zooName, então a página será impressa, se não existir, rlr mostra um formulário
que pede por ele. Quando você clica `no submit, os dados que você digitou farão com que o comando "if"
seja avaliado, e este código deveria imprimir o que foi digitado no formulário.

Mas infelizmente, esta é uma dessas instâncias na qual a DTML não fará o que você quer, porque o
nome do DTML Document que contém este DTML também é chamado zooName, e ele não usa a
variável fora do requerimento (request), ele usa para si mesmo, que faz com que ele chame ele mesmo, e
novamente, infinitamente, até que você consiga um erro "Excessive recursion" (recursão excessiva).
Assim ao invés de fazer o que você realmente quer, você obtém um erro. Isto é o que confunde os
iniciantes. Nas próximas seções, mostraremos como você concerta este exemplo para fazer o que você
quer.

Como as Variáveis são Encontradas


Existem atualmente duas maneiras de concertar o erro do DTML no documento zooName. A primeira é
que você pode renomear o documento para algo como zopeNameFormOrReply e sempre lembrar esta
excessão especial e nunca fazê-la; nunca sabendo porque ela acontece. A segunda é entender como os
nomes são procurados, e saber de onde você quer que o nome venha de um namespace.

O namespace da DTML é uma coleção de objetos organizados em uma pilha. Uma pilha é uma lista de
objetos que podem ser manipulados pelos objetos pushing e popping dentro e fora da pilha.

Quando o DTML Document ou Method é executado, o Zope cria um namespace da DTML para decidir
os nomes das variáveis DTML. Isto é importante para entender o funcionamento do namespace da
DTML assim que você pode exatamente predizer como o Zope localizará as variáveis. Alguns dos
problemas enganosos você executará com a DTML provavelmente pode ser resolvido entendendo o
DTML namespace.

Quando o Zope procura por nomes na pilha do namespace da DTML ele primeiro procura no objeto bem
do topo da pilha. Se o nome não é encontrado ali, então o próximo item abaixo é vasculhado. Zope vai
procurar para baixo na pilha, examinando cada objeto dentro dela até ele achar o nome que está
procurando.

Se o Zope chegar ao final da pilha e nãp encontrou o que estava procurando, então um erro é gerado.

112 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Por exemplo, tente procurar por um nome não existente, unicorn:

<dtml-var unicorn>

Contanto que não haja uma variável chamada unicorn este DTML retornará um erro, como mostra a
Figura 7.1:

Figura 7.1 - Mensagem de erro do DTML indicando que ele não pode achar a variável

Mas a pilha do DTML não é muito para nomes porque a DTML não inicia com uma pilha vazia, antes
mesmo que você inicie executando a DTML no Zope já existem objetos na pilha do namespace.

DTML Namespace
Namespaces da DTML são construídas dinamicamente para cada requisição no Zope. Quando você
chama um DTML Method ou DTML Document através da web, o namespace da DTML inicia com os
mesmos dois primeiros elementos da pilha o objeto cliente e a requisição como mostra a Figura 7.2.

Figura 7.2 - stack DTML namespace inicial.

O objeto cliente é o primeiro objeto no topo da pilha do namespace da DTML. O objeto cliente depende
se você está ou não executando um DTML Method ou Document. Em nosso exemplo acima, isto
significa que o objeto cliente é chamado de zooName. Motivo pelo qual ele quebra. A entrada do
formulário que realmente queremos vem do request da web, mas mas o cliente é procurado primeiro.

O namespce da requisição está sempre no final da pilha do namespace do DTML, e é dessa forma o
último namespace a ser procurado por nomes. Isto significa que devemos ser explícitos em nosso
exemplo sobre que namespace queremos. Podemos fazer isto com a tag with da DTML.

113 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<dtml-with REQUEST only>


<dtml-if zooName>
<p><dtml-var zooName></p>
<dtml-else>
<form action="<dtml-var URL>" method="GET">
<input name="zooName">
<input type="submit" value="What is zooName?">
</form>
</dtml-if>
</dtml-with>

<dtml-var standard_html_footer>

Aqui a tag with diz para olhar no namespace REQUEST, e somente o namespace REQUEST, para o
nome "zooName".

Objeto Cliente do DTML

O objeto cliente na DTML depende se você está ou não executando um DTML Method ou Document. No
caso de um Document, o objeto cliente é sempre o próprio documento, ou em outras palavras, um
documento DTML um DTML Documento é seu próprio objeto cliente.

Um DTML Method de qualquer forma pode ter diferentes tipos de objetos cliente dependendo de como
ele é chamado. Por exemplo, se você possuia um DTML Method mostraca todos os conteúdos de uma
pasta do objeto cliente querendo esta pasta então o objeto cliente seria a pasta que está sendo
mostrada. Este objeto cliente pode mudar dependendo de qual pasta o método em questão é mostrado.
Por exemplo, considere o seguinte DTML Method chamado list no folder raiz.

114 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<ul>
<dtml-in objectValues>
<li><dtml-var title_or_id></li>
</dtml-in>
</ul>

<dtml-var standard_html_footer>

Agora, o que este método mostra depende de como ele é usado. Se você aplicar este método para a
pasta Reptiles com a URL http://localhost:8080/Reptiles/list, então você conseguirá algo como na
Figura 7.3.

Figura 7.3 - Aplicando o método list para a pasta Reptiles.

Mas se você adotar o método para a pasta Birds com a URL http://localhost:8080/Birds/list então
você obteria algo diferente, somente dois itens na lista, Parrot e Raptors.

Mesmo DTML Method, diferentes resultados. No primeiro exemplo, o objeto cliente do método list foi a
pasta Reptiles. No segundo exemplo, o objeto cliente foi a pasta Birds. Quando o Zope procurou a
variável objectValues, no primeiro caso ele chamou o método objectValues da pasta Reptiles, no
segundo caso ele chamou o método objectValues da pasta Birds.

Em outras palavras, o objeto cliente é onde as variáveis assim como os métodos, e propriedades são
procuradas por primeiro.

Como você viu Capítulo 4, "Conteúdo Dinâmico com DTML", se o Zope não pode achar uma variável no
objeto cliente, ele procura através do repositório do objeto. O Zope usa aquisições para
automaticamente [ herdar variáveis do repositório do objeto cliente. Assim quando o Zope passar sobre

115 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

a hierarquia do objeto procurando as variáveis ele sempre iniciará no objeto cliente, e fucionará bem a
partir daí.

Objeto Request do DTML

O objeto request é o objeto mais inferior na pilha do namespace da DTML. A requisição possui todas as
informações especificadas para a requisição da web atual.

Da mesma forma o objeto cliente usa aquisição para procurar em vários lugares pelas variáveis, assim
também o request procura as variáveis em muitos lugares. Quando o request procura uma variável ele
consulta estes fontes em ordem:

1. O ambiente CGI. O Common Gateway Interface, ou interface CGI define um grupo padrão de
variáveis do ambiente para ser usado por scripts web dinâmicos. Estas vaiáveis são oferecidas
pelo Zope no namespace do REQUEST.
2. Dados do formulário. Se a requisição corrente é uma ação do formulário, então qualquer dado de
entrada do formulário que foi submetido com a requisição pode ser encontrada no REQUEST do
objeto.
3. Cookies. Se o cliente da requisição corrente tem cookies este pode ser encontrado no objeto
REQUEST corrente.
4. Variáveis adicionais. O namespace REQUEST oferece a você muitas outras informações úteis,
como a URL do objeto corrente e tudo sobre seus pais.

O namespace request é muito útil no Zope desde que ele seja o primeiro modo no qual os clientes(neste
caso, browsers) se comuniquem com o Zope provendo dados do formulário, cookies e outras
informações sobre eles mesmos. Para maiores informações sobre o objeto request, veja o Apêndice B.

Um exemplo muito simples e esclarecedor para simplesmente imprimir o REQUEST em uma página
HTML:

<dtml-var standard_html_header>

<dtml-var REQUEST>

<dtml-var standard_html_footer>

Teste você mesmo, você deveria obter algo como na Figura 7.4.

116 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 7.4 - Mostrando o request.

Considerando que o request vem depois do objeto cliente, se houver nomes que existam em ambos
request e ojetos cliente, o DTML sempre os achará primeiro no objeto cliente. Isto pode se um
problema. Depois, vamos observar algumas maneiras de contornar este problema controlando mais
diretamente como o DTML procura as variáveis.que modo procurou variáveis.

Renderizando Variáveis

Quando você inserir uma variável usando a tag var, o Zope primeiro procura a variável usando o
namespace da DTML, então ele renderiza-a e insere os resultados. Renderizar significa transformar um
objeto ou valor em uma string adequada para inserir na saída. O Zope renderiza simples variáveis
usando o método padrão do Python para transformar objetos para strings. Para objetos complexos
como DTML Methods e SQL Methods, o Zope chamará o objeto ao invés de apenas tentar transformar
ele em uma string. Isto lhe permite inserir DTML Methods en outros DTML Methods.

Em geral o Zope renderiza variáveis do jeito que você quer. Você torna-se conhecedor do processo de
renderização quando você começa a fazer coisas mais avançadas. Mais adiante neste capítulo veremos
alguns exemplos de como controlar renderização usando a função do DTML getitem.

Modificando o DTML Namespace


Agora que você sabe que o namespace da DTML é uma pilha, você deve estar maravilhado em como, ou
até mesmo porque, os novos objetos são inseridos nele.

Algumas tags DTML modificam o namespace da DTML enquanto elas estão executando. Uma tag pode
inserir algum objeto no namespace da pilha durante o curso da execução. Estas tags incluem a tag in, a
tag with, e a tag let.

Modificações no Namespace da Tag In

Quando a tag in interage sobre uma seqüência ele insere o item corrente na seqüência para o topo do
namespace da pilha:

117 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var getId> <!-- This is the id of the client object -->

<dtml-in objectValues>

<dtml-var getId> <!-- this is the id of the current item in the


objectValues sequence -->

</dtml-in>

Você viu isto muitas vezes nos exemplos deste livro. Enquanto a tag in está interagindo sobre uma
seqüência cada item é inserido para a pilha do namespace para a duração dos conteúdos do bloco da tag
in. Quando o bloco acaba de excecutar, o item corrente na seqüência é mandado para fora da pilha do
namespace da DTML e o próximo item da seqüência é inserido.

A Tag With

A tag with insere um objeto que você especificou para o topo da pilha do namespace para o resto do
bloco with. Isto permite você especificar onde as variáveis poderiam ser procuradas por primeiro.
Quando o bloco with fecha, o objeto é mandado para a pilha do namespace.

Considere uma pasta que contém alguns métodos e propriedades que lhe interessam. Você poderia
acessar aqueles nomes com expressões Python como esta:

<dtml-var standard_html_header>

<dtml-var expr="Reptiles.getReptileInfo()">

<dtml-var expr="Reptiles.reptileHouseMaintainer"

<dtml-in expr="Reptiles.getReptiles()">

<dtml-var species>
</dtml-in>

<dtml-var standard_html_footer>

118 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Observe que algumas coisas complexas foram adicionadas ao código apenas obter coisas fora do folder
Reptiles. Usando a tag with você pode tornar este exemplo mais fácil de entender:

<dtml-var standard_html_header>

<dtml-with Reptiles>

<dtml-var getReptileInfo>
<dtml-var reptileHouseMaintainer>

<dtml-in getReptiles>
<dtml-var species>
</dtml-in>

</dtml-with>

<dtml-var standard_html_footer>

Outra razão para você querer usar a tag with é colocar o request, ou qualquer parte do request no topo
da pilha do namespace. Por exemplo suponha que você tenha um formulário que inclui uma entrada
chamada id. Se você tentar processar este formulário procurando a variável id como:

<dtml-var id>

Você não obterá a variável id do formulário, mas o id do cliente objeto. Uma solução é colocar o
formulário do request da web no topo da pilha do namespace do DTML usando a tag with:

<dtml-with expr="REQUEST.form">
<dtml-var id>
</dtml-with>

Isto assegurará que você obtenha o id do formulário primeiro. Veja o Apêndice B para analisar a
documentação completa do API do objeto request.

Se você submeteu seu formulário sem fornecer um valor para a entrada id, o formulário no topo da pilha

119 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

do namespace não funcionará bem, pois o formulário não contém uma variável id. Você ainda obterá o
id do objeto cliente id visto que a DTML procurará o objeto cliente depois da falha para achar a variável
id no formulário. A tag with tem um atributo que permite você preparar o namespace da DTML para
incluir somente o objeto que você especificou:

<dtml-with expr="REQUEST.form" only>


<dtml-if id>
<dtml-var id>
<dtml-else>
<p>The form didn't contain an "id" variable.</p>
</dtml-if>
</dtml-with>

Usando o atributo only você sabe onde suas variáveis começam a ser procuradas.

A Tag Let

A tag let permite você inserir um novo namespace para a pilha do namespace. Este namespace é
definida pelos atributos da tag para a tag let:

<dtml-let person="'Bob'" relation="'uncle'">


<p><dtml-var person>'s your <dtml-var relation&gt.</p>
</dtml-let>

Este exemplo deveria mostrar:

<p>Bob's your uncle.>/p<

A tag let engloba muitos dos mesmos objetivos da tag with. A principal vantagem da tag let é que você
pode usá-la para definir múltiplas variáveis para serem usadas em um bloco. A Tag let cria uma ou mais
variáveis novas e seus valores e insere um objeto namespace contendo aquelas variáveis e seus valores
no topo da pilha do namespace da DTML. Em geral a tag with é mais útil para inserir objetos existentes
para a pilha do namespace, enquanto a tag let é mais adequada para definir novas variáveis para um
bloco.

Quando você estiver escrevendo um DTML complexo que requer coisas como novas variáveis, há uma
boa chance de você fazer a mesma coisa melhor com o Python ou Perl. Scripts avançados são mostrados
no Capítulo 10, "Avançados Scripts em Zope".

O namespace da DTML é complexo, e esta complexidade envolve muito tempo. Entretanto ela ajuda a
entender de onde os nomes vem, é muito mais útil sempre especificar onde você está procurando um
nome. As tags with e let controlam o namespace para procurar exatamente no lugar certo o nome que
você procura.

Funções Úteis do DTML Namespace


Como todas as coisas no Zope, o namespace da DTML é um objeto, e ele pode ser acessado diretamente
no DTML com o objeto (underscore). O namespace é freqüentemente referenciado como "the under
namespace".

O under namespace oferece a você muitos métodos úteis para certas tarefas de programação. Vejamos
alguns deles.

Digamos que você queira imprimir seu nome 3 vezes. Isto pode ser feito com a tag in, mas como você diz
explicitamente para a tag in fazer um loop 3 vezes? Apenas passe para ela uma seqüência com três itens:

120 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>
<ul>

<dtml-in expr="_.range(3)">
<li>&ltdtml-var sequence-item>: My name is Bob.</li>
</dtml-in>
</ul>
<dtml-var standard_html_footer>

A expressão Python _.range(3) retornará uma seqüência dos primeiros três inteiros, 0, 1 e 2. A função
range é um padrão embutido no Python e muitas das funções embutidas do Python podem ser
acessadas através do namespace _, incluindo:

range([start,], stop, [step])

Retorna uma lista de inteiros do start ao stop contando os inteiros step da vez. O padrão de start é 0 e o
padrão do stepé 1. Por exemplo.

_.range(3,9,2) -- gives [3,5,7,9].

len(sequence)

len returns the size of sequence as an integer (retorna o tamanha da sequence como um inteiro)

Muitos desses nomes vem da linguagem Python, que contém um conjunto de funções especiais
chamadas built-in. A filosofia do Python é possuir um pequeno conjunto de números de nomes built-in.
A filosofia do Zope pode ser imaginada como tendo um grande e complexo array de nomes embutidos.

O namespace under pode também se usado para controlar explicitamente a procura de variáveis. Existe
um uso muito comum desta sintaxe. Você viu que a tag in define variáveis especiais, como
sequence-item e sequence-key que você pode usar dentro de um loop para ajudar você a mostrá-la e
controlá-la. O que acontece se você quiser usar uma destas variáveis dentro de uma expressão Python?:

121 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<h1> O ajuste para as primeiras 3 inteiras:</h1>


<ul>
<dtml-in expr="_.range(3)">
<li>The square of <dtml-var sequence-item> is:
<dtml-var expr="sequence-item * sequence-item">
</li>
</dtml-in>
</ul>

<dtml-var standard_html_footer>

Tente teste isto, ele funciona? Não! Por que não? O problema está na tag var:

<dtml-var expr="sequence-item * sequence-item">

Lembre-se, tudo dentro de um atributo da expressão do Python deve ser uma expressão válida do
Python. No DTML, sequence-item é o nome de uma variável, mas em Python significa "The object
sequence minus the object item" (A seqüência do objeto menos o item do objeto). Não é o que voccê
quer.

O que você realmente quer é procurar a variável sequence-item. Uma maneira de resolver este problema
é usar o atributo prefix da tag in. Por exemplo:

<dtml-var standard_html_header>

<h1> O quadro dos três primeiros inteiros:</h1>


<ul>
<dtml-in prefix="loop" expr="_.range(3)">
<li>The square of <dtml-var loop_item> is:
<dtml-var expr="loop_item * loop_item">
</li>
</dtml-in>
</ul>

<dtml-var standard_html_footer>

O atributo prefix faz com que as variáveis da tag in sejam renomeadas usando o prefix especifico e
underscores, preferivelmente usando "sequence" e dashes. Assim neste exemplo, "sequence-item"
transformam-se em "loop-item". Veja o Apêndice A para mais informção sobre o atributo prefix.

Outra alternativa para procurar a variável sequence-item em uma expressão DTML é usar dentro da
expressão DTML é usar a função utilitária getitem para explicitamente procurar uma variável:

122 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

The square of <dtml-var sequence-item> is:


<tml-var expr="_.getitem(sequence-item) *
_.getitem(sequence-item)">

A função getitem pega o nome para procurar no primeiro argumento. Agora, o DTML Method mostrará
corretamente a soma dos três primeiros inteiros. O método getitem recebe um segundo argumento
opcional que especifica se renderiza ou não a variável. Lembre que renderizar uma variável DTML
significa transformá-la em uma string. Por default a função getitem não renderiza uma variável.

Aqui está como inserir uma variável renderizada chamada my Doc:

<dtml-var expr="_.getitem(myDoc, 1)">

Este exemplo é de alguma maneira sem propósito, este é o equivalente:

<dtml-var myDoc>

De qualquer forma, suponha que você tinha um formulário no qual um usuário consegue selecionar em
qual documento ele quer ver de uma lista de opções. Suponha que o formulário possuia uma entrada
chamada selectedDoc que continha o nome do documento. Você poderia então mostrar o documento
renderizado assom:

<dtml-var expr="_.getitem(selectedDoc, 1)">

Observe no exemplo acima que selectedDoc não está entre aspas. Nós não queremos inserir a variável
chamada selectedDoc nós queremos inserir a variável chamada pelo selectedDocs. Por exemplo, o valor
do selectedDoc poderia ser ghapterOne. Usando inserções indiretas de variáveis você pode inserir a
variável chapterOne. Assim você pode inserir uma variável cujo nome você não sabe quando está
autorizando o DTML.

Se você programa em Python e você começa usando os mais complexos aspectos da DTML, considere
feito muito do seu trabalho em scripts Python que você chama pela DTML. Isto é melhor explicado no
Capítulo 10, "Avançado Script em Zope". Usar Python faz com que você não utilize muito a DTML.

Segurança do DTML
O Zope pode ser usado por diferentes tipos de usuários. Por exemplo, no site do Zope, Zope.org, possui
no momento mais de 11.000 membros da comunidade. Cada membro pode logar no Zope, adicionar
objetos e novos itens e gerenciar suas contas.

Porque a DTML é uma linguagem script, ela é muito flexível no trabalho com objetos e suas
propriedades. Se não existir um sistema de segurança que compele a DTML então um usuário poderia
potencialmente criar maldiciosamente ou invadir a privacidade do código DTML.

DTML é restrito pelo padrão das configurações de segurança do Zope. Assim se você não tem permissão
para acessar um objeto pela sua URL você também não terá permissão para acessá-la pela DTML. Você
não pode usar DTML para burlar o sistema de segurança do Zope.

Por exemplo, suponha que você possui um DTML Document chamado Diary que é privado. Usuários
anônimos não poderão acessar seu diário pela web. Se um usuário anônimo visualizar DTML que tenta
acessar seu diário o acesso será negado:

123 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var Diary>

DTML verifica que o usuário corrente está autorizado para acessar todas as variáveis DTML. Se o
usuário não tem autorização, então o sistema de segurança vai causar um erro Unauthorized e será
pedido ao usuário apresentar mais credenciais de autorização privilegiada.

No Capítulo 7, "Usuários e segurança", você leu sobre regras de segurança para conteúdo executável.
Existem maneiras de juntar as funções de um DTML Document ou Method para permití-lo acessar
variáveis restritas sem levar em consideração as funções do usuário.

Limites de Segurança nos Scripts

DTML não deixará você consumir memória ou executar infinitos loops e recursões onde restrições nos
looping e memória são curtas, fazendo da DTML uma linguagem para programação complexa e
despendiosa. Por exemplo, você não pode criar grandes listas com a função de utilidade _.range. Você
também não tem como acessar o sistema de arquivos diretamente no DTML.

Lembre-se de qualquer forma que os limites de segurança são simples e pode ser mais inteligente para
um determinado usuário. Ele geralmente não é uma boa idéia para permitir que qualquer pessoa não
confiável escreva código DTML em seu site.

Tags Avançadas do DTML


No restante deste capítulo nós veremos as avançadas tags DTML. Estas tags estão resumidas no
Apêndice A. A DTML possui várias tags embutidas, como documentado neste livro, que podem ser
levadas em consideração para serem apresentadas em todas as instalações do Zope e execução dos tipos
mais comuns de objetos. De qualquer forma, é também possível adicionar novas tags para uma
instalação do Zope. Instruções para fazer isto são oferecidas no web site do Zope.org, juntamente com
um conjunto interessante de tags DTML.

Esta seção mostra o que poderia ser referenciado como tags diferentes do Zope. Estas tags realmente
não se enquadram em nenhuma categira ampla exceto em um grupo de tags, as tags DTML de exception
handling (tratamento de excessão) que são discutidos no final deste capítulo.

A Tag Call
A tag var pode chamar métodos, mas ela também insere um valor de retorno. Usando a tag call você
pode chamar métodos sem inserir seus valores de retorno na saída. Isto é útil se você estiver mais
interessado no efeito da chamada de um método especialmente seu valor de retorno.

Por exemplo, quando você quiser mudar o valor de uma propriedade, animalName, você está mais
interessado nos efeitos da chamada do método manage_changeProperties do que no valor de retorno
que o método lhe oferece. Aqui está um exemplo:

<dtml-if expr="REQUEST.has_key(animalName)">
<dtml-call expr="manage_changeProperties(animalName=REQUEST['animalName'])">
<li>The property animalName has changed</h1>
<dtml-else>
<h1>No properties were changed</h1>
</dtml-if>

Neste exemplo, a página mudará uma propriedade dependendo se um certo nome existe. O resultado
do método manage_changeProperties não é importante e não precisa ser mostrado para o usuário.

124 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Outro uso comum da tag call é chamar métodos que afetam o comportamento do cliente, como o
método RESPONSE.redirect. Neste exemplo, você cria o cliente redirecionado a uma página diferente,
para mudar a página que foi redirecionada, mude o valor da variável "target" definida na tag let:

<dtml-var standard_html_header>

<dtml-let target="'http://example.com/new_location.html'">
&lth1>This page has moved, you will now be redirected to the
correct location. If your browser does not redirect, click <a
href="<dtml-var target>"><dtml-var target></a>.</h1>

&ltdtml-call expr="RESPONSE.redirect(target)">

</dtml-let>

<dtml-var standard_html_footer>

Em resumo, a tag call funciona exatamente como a tag var com exceção do fato dela não inserir os
resultados chamando a variável.

A Tag Comment
O DTML pode ser documentado com comentários usando a tag comment:

125 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>
<dtml-comment>
This is a DTML comment and will be removed from the DTML code
before it is returned to the client. This is useful for
documenting DTML code. Unlike HTML comments, DTML comments
are NEVER sent to the client.
</dtml-comment>

<!--
This is an HTML comment, this is NOT DTML and will be treated
as HTML and like any other HTML code will get sent to the
client. Although it is customary for an HTML browser to hide
these comments from the end user, they still get sent to the
client and can be easily seen by Viewing the Source of a
document.
-->
<dtml-var standard_html_footer>

O bloco comment é removido da saída do DTML.

Além disso para documentar o DTML você pode usar a tag comment para temporariamente comentar
outras tags DTML. Mais tarde você pode remover as tags comment para reabilitar o DTML.

A Tag Tree
A tag tree permite que você construa facilmente árvores dinâmicas em HTML para mostrar dados
hierarquicamente. A tree é uma representação gráfica de dados que começa com o objeto "root" que tem
objetos abaixo dele geralmente referenciados como "branches" (ramificações) Ramificações podem ter
suas próprias ramificações, exatamente como em uma árvore real. Este conceito deveria ser familiar
para qualquer um que usa um programa de gerenciamento de arquivo como o Microsoft Windows
Explorer para navegar nos sismtemas de arquivos. E, de fato, a visualização de navegação do frame a
esquerda da interface de gerenciamento do Zope é criada usando a tag tree.

Por exemplo aqui temos uma árvore que representa uma coleção de pastas e sub-pastas.

Figura 7.5 Árvore HTML gerada pela tag tree.

Aqui está o DTML que gerou esta árvore:

126 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>
<dtml-tree>
<dtml-var getId>
</dtml-tree>
<dtml-var standard_html_footer>

A tag tree busca objetos para achar seus sub-objetos e ter a responsabilidade de mostrar os resultados
como em uma árvore. O bloco da tag tree funciona a como um modelo para mostrar ligações da árvore.

Agora, mesmo o protocolo básico da web, HTTP, é sem origem, você precisa de alguma forma lembrar
em que situação a árvore está cada vez que você olhar uma página. Para isto, o Zope armazena o estado
da árvore em um cookie. Pelo fato do estado desta árvore estar armazenado em um cookie, somente
uma árvore pode aparece em uma página web de cada vez, se não elas vão usar o mesmo cookie
confusamente.

Você pode juntar o comportamento da tag tree inteiramente com os atributos da tag tree e com as
variáveis especiais. Aqui está uma amostra dos atributos da tag tree.

branches

O nome do método usado para procurar por sub-objetos. Seu padrão é tpValues, que é um método
definido pela quantidade de objetos padrão do Zope.

leaves

O nome de um método usado para mostrar objetos que não tem ramificações de sub-objetos.

nowrap

Tanto 0 como 1. Se 0, então o texto ramificado passará para a próxima linha, se não o texto pode ser
truncado. O valor default é 0.

sort

Forma ramos antes da inserção de texto ser executado. O valor do atributo é o nome do atributo cujos
itens deveria ser classificados.

assume_children

Tanto 0 ou 1. Se 1, então todos os objetos tem sub-objetos, e terão sempre um sinal de mais na frente
deles quando eles estão poder então sempre um sinal de adição em frente de os quando eles não
estiverem expandidos. Somente quando um item está expandido os sub-objetos podem ser procurados.
esta poderia ser uma boa opção quando o retorno dos sub-objetos for um processo custoso. O valor
default é 0.

single

Tanto 0 ou 1. Se 1, então somente uma ramificação pode ser expandida. Qualquer ramificação expandida
não será expandida quando uma nova ramificação for expandida. O valor default é 0.

skip_unauthorized

Tanto 0 ou 1. Se 1, então não haverá erro ao tentar mostrar os sub-objetos cujo usuário não tem acesso
sufuciente. Os sub-objetos protegidos não são mostrados. O valor default é 0.

127 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Suponha que você quer usar a tag tree para criar um mapa dinâmico do site. Você não quer que cada
páginaseja mostrada no mapa do site. Digamos que você colocou uma propriedade nos folders e
documentos que você quer mostrar no mapar do site.

Vamos primeiro definir um Script com o id publicObjects que retorna objetos públicos:

## Script (Python) "publicObjects"


##
"""
Retorna sub-objetos e documentos DTML que possuem uma propriedade true ‘siteMap’.
"""
results=[]
for object in context.objectValues([Folder, 'DTML Document']):
if object.hasProperty(siteMap) and object.siteMap:
results.append(object)
return results

Agora podemos criar um DTML Method que usa a tag tree e nossos scripts desenhar o mapa do site:

<dtml-var standard_html_header>
<h1>Site Map</h1>
<p><a href="&dtml-URL0;?expand_all=1">Expand All</a> |
<a href="&dtml-URL0;?collapse_all=1">Collapse All</a>
</p>
<dtml-tree branches="publicObjects" skip_unauthorized="1">
<a href="&dtml-absolute_url;"><dtml-var title_or_id></a>
</dtml-tree>
<dtml-var standard_html_footer>

Este DTML Method especiica um link para todos recursos públicos e mostra-os em uma árvore. Aqui
está o resultado do mapa do site:

Figura 7.6 - Mapa do site dinâmico usando a tag tree.

Para um resumo dos argumentos da tag tree e variáveis especiais vveja o Apêndice A.

A Tag Return
Em geral DTML cria saídas textuais. Você pode de qualquer forma, fazer com que a DTML retorne
outros valores além de texto. Usando a tag return, você pode fazer com que o DTML Method retorne
um calor arbitrário exatamente como scripts baseados em Python ou Perl.

Aqui temos um exemplo:

128 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<p>Este texto é ignorado.</p>

<dtml-return expr="42">

Este DTML Method retorna o número 42.

Outro resultado no uso da tag return é que a execução do DTML parará depois da tag return.

Se você estiver usando a tag return, você certamente deveria estar usando um script no lugar. A tag
return foi desenvolvida antes dos scripts e não é muito usada agora que você pode escrever scripts
facilmente em Python e Perl.

A Tag Sendmail
A tag sendmail formata e envia mensagens de e-mail. Você pode usar a tag sendmail para conectar-se a
um Host Mail existente, ou você pode especificar manualmente seu host SMTP.

Aqui temos um exemplo de como enviar uma mensagem de e-mail usando a tag sendmail:

<dtml-sendmail>
To: <dtml-var recipient>
Subject: Make Money Fast!!!!

Take advantage of our exciting offer now! Using our exclusive method
you can build unimaginable wealth very quickly. Act now!
</dtml-sendmail>

Note que existe uma linha branca extra separando o cabeçalho do email do corpo da mensagem.

Um uso comum da tag sendmail é enviar mensagens de e-mail geradas por um formulário de feedback.
A tag sendmail pode conter qualquer tag DTML que você quiser, assim é fácil juntar sua mensagem com
os dados do formukário.

A Tag Mime
A tag mime lhe permite formatar dados usando MIME (Multipurpose Internet Mail Extensions). MIME
é um padrão da Internet para codificar dados em uma mensagem de e-mail. Usando a tag mime você
pode usar o Zope para enviar emails com anexos.

Suponha que você queira atualizar seu sumário no Zope e tem que mandar um email com este arquivo
para o Zope para uma lista de potenciais dos empregados.

Aqui temos o formulário de atualização:

129 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>
<p>Send you resume to potential employers</p>
<form method=post action="sendresume" ENCTYPE="multipart/form-data">
<p>Resume file: <input type="file" name="resume_file"></p>
<p>Send to:</p>
<p>
<input type="checkbox" name="send_to:list" value="jobs@yahoo.com">
Yahoo<br>

<input type="checkbox" name="send_to:list" value="jobs@microsoft.com">


Microsoft<br>

<input type="checkbox" name="send_to:list" value="jobs@mcdonalds.com">


McDonalds</p>

<input type=submit value="Send Resume">


</form>

<dtml-var standard_html_footer>

Crie outro DTML Method chamado sendresume para processar o formulário e enviar o arquivo sumário:

<dtml-var standard_html_header>
<dtml-if send_to><dtml-in send_to>
<dtml-sendmail smtphost="my.mailserver.com">
To: <dtml-var sequence-item>
Subject: Resume
<dtml-mime type=text/plain encode=7bit>Hi, please take a look at my resume.
<dtml-boundary type=application/octet-stream disposition=attachment
encode=base64><dtml-var expr="resume_file.read()"></dtml-mime>
</dtml-sendmail></dtml-in><p>Your resume was sent.</p>
<dtml-else><p>You didn't select any recipients.</p>
</dtml-if>
<dtml-var standard_html_footer>

Este método interage sobre a variável sendto e envia um e-mail para cada item.

Note que não existe uma linha branca entre o cabeçalho do To: e o inicio da tag mime. Se uma linha
branca for inserida entre eles então a mensagem não será interpretada como uma mensagem multipar
pelo leitor que receberá o email.

Note também que não há uma nova linha entre a tag boundary e a tag var, ou o fim da tag var e o
fechamento da tag mime. Isto é importante, se você quebra as tags com novas linhas então elas serão
codificadas e incluídas na parte do MIME, o que provavelmente você não quer.

Conforme a especificação do MIME spec, tags mime podem ser colocadas arbitrariamente dentro das
tags mime.

A Tag Unless
A tag unless executa um bloco de códigos a menos que a condição dada seja verdadeira. A tag unless é o
oposto da tag if. O código DTML:

<dtml-if expr="not butter">


I can't believe it's not butter.
</dtml-if>

é equivalente a:

130 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-unless expr="butter">
I can't believe it's not butter.
</dtml-unless>

Qual é o objetivo da tag unless? Esta é simplesmente uma tag de conveniência. A tag unless é mais
limitada que a tag if, sendo assim ela não pode conter uma tag else ou elif.

Como a tag if, chamando a tag unless pelo nome temos:

<dtml-unless the_easter_bunny>
The Easter Bunny does not exist or is not true.
</dtml-unless>

Checa a existência da the_easter-bunny bem como se é verdadeira. Enquanto este exemplo somente
checa pela verdade do the_easter_bunny:

<dtml-unless expr="the_easter_bunny">
The Easter Bunny is not true.
</dtml-unless>

Este exemplo causará uma exceção se a the_easter_bunny não existir.

Qualquer coisa que possa ser feita pela tag unless pode ser feita pela tag if. Desta forma, seu uso é
totalmente opcional e uma forma de estilo.

Processamento em Lote com a Tag In


Freqüentemente você precisa mostrar uma lista grande de informações mas somente mostrar uma tela
de cada vez para o usuário. Por exemplo, se um usuário fizesse uma busca em seu banco de dados e
obtesse 120 resultados, você provavelmente vai querer mostrá-los ao usuário somente um pequeno lote,
digamos que 10 ou 20 resultados por página. Dividir uma grande lista em partes é chamado de batching
(paginação). A paginação possui vários benefícios.

1. O usuário precisa somente fazer um download de um documento com um tamanho razoável


especialmente de um documento grande. Isto faz com que páginas sejam rapidamente baixadas
sendo elas menores.
2. Porque lotes menores de resultados são usados, frequentemente para que menos memória seja
consumida pelo Zope.
3. As interfaces de navegação Next e Previous analisam grandes lotes facilmente.

A tag in oferece várias variáveis para facilitar o processamento de lotes. Olhe este exemplo completo que
mostra como exibir 100 itens em grupos de 10 de cada vez:

131 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>
<dtml-in expr="_.range(100)" size=10 start=query_start>
<dtml-if sequence-start>
<dtml-if previous-sequence>
<a href="<dtml-var URL><dtml-var sequence-query>
query_start=<dtml-var previous-sequence-start-number>"Egt
(Previous <dtml-var previous-sequence-size> results)
</a>
</dtml-if>
<h1>These words are displayed at the top of a batch:</h1>
<ul>
</dtml-if>
<li>Iteration number: <dtml-var sequence-item></li>
<dtml-if sequence-end>
</ul>
<h4>These words are displayed at the bottom of a batch.</h4>
<dtml-if next-sequence>
<a href="<dtml-var URL><dtml-var sequence-query>
query_start=<dtml-var
next-sequence-start-number>">
(Next <dtml-var next-sequence-size> results)
</a>
</dtml-if>
</dtml-if>
</dtml-in>
<dtml-var standard_html_footer>

Vamos dar uma olhada no DTML para ter uma idéia de como ele funciona. Primeiro temos uma tag in
que interage sobre os 100 números que são gerados por uma função de utilidade range. O atributo size
diz para a tag in mostrar somente 10 itens cada vez. O atributo start diz para a tag in quais números dos
itens exibir primeiro.

Dentro da tag in existem duas tags if essenciais. A primeira testa a variável especial sequence-start. Esta
variável somente é verdadeira na primeira passagem pelo bloco. Assim os conteúdos desta tag if
somente serão executados uma vez no início do loop. A Segunda tag if testa a variavel especial
sequence-end. Esta variável somente é verdadeira na última passagem pela tag in. Desta forma o
segundo bloco if somente será executado uma vez no final. O parágrafo entre as tags if é executado cada
vez que passar pelo loop.

Dentro de cada tag if existe outra tag if que busca pelas vaiáveis especiais previous-sequence e
next-sequence. As variáveis são verdadeiras quando o grupo atual tem lotes anteriores ou posterioes
respectivamente. Em outras palavras previous-sequence é verdadeira para todos os lotes exceto para o
primeiro, e next-sequence é verdadeira para todos os lotes exceto para o último. Assim o DTML testa
para ver se há lotes adicionais disponíveis, e se assim ele desenha links de navegação.

A navegação do lote consiste de links que voltam ao documento com um conjunto de variáveis
query_start que indicam onde a tag in deveria iniciar quando estiver exibindo o lote. Para perceber
melhor como isto funciona, clique nos links previous e next algumas vezes e observe como as URLs para
os links de navegação mudam.

Enfim algumas estatísticas sobre os lotes previous e next são mostrados usando variáveis especiais
next-sequence-size e previous-sequence-size. Tudo isso termina gerando o seguinte código HTML:

132 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<html><head><title>Zope</title></head><body bgcolor="#FFFFFF">
<h1>Estas Palavras são mostradas no topo de um grupo:</h1>
<ul>
<li>Iteration number: 0</li>
<li>Iteration number: 1</li>
<li>Iteration number: 2</li>
<li>Iteration number: 3</li>
<li>Iteration number: 4</li>
<li>Iteration number: 5</li>
<li>Iteration number: 6</li>
<li>Iteration number: 7</li>
<li>Iteration number: 8</li>
<li>Iteration number: 9</li>
</ul>
<h4>Estas palavras são mostradas no fundo de um Grupo.</h4>
<a href="http://pdx:8090/batch?query_start=11">
(Next 10 results)
</a>
</body></html>

Processamento em lote pode ser complexo. Uma boa maneira de trabalhar com lotes é usar o objeto
Searchable Interface para criar um relatório de busca em grupos (itens, quantidades) para você. Você
pode então modificar o DTML para adequar as suas necessidades. Isto é melhor explicado no Capítulo
11, "Buscando e Categorizando Conteúdo".

Tags de Tratamento de Excessão


O Zope possui várias facilidades para o tratamento de excessões. Você pode ter acesso a essas
facilidades com as tags raise e try. Para maiores informações sobre excessões e como elas são causadas
e tratadas veja um livro sobre Python ou você pode ler o Turorial do Python online.

A Tag Raise

Você pode tratar excessões com a tag raise. Uma razão para tratar excessões é para indicar um erro. Por
exemplo você poderia buscar um problema com uma tag if, e no caso de haver algo errado você poderia
informar o erro com a tag raise.

A tag raise possui um atributo type para especificar um tipo de erro. O tipo de erro é um pequeno nome
descritivo para o erro. Além disso, existem alguns tipos de erros padrão, como Unauthorized e Redirect
que são retornados como erros HTTP. Erros Unauthorized mostram a tela de log in no browser do
usuário. Você pode tratar erros HTTP para fazer com que o Zope envie um erro HTTP. Por exemplo:

<dtml-raise type="404"&gtNot Found</dtml-raise>

Isto trata um erro HTTP 404 (not Found). O Zope responde enviando o erro HTTP 404 de volta para o
browser do usuário.

A tag raise é uma tag de bloco. O bloco fechado pela tag raise é renderizado para criar uma mensagem
de erro. Se o texto renderizado contém qualquer marcação HTML, então o Zope pode exibir o texto com
uma mensagem de erro no browser, se não uma mensagem de erro genérica é exibida.

Aqui está um exemplo da tag raise:

133 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-if expr="balance>= debit_amount">


<dtml-call expr="debitAccount(account, debit_amount)">
<p><dtml-var debit_amount> has been deducted from your
account <dtml-var account>.</p>
<dtml-else>
<dtml-raise type="Insufficient funds">
<p>There is not enough money in account <dtml-account>
to cover the requested debit amount.</p>
</dtml-raise>
</dtml-if>

Há o lado importante do efeito do tratamento de uma excessão, excessões fazem com que a transação
corrente seja desfeita. Isto significa que qualquer mudança feita por um request na web será ignorada.
Assim além disso para informar erros, excessões permitem a você desfazer as mudanças se um
problema surgir.

A Tag Try

Se uma excessão é tratada tanto manualmente com a tag raise, quanto com os resultados de alguns
erros que o Zope encontra, você pode capturá-los com a tag try.

Excessões são erros inesperados que o Zope encontra durante a execução de um DTML Document ou
Method. Quando uma excessão é detectada, a execução normal da DTML para. Considere o seguinte
exemplo:

Cost per unit: <dtml-var


expr="_.float(total_cost/total_units)"
fmt=dollars-and-cents>

Este DTML trabalha muito bem se total_units não for zero. Entretanto, se total_units for zero, uma
excessão ZeroDivisionError (erro de divisão por zero) é causado indicando uma operação ilegal.
Portanto quando o DTML for renderizado, uma mensagem de erro será retornada.

Você pode usar a tag try para tratar este tipo de problema. Com a tag try você mesmo pode antecipar e
tratar os erros, especialmente obtendo uma mensagem de erro no Zope sempre que ocorrer uma
excessão.

A tag try possui duas funções. Primeira, se uma excessão é causada, a tag try adquire o controle da
execução e trata a excessão apropriadamente, e deste modo evita o retorno de uma mensagem de erro
do Zope. Segunda, a tag try permite a renderização de qualquer DTML subsequente contimue.

Dentro da tag try existem uma ou mais tags except que identificam e tratam diferentes excessões.
Quando uma excessão é causada, cada tag except é verificada uma após a outra para ver se ela está
compatível com os tipos de excessões. A primeira tag except para verifica trata a excessão. Se excessões
não são dadas em uma tag except então a tag except irá comparar todas as excessões.

Aqui está como usar a tag try para prevenir erros que poderiam ocorrer no último exemplo:

<dtml-try>
Cost per unit: <dtml-var expr="_.float(total_cost/total_units)" fmt="dollars-and-cents">
<dtml-except ZeroDivisionError>
Cost per unit: N/A
</dtml-try>

Se um ZeroDivisionError for causado, o controle passa para a tag except e "Cost per unit: N/A" é
mostrado. Quando o bloco da tag except termina, a execução do DTML contimua depois do bloco try.

134 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

A tag except da DTML funciona com excessões de classes baseadas em Python. Além disso para
compara excessões por nome, a tag except verificará qualquer sub classe da excessão chamada. Por
exemplo, se ArithmeticError for nomeado na tag except, a tag pode tratar de todas as subclasses
ArithmeticError incluindo, ZeroDivisionError. Veja uma referência ao Python como a Referência a
Biblioteca do Python online uma lista de excessões do Python e suas subclasses. Uma tag except pode
capturar múltiplas excessões listando-as todas na mesma tag.

Dentro do corpo de uma tag except você pode acessar informações sobre a excessão tratada através de
muitas variáveis especiais.

error_type
O tipo de excessão tratada.
error_value
O valor da excessão tratada.
error_tb
O traceback da excessão tratada.

Você pode usar estas variáveis para oferecer mensagens de erro para os usuários ou para adotar
diferentes ações como enviar e-mails para o webmaster ou documentar erros dependendo do tipo de
erro.

O Bloco Opcional Else da Tag Try

A tag try possui um bloco opcional else que é renderizado se uma excessão não ocorreu. Aqui temos um
exemplo de como usar a tag else dentro da tag try.

<dtml-try>
<dtml-call feedAlligators>
<dtml-except NotEnoughFood WrongKindOfFood>
<p>Make sure you have enough alligator food first.</p>
<dtml-except NotHungry>
<p>The alligators aren't hungry yet.</p>
<dtml-except>
<p>There was some problem trying to feed the alligators.<p>
<p>Error type: <dtml-var error_type></p>
<p>Error value: <dtml-var error_value></p>
<dtml-else>
<p>The alligator were successfully fed.</p>
</dtml-try>

O primeiro bloco except verifica que tipo de erro causado é renderizado. Se um bloco except não possuir
nome, então ele verifica todos os erros causados. O bloco opcional else é renderizado quando não ocorre
excessões no bloco try. Excessões no bloco else não são tratados pelo bloco except precedente.

O Bloco Opcional Finally da Tag Try

Você também pode usar a tag try de um modo um pouco diferente. Ao invés de tratar excessões, a tag
try pode ser usada não para pegar excessões, mas para concertá-las.

A tag finally dentro da tag try especifica um bloco limpo para ser renderizado até mesmo quando uma
excessão ocorre.

O bloco finally somente é útil se você precisa limpar algo que não pode ser limpo pelo código para
aobrtar da transação. O bloco finally sempre será chamado, se houver uma excessão ou não e se uma
tag return for usada ou não. Se você usa uma tag return no bloco try, qualquer saída do bloco finally é
descartada. Aqui temos um exemplo de como você poderia usar a tag finally:

135 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-call acquireLock>
<dtml-try>
<dtml-call useLockedResource>
<dtml-finally>
<!-- this always gets done even if an exception is raised -->
<dtml-call releaseLock>
</dtml-try>

Neste exemplo primeiro você adquire um lock em um recurso, então tenta executar algumas ações em
um recurso bloqueado (locked). Se uma excessão é causada, você não trata-a, mas você deve lembrar de
liberar o lock antes de passar o controle a um tratamento de excessão. Se tudo der certo e nenhuma
excessão for causada, você ainda libera o lock no final do bloco try executando o bloco finally.

A forma try/finally da tag try é raramente usada no Zope. Este tipo de controle complexo da
programação é freqüentemente feito melhor em Python ou Perl.

Conclusão
O DTML oferece algumas funcionalidades muito poderosas para projetar aplicações para a web. Neste
capítulo, nós vimos as tags DTML mais avançadas e algumas de suas opções. Uma referência mais
completa pode ser encontrada no Apêndice A.

O próximo capítulo ensina a você como transformar um ajudante de Modelo de Página. Enquanto o
DTML é uma poderosa ferramenta, Modelos de Páginas oferecem uma solução mais elegante para
geração do HTNL.

10. Modelo de Página Avançado


Este capítulo analisa profundamente os templates (modelos). Este capítulo ensina a você
todas as instruções do template e tipos de expressão. Também mostra macros que
deixam você reusar elementos de apresentação. No final deste capítulo você saberá tudo
o que há sobre modelos de páginas.

No Capítulo "Usando Modelos de Páginas no Zope" você aprendeu o básico sobre Modelos de Páginas.
Neste capítulo você aprenderá sobre técnicas avançadas incluindo novos tipos de expressões e macros.

TAL Avançada
Você já aprendeu sobre algumas expressões TAL. Nesta seção nós veremos todas as expressões TAL e
suas várias opções. Note, esse material é abordado mais resumidamente no Apêndice C, "Referências a
Modelos de Páginas do Zope".

Inserção Avançada de Conteúdo

Você já viu como tal:content e tal:replace funcionam no Capítulo 5, "Usando Modelos de Páginas do
Zope". Nesta seção você aprenderá algumas dicas avançadas para a inserção de conteúdo.

Inserindo Estruturas

Normalmente, as expressões tal:replace e tal:content introduzem tags e entidades HTML no texto que
elas inserem, convertendo < para &lt;, por exemplo. Se você realmente quer inserir o texto sem aspas,
você precisa preceder a expressão com a palavra-chave structure. Por exemplo:

136 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<p replace="structure here/story">


the <b>story</b>
</p>

Essa característica é útil quando você está inserindo um fragmento de HTML ou XML que está
armazenado em uma propriedade ou que foi gerado por outro objeto do Zope. Por exemplo, você pode
ter novos itens que contenham tags HTML simples como texto em negrito e itálico quando eles são
renderizados, e você quer preservar isso quando inseri-los em uma página de "Top News". Neste caso,
você deve escrever:

<p tal:repeat="newsItem here/topNews"


tal:content="structure newsItem">
A news item with<code>HTML</code> markup.
</p>

Isso irá inserir os novos itens incluindo suas tags HTML em parágrafos.

Elementos de Imitação

Você pode incluir elementos de páginas que estejam visíveis no modelo mas não no texto gerado usando
a variável embutida nothing, como nesse exemplo:

<tr tal:replace="nothing">
<td>10213</td><td>Example Item</td><td>$15.34</td>
</tr>

Isso pode ser útil para preencher partes da página que serão ocupadas com conteúdo dinâmico. Por
exemplo, uma tabela que normalmente tem 10 linhas terá apenas uma linha no modelo. Adicionando
nove linhas de imitação, o layout do modelo se parecerá mais com o resultado final.

Não é preciso usar sempre tal:replace="nothing" para conseguir conteúdo modelo em seus Modelos de
Páginas. Por exemplo, você já viu que normalmente nada dentro de um tal:content ou tal:replace é
removido quando o modelo é renderizado. Nesses casos você não tem que fazer nada em especial para
se certificar de que o conteúdo modelo foi removido.

Conteúdo Padrão

Você pode deixar o conteúdo de uma tag para adiante usando a expressão default com tal:content ou
tal:replace. Por exemplo:

<p tal:content="default">Spam<p>

Isso é interpretado como:

Spam

Mais freqüentemente você irá querer incluir conteúdo padrão seletivamente, ao invés de sempre incluir
isso. Por exemplo:

<p tal:content="python:here.getFood() or default">Spam</p>

Nota: expressões Python serão explicadas mais tarde no capítulo. Se o método getFood retornar um

137 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

valor verdadeiro então seu resultado será inserido no parágrafo, senão é um Spam.

Repetição Avançada da Tag

Você já viu quase tudo que pode ser feito com a expressão tal:repeat no Capítulo 5, "Usando Modelos
de Páginas do Zope ". Essa seção abrange algumas características avançadas da expressão tal:repeat.

Variáveis de Repetição

Um tópico que pode apresentar mais explicações é o das variáveis de repetição. Variáveis de repetição
fornecem informação sobre a repetição em andamento. Esses atributos estão disponíveis nas variáveis
repeat:

index - repetição de números, começando do zero.


number - repetição de números, começando do 1.
even - verdadeiro para repetições even-indexed (0, 2, 4, ...).
odd - verdadeiro para repetições odd-indexed (1, 3, 5, ...).
start - verdadeiro para o começo da repetição (index 0).
end - verdadeiro para a conclusão, ou final, da repetição.
length - tamanho da seqüência - que será o número total de repetições.
letter - conta reps com letras lower-case (letras minúsculas): "a" - "z", "aa" - "az", "ba" - "bz", ...,
"za" - "zz", "aaa" - "aaz", e assim por diante.
Letter - versão upper-case (maiúscula) de letter.

Você pode acessar os conteúdos de uma variável de repetição usando expressões path ou expressões
Python. Em expressões path, você escreve um path em três partes consistindo no nome repeat, a
expressão do nome da variável, e o nome da informação que você quer, por exemplo, repeat/item/start.
Em expressões Python, você normalmente usa notação de dicionários para obter a variável de repetição,
e após atributos de acesso para obter a informação, por exemplo, 'python:repeat['item'].start'.

Dicas de Repetição

Aqui estão algumas dicas práticas que você pode achar útil. Algumas vezes você quer repetir uma tag,
mas não tem uma tag de fechamento. Por exemplo, você pode querer repetir várias tags de parágrafo,
mas não há necessidade de fechá-las em outra tag. Você pode fazer isso com a expressão tal:omit-tag:

<div tal:repeat="quote here/getQuotes"


tal:omit-tag="">
<p tal:content="quote">quotation</p>
</div>

A expressão tal:omit-tag será descrita mais tarde neste capítulo.

Mesmo que já tenha sido mencionado antes, é melhor dizer novamente: você pode colocar expressões
tal:repeat uma dentro da outra. Cada expressão tal:repeat deve ter uma variável de repetição com
nome diferente. Aqui está um exemplo que mostra uma tabela-tempo aritmética:

<table border="1">
<tr tal:repeat="x python:range(1, 13)">
<div tal:repeat="y python:range(1, 13)"
tal:omit-tag="">
<td tal:content="python:%d x %d = %d % (x, y, x*y)">
X x Y = Z
</td>
</div>
</tr>
</table>

138 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Esse exemplo usa expressões Python e a expressão tal:omit-tag, ambas serão tratadas mais tarde neste
capítulo.

Se você trabalha muito com a expressão de repetição do DTML dtml-in, você terá paginações
inesperadas. Paginação é o processo de dividir uma lista extensa em listas menores. Você usa isso
tipicamente para exibir um número menor de itens de uma lista extensa em uma página da web. Pense
em como um mecanismo de busca pagina seus resultados. A expressão tal:repeat não suporta
paginação, mas o Zope possui uma utilidade de paginação. Veja a seção, "Paginação" mais adiante neste
capítulo.

Outra característica útil que não é suportada pela tal:repeat é a classificação. Se você quer classificar
uma lista você pode tanto escrever seu próprio script de classificação (que é mais fácil em Python) como
usar a função utilitária sequence.sort. Aqui está um exemplo de como classificar uma lista de objetos por
título e após por data de modificação:

<table tal:define="objects here/objectValues;


sort_on python:((title, nocase, asc),
(bobobase_modification_time, cmp, desc));
sorted_objects python:sequence.sort(objects, sort_on)">
<tr tal:repeat="item sorted_objects">
<td tal:content="item/title">title</td>
<td tal:content="item/bobobase_modification_time">
modification date</td>
</tr>
</table>

Esse exemplo tenta fazer coisas claramente ao definir os argumentos da classificação fora da função
sort. Você chama a função sequence.sort pegando uma seqüência e uma descrição de como
classificá-los. Neste exemplo a descrição de como classificar a seqüência é definida na variável sort_on.
Veja o Apêndice B, "Referência API" para mais informação sobre a poderosa função sequence.sort.

Controle Avançado do Atributo

Você já conhece a expressão tal:attributes. Você pode usá-la dinamicamente substituindo atributos da
tag, por exemplo, o atributo href em um elemento a. Você pode substituir mais do que um atributo em
uma tag ao separar atributos com ponto e vírgula:

<a href="link"
tal:attributes="href here/getLink;
class here/getClass">link</a>

Você também pode definir atributos com namespaces XML. Por exemplo:

<Description
dc:Creator="creator name"
tal:attributes="dc:Creator here/owner/getUserName">
Description</Description>

Simplesmente coloque o prefixo namespace XML antes do atributo name e você pode criar atributos
com namespaces XML.

Definindo Variáveis

Você pode definir suas próprias variáveis usando o atributo tal:define. Existem várias razões para que
você queira fazer isso. Uma razão é evitar ter que escrever longas expressões repetidamente em um
modelo. Outro é evitar ter que chamar métodos muito extensos repetidamente. Você pode definir uma

139 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

variável uma vez e então usá-la várias vezes em um modelo. Por exemplo, aqui está uma lista que define
uma variável, testa ela e depois gera uma repetição sobre ela:

<ul tal:define="items container/objectIds"


tal:condition="items">
<li tal:repeat="item items">
<p tal:content="item">id</p>
</li>
</ul>

A expressão tal:define cria a variável items que você pode usar em qualquer lugar na tag ul. Note
também como você pode ter duas expressões TAL na mesma tag ul. Veja depois, neste mesmo capítulo,
a seção "Interações Entre Expressões TAL" para mais informações sobre como usar mais de uma
expressão em uma tag. Neste caso a primeira expressão usa a variável items e a segunda usa items em
uma condição para ver se ela é ou não é falsa (neste caso, uma seqüência vazia) ou verdadeira. Se a
variável items for falsa, então a tag ul não é mostrada.

Agora, suponha que ao invés de simplesmente remover a lista quando não houver itens, você queira
mostrar uma mensagem. Para fazer isso, coloque o seguinte antes da lista:

<h4 tal:condition="not:container/objectIds">There
Are No Items</h4>

A expressão not:container/objectIds é verdadeira quando container/objectIds é falsa, e vice versa. Veja


a seção, "Expressões Not" mais adiante neste capítulo para mais informação.

Você não pode usar suas variáveis items aqui, pois elas não foram definidas ainda. Se você mover a
definição de items para a tag h4, você não poderá mais usá-la na tag ul porque ela se tornou uma
variável local da tag h4. Você pode colocar a definição em algumas tags que finalizam a h4 e a ul, mas
existe uma solução mais simples. Ao colocar a palavra-chave global na frente da variável name, você
pode fazer a definição durar da tag h4 até o final do modelo:

<h4 tal:define="global items container/objectIds"


tal:condition="not:items">There Are No Items</h4>

Você pode definir mais do que uma variável usando tal:define ao separá-las com ponto e vírgula. Por
exemplo:

<p tal:define="ids container/objectIds;


title container/title">

Você pode definir quantas variáveis quiser. Cada variável pode ter seu próprio âmbito global ou local.
Você também pode fazer referências a variáveis definidas anteriormente em definições posteriores. Por
exemplo:

<p tal:define="title template/title;


tlen python:len(title);">

Com uso ponderado de tal:define você pode melhorar a eficiência e a capacidade de leitura de seus
modelos.

Omitindo Tags

140 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Você pode remover tags com a expressão tal:omit-tag. Você raramente precisará usar essa expressão
TAL, mas ocasionalmente é útil. O atributo omit-tag remove uma tag, mas não afeta seu conteúdo. Por
exemplo:

<b tal:omit-tag=""><i>this</i> stays</b>

É renderizado:

<i>this</i> stays

Nesse nível de uso, tal:omit-tag opera quase como tal:replace="default". No entanto, tal:omit-tag é
mais útil quando usada em combinação com outra expressão TAL como tal:repeat. Por exemplo, eis
uma forma de criar 10 tags de parágrafo usando tal:repeat:

<span tal:repeat="n python:range(10)"


tal:omit-tag="">
<p tal:content="n">1</p>
</span>

Isso irá gerar 10 tags de parágrafo, porém, a tag span não aparecerá na saída.

O atributo tal:omit-tag retira uma expressão, contudo normalmente você usará somente uma expressão
vazia. Se a expressão é verdadeira ou se não há expressão então a expressão tag é removida. Se a
expressão é falsa, então a tag não é omitida. Isso permite que você remova as tags seletivamente
dependendo da dinâmica da circunstância.

Tratamento de Erro

Se um erro ocorre no seu modelo de página, você pode pegar esse erro e mostrar uma mensagem de
erro muito útil ao seu usuário. Por exemplo, suponha que seu modelo define uma variável usando uma
estrutura de dados:

...
<span tal:define="global prefs request/form/prefs"
tal:omit-tag="" />
...

Se o Zope encontrar um problema, como não achar a variável prefs na estrutura de dados, a página
inteira trancará e você terá no seu lugar uma página de erro. Felizmente, você pode evitar esse tipo de
coisa com tratamento limitado de erro usando a expressão tal:on-error:

...
<span tal:define="global prefs here/scriptToGetPreferences"
tal:omit-tag=""
tal:on-error="string:An error occurred">
...

Quando um erro é detectado ao carregar o modelo, o Zope procura por uma expressão tal:on-error para
tratar do erro. Primeiro ele procura na tag corrente, depois na tag de fechamento, e assim por diante até
chegar na tag top-level (nível superior). Quando ele encontra um tratador de erro, ele substitui os
conteúdos da tag com as expressões de tratamento de erro. Nesse caso, a tag span irá conter uma
mensagem de erro.

141 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Tipicamente você definirá um tratador de erros em uma tag que finaliza um elemento lógico da página,
uma tabela, por exemplo. Se um erro surgir inserindo a tabela, então o tratador de erros pode
simplesmente omitir a tabela da página, ou também repô-la com uma mensagem de erro de alguma
classificação.

Para um tratamento de erros mais flexível você pode chamar um script. Por exemplo:

<div tal:on-error="structure here/handleError">


...
</div>

Qualquer erro que ocorrer dentro do div chamará o script handleError. Note que a opção structure
permite que o script dê retornos em HTML. Seu script de tratamento de erros pode examinar o erro e
tomar várias atitudes dependendo do erro. Seu script tem acesso ao erro através da variável error no
namespace. Por exemplo:

## Script (Python) "handleError"


##bind namespace=_
##
error=_['error']
if error.type==ZeroDivisionError:
return "<p>Can't divide by zero.</p>"
else
return """<p>An error occurred.</p>
<p>Error type: %s</p>
<p>Error value: %s</p>""" % (error.type,
error.value)

Seu script de tratamento de erro pode tomar todo tipo de atitude, por exemplo, ele pode logar o erro ao
mandar um e-mail.

A expressão tal:on-error não foi feita para o propósito geral de tratamento de exceções. Por exemplo,
você não deve validar dados de entrada no formulário nele. Você deve usar um script para isso, já que os
scripts permitem que você faça um poderoso tratamento de exceções. A expressão tal:on-error é para
lidar com problemas incomuns que podem ocorrer na renderização de modelos.

Interações Entre Expressões TAL

Quando há apenas uma expressão TAL por elemento, a ordem na qual elas são executadas é simples.
Começando com o elemento da raiz, cada expressão do elemento é executada, depois cada um de seus
elementos-filhos é visitado, em ordem, e suas expressões são executadas, e assim por diante.

Contudo, é possível que exista mais do que uma expressão TAL no mesmo elemento. Qualquer
combinação de expressões pode aparecer no mesmo elemento, menos a combinação em que a expressão
tal:content e tal:replace aparecem juntas.

Quando um elemento tem várias expressões, eles são executados nesta ordem:

1. define
2. condition
3. repeat
4. content or replace
5. attributes
6. omit-tag

A expressão tal:on-error não aparece na lista, já que ela é chamada apenas quando ocorre um erro.

142 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

A razão por trás desta ordem é que freqüentemente você pode querer definir variáveis para usar em
outras expressões, assim a definição vem primeiro. A próxima coisa a fazer é decidir se esse elemento
será incluído no todo, a condição vem primeiro; mas se a condição depender das variáveis que você
define, ela vem depois da definição. É muito importante ser capaz de repor várias partes de um
elemento com diferentes valores a cada interação de uma repetição, assim a repetição vem antes do
content, replace e attributes. Content e replace não podem ser usados no mesmo elemento ao mesmo
tempo já que eles ocupam o mesmo lugar. Omit-tag vem por último, pois é provável que nenhuma outra
expressão dependa dela e porque ela deve vir depois de define e repeat.

Aqui está um exemplo de tag que inclui várias expressões TAL:

<p tal:define="x /root/a/long/path/x | nothing"


tal:condition="x"
tal:content="x/txt"
tal:attributes="class x/class">Ex Text</p>

Veja como a expressão tal:define é executada primeiro e como as outras expressões dependem de seus
resultados.

Existem três regras que você deve seguir quando combinar expressões TAL nos elementos:

1. Apenas uma expressão de cada tipo pode ser usada em uma tag. Já que HTML não permite
vários atributos com o mesmo nome. Por exemplo, você não pode ter dois tal:define na mesma
tag.
2. tal:content e tal:replace não podem ser usados na mesma tag pois suas funções conflitam.
3. A ordem na qual você escreve atributos TAL em uma tag não afeta a ordem na qual eles serão
executados. Não importa como você combina as expressões TAL em uma tag, elas sempre são
executadas na ordem descrita anteriormente.

Se você quiser passar por cima da ordem das expressões TAL, então você deve fazer isso colocando o
elemento dentro de um outro elemento, possivelmente div ou span, e colocar algumas das expressões
neste novo elemento. Por exemplo, suponha que você quer dar um loop sobre uma série de itens e
deixar alguns de fora. Aqui está uma tentativa de escrever um modelo que dá loops sobre os números de
zero a nove e pula três:

<!-- broken template -->


<ul>
<li tal:repeat="n python:range(10)"
tal:condition="python:n != 3"
tal:content="n">
1
</li>
</ul>

Esse modelo não funciona porque a condição é testada antes do repeat ser executado. O resultado é que
a variável n só é definida depois de ser testada. Aqui está um jeito de contornar este problema:

<ul>
<div tal:repeat="n python:range(10)"
tal:omit-tag="">
<li tal:condition="python:n != 3"
tal:content="n">
1
</li>
</div>
</ul>

Esse modelo resolve o problema definindo a variável n em uma tag de fechamento div. Note que a tag

143 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

div não aparecerá na saída devido a sua expressão tal:omit-tag. Isso pode não ter um aspecto muito
bom, mas funciona. Talvez as versões futuras dos Modelos de Páginas possam resolver esse problema
de uma maneira agradável.

Processamento de Formulário

Você pode processar formulários em DTML usando um modelo comum chamado "form/action pair"
("par formulário/ação"). Um form/action pair consiste de dois métodos DTML ou documentos: um
que contém um formulário que lê os dados de entrada do usuário, e um que contêm a ação de pegar
esses dados de entrada e retornar ao usuário uma resposta. O formulário chama a ação. Veja o Capítulo
4, "Conteúdo Dinâmico com DTML" para mais informações sobre o modelo form/action.

Os Modelos de Páginas do Zope não trabalham particularmente bem com o modelo form/action já que
eles assumem esse processamento de entrada e apresentam respostas que são tratadas pelo mesmo
objeto (a ação). Ao invés de usar o modelo form/action você deve usar o modelo form/action/response
(formulário/ação/resposta) nos Modelos de Páginas. O formulário e a resposta devem ser Modelos de
Páginas e a ação deve ser um script. O modelo do formulário apanha a entrada e chama o script de ação.
O script de ação deve processar a entrada e retornar um modelo de resposta. Esse modelo é mais
flexível do que o modelo form/action já que ele permite ao script retornar qualquer número dentre
diferentes objetos de resposta.

Por exemplo, aqui está uma parte de um modelo de formulário:

...
<form action="action">
<input type="text" name="name">
<input type="text" name="age:int">
<input type="submit">
</form>
...

Esse formulário pode ser processado por esse script:

## Script (Python) "action"


##parameters=name, age
##
container.addPerson(name, age)
return container.responseTemplate()

Esse script chama um método para processar as entradas e retorna outro modelo depois, a resposta.
Você pode carregar um Modelo de Página do Python chamando ele. O modelo de resposta tipicamente
contém uma confirmação de que o formulário foi processado corretamente. O script de ação pode fazer
todo tipo de coisas. Ele pode validar as entradas, tratar erros, mandar e-mail, e muito mais. Aqui está
um esboço de como validar as entradas com um script:

## Script (Python) "action"


##
if not context.validateData(request):
# if there's a problem return the form page template
# along with an error message
return context.formTemplate(error_message=Invalid data)

# otherwise return the thanks page


return context.responseTemplate()

Esse script dá validade ao formulário de entrada e retorna o modelo de formulário com uma mensagem

144 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

de erro se houver um problema. Você pode passar informação extra de Modelos de Páginas com
argumentos de palavras-chave. Os argumentos de palavras-chave estão disponíveis para o modelo
através da variável embutida options. Assim o modelo de formulário nesse exemplo deve incluir uma
seção como essa:

A mensagem de erro vai aqui.

Esse exemplo mostra como você pode exibir uma mensagem de erro que é passada ao modelo por meio
de argumentos de palavras-chave.

Dependendo da sua aplicação você pode escolher redirecionar o usuário para um Modelo de Página de
resposta ao invés de dar um retorno a ele diretamente. Isso resulta em duas vezes mais atividade na
rede de trabalho, mas pode ser útil porque muda a URL exibida no browser do usuário para a URL do
Modelo de Página, melhor do que o script de ação. Se você insistir em fazer um trabalho de baixa
qualidade, você pode criar sempre a versão mais fraca do modelo form-action usando Modelos de
Páginas. Você deve fazer isso apenas quando você não se importa com o tratamento de erro e quando a
resposta será sempre a mesma, não importa o que o usuário submeter. Já que Modelos de Páginas não
tem um equivalente para a dtml-call, você pode usar um dos vários números de cortes para chamar um
método de processamento de entrada sem inserir seus resultados. Por exemplo:

<span tal:define="unused here/processInputs"


tal:omit-tag=""/>

Este teste chama o método processInputs e atribui o resultado para a variável unused.

Expressões
Você já encontrou expressões de Modelos de Página. Expressões adquirirem valores para expressões
modelo. Por exemplo, expressões path descrevem objetos ao dá-los endereços, tais como
request/form/age, ou user/getUserName. Nesta seção você aprenderá sobre todos os diferentes tipos
de expressões e variáveis.

Variáveis Embutidas

Variáveis são nomes que você pode usar em expressões. Você já viu alguns exemplos de variáveis
embutidas, como template, user, repeat, e request. Aqui está uma lista completa de outras variáveis
embutidas e seu uso:

nothing

Um valor falso, similar a uma string em branco, você pode usar em tal:replace ou
tal:content para apagar uma tag ou seu conteúdo. Se você definir um atributo para nothing,
o atributo é removido da tag (ou não é inserido), diferente do que acontece com uma string
em branco.

default

Um valor especial que não muda nada quando usado na tal:replace, tal:content, ou
tal:attributes. Ele deixa o texto do modelo no lugar.

options

145 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Os argumentos de palavras-chave, if any, que eram passados para o modelo. Nota: options
está disponível apenas quando um modelo é chamado do Python. Quando um modelo é
carregado da web, nenhuma opção é apresentada.

attrs

Um dicionário de atributos da tag em uso no modelo. As chaves são os nomes de atributos e


os valores são valores originais dos atributos no modelo. Essa variável raramente é
necessária.

root

A raiz do objeto Zope. Use isso para obter objetos Zope de locações fixadas, não importa
onde seu modelo está situado ou chamado.

here

O objeto no qual o modelo está sendo chamado. Essa variável é tão freqüente quanto a
variável container, mas pode ser diferente se você está usando aquisição. Use ela para obter
objetos Zope que você espera encontrar em lugares diferentes dependendo de como o
modelo for chamado. A variável here é similar à variável context em scripts Python-based.

container

O contêiner (usualmente uma Pasta) no qual os modelos são guardados. Use isso para obter
objetos Zope de locações relativas ao home permantente do modelo. A variável container e
here se referem ao mesmo objeto quando um modelo é chamado de sua locação normal.
Contudo, quando um modelo é aplicado a outro objeto (por exemplo, um Método ZSQL)
container e here não farão referência ao mesmo objeto.

modules

Coleção disponível de módulos Python para modelos. Veja a seção sobre como escrever
expressões Python.

Você encontrará exemplos de como usar essas variáveis ao longo desse capítulo.

Expressões String

Expressões String permitem que você combine facilmente expressões path com texto. Todo o texto
depois da guia string: é tomada e procurada por expressões path. Cada expressão path deve ser
precedida pelo sinal de dólar ($). Aqui estão alguns exemplos:

"string:Just text. There's no path here."


"string:copyright $year, by me."

Se a expressão path tiver mais de uma parte, ou precisar ser separada do texto que a segue, ela deve ser
envolvida por chaves ({}). Por exemplo:

"string:Three ${vegetable}s, please."


"string:Your name is ${user/getUserName}!"

Veja como no exemplo acima, você precisa envolver a path vegetable com chaves para que o Zope não
confunda com vegetables.

146 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Já que o texto está dentro de um valor atributo, você pode incluir somente uma quota dupla ao usar a
sintaxe da entidade ". Já que o sinal de dólar é usado para assinalar expressões path, um sinal de dólar
literal deve ser escrito como dois sinais de dólar ($$). Por exemplo:

"string:Please pay $$$dollars_owed"


"string:She said, "Hello world.""

Algumas operações complexas de formatação de strings (tais como procura e substituição ou troca de
letras maiúsculas) não podem ser feitas facilmente com expressões string. Para esses casos, você deve
usar expressões Python ou Scripts.

Expressões Path

Expressões path são usadas em objetos com um endereço que se parece com um endereço de URL. Um
path descreve um traversal de objeto a objeto. Todos os paths começam com um objeto conhecido
(assim como uma variável embutida, uma variável de repetição ou uma variável definida pelo usuário) e
partem daí para o objeto desejado. Aqui estão alguns exemplos de expressões path:

template/title
container/files/objectValues
user/getUserName
container/master.html/macros/header
request/form/address
root/standard_look_and_feel.html

Com expressões path você pode traverse de um objeto para seus sub-objetos incluindo propriedades e
métodos. Você também pode usar aquisição em expressões path. Veja a seção "Chamando Scripts da
Web" no Capítulo 8, "Scripts Avançados do Zope" para mais informações sobre aquisição e path
traversal.

O Zope restringe traversal objetos em expressões path do mesmo jeito que restringe acesso a objetos
via URLs. Você deve ter permissões adequadas para acessar um objeto para se referir a ele com uma
expressão path. Veja o Capítulo 6, "Usuários e Segurança" para mais informações sobre controle de
acesso a objetos.

Paths Alternados

O endereço template/title tem garantia de existir a cada vez que o modelo é usado, mesmo sendo uma
string em branco. Alguns paths, como request/form/x, podem não existir durante o carregamento do
modelo. Isso normalmente causa erros quando o Zope avalia a expressão path. Quando um endereço
não existe, você pode ter um path fall-back ou valores que você gostaria de usar no seu lugar. Por
exemplo, se request/form/x não existir você deve usar no seu lugar here/x. Você pode fazer isso ao listar
os endereços em ordem de preferência, separados pelo caractere barra vertical (|):

<h4 tal:content="request/form/x | here/x">Header</h4>

As variáveis nothing e default são muito úteis em uma lista de alternativas, como o endereço visto
anteriormente. Por exemplo, default diz a tal:content para deixar o conteúdo modelo. Expressões TAL
diferentes interpretam default e nothing diferentemente. Veja o Apêndice C, "Referências a Modelos de
Páginas do Zope" para mais informação.

Você pode usar também uma expressão não-path como a última parte em uma expressão de
path-alternado. Por exemplo:

147 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<p tal:content="request/form/age|python:18">age</p>

Nesse exemplo, se o endereço request/form/age não existe, então o valor é o número 18. Esse
formulário permite que você especifique valores padrão para usar que não podem ser expressados como
paths. Veja, você pode usar apenas uma expressão não-path como última alternativa.

Você pode testar também a existência de um endereço diretamente com o prefixo tipo expressão exists.
Veja a seção "Expressões Exist" abaixo para mais informações sobre expressões exists.

Expressões Not

As expressões Not deixam você negar o valor de outras expressões. Por exemplo:

<p tal:condition="not:here/objectIds">
There are no contained objects.
</p>

As Expressões Not retornam verdadeiro quando a expressão na qual elas estão sendo usadas é falsa, e
vice versa. Em Zope, variáveis non-existent, zero, strings vazias, seqüências vazias, nothing, and None
são consideradas falso, enquanto que todo o resto é verdadeiro.

Não há muita razão para usar expressões not com expressões Python já que, em Python, você pode usar
a palavra-chave not no seu lugar.

Expressões Nocall

Uma expressão path comum tenta carregar o objeto que ela busca. Isso significa que se o objeto é uma
função, um Script, um Método, ou algum outro tipo de coisa executável, então a expressão irá avaliar
para o resultado de chamar o objeto. Geralmente é isso que você quer, mas nem sempre. Por exemplo,
se você quer por um Documento DTML dentro de uma variável para que você possa aplicar-se de suas
propriedades, você não pode usar uma expressão path normal porque ela irá carregar o Documento
como uma string.

Se você colocar a expressão type prefix nocall: na frente de um path, isso evita a interpretação e
simplesmente lhe fornece o objeto. Por exemplo:

<span tal:define="doc nocall:here/aDoc"


tal:content="string:${doc/getId}: ${doc/title}">
Id: Title</span>

Esse tipo de expressão também é importante quando você quer definir uma variável para envolver uma
função ou uma classe de um modulo, para usar em uma expressão Python.

As expressões nocall podem ser usadas também em funções, e não só em objetos:

<p tal:define="join nocall:modules/string/join">

Essa expressão define a variável join como uma função (string.join), e não só como o resultado de
chamar uma função.

Expressões Exists

148 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Uma expressão exists é verdadeira se seu endereço existe, senão é falsa. Por exemplo aqui está um jeito
de mostrar uma mensagem de erro apenas se ela passar pelo que é solicitado:

<h4 tal:define="err request/form/errmsg | nothing"


tal:condition="err"
tal:content="err">Error</h4>

Você pode fazer a mesma coisa mais facilmente com uma expressão exists:

<h4 tal:condition="exists:request/form/errmsg"
tal:content="request/form/errmsg">Error!</h4>

Você pode combinar expressões exists com expressões not, por exemplo:

<p tal:condition="not:exists:request/form/number">Por favor digite um número entre 0 e 5</p>

Note que neste exemplo você não pode usar a expressão, "not:request/form/number", já que essa
expressão será verdadeira se a variável number existir e for zero.

Expressões Python

A lingugem de programação Python é simples e expressiva. Se você nunca trbalhou com ela antes, você
deve ler um dos excelentes tutoriais ou introduções disponíveis no website da Python.

Uma expressão Modelo de Página Python pode conter qualquer coisa que a linguagem Python
considerar uma expressão. Você não pode usar expressões como if e while. Em adição, o Zope impõem
algumas restrições de segurança para que você continue acessando informação protegida, trocando
dados seguros, e criando problemas como loops infinitos. Veja o Capítulo 8, "Scripts Avançados em
Zope" para mais informações sobre restrições de segurança do Python.

Comparações

Um lugar onde expressões Python são praticamente necessárias é na expressão tal:condition.


Geralmente você quer comparar duas strings ou números, e não há nenhuma outra maneira de fazer
isso sem expressões Python. Você pode usar os operadores de comparação < (menor que), > (maior
que), == (igual a), e != (diferente de). Você também pode usar os operadores booleanos and, not e or.
Por exemplo:

<p tal:repeat="widget widgets">


<span tal:condition="python:widget.type == gear>
Gear #<span tal:replace="repeat/widget/number>1</span>:
<span tal:replace="widget/name">Name</span>
</span>
</p>

Esse exemplo dá um loop sobre uma coleção de objetos, testando cada atributo do objeto type.

Algumas vezes você quer escolher valores diferentes dentro de uma única expressão baseada em uma
ou mais condições. Você pode fazer isso com a função test:

149 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Você <span tal:define="name user/getUserName"


tal:replace="python:test(name==Anonymous User,
need to log in, default)">
está logado como
<span tal:replace="name">Nome</span>
</span>

A função test trabalha como uma expressão if/then/else (se/então/senão). Veja Apêndice A, "Referência
DTML" para mais informação sobre a função test. Aqui está outro exemplo de como você pode usar a
função test:

<tr tal:define="oddrow repeat/item/odd"


tal:attributes="class python:test(oddrow, oddclass,
evenclass)">

Sem a função test você teria que escrever dois elementos tr cada um com uma condição diferente, um
para even rows, e outro para odd rows.

Usando outros Tipos de Expressões

Você pode usar outros tipos de expressões dentro de uma expressão Python. Cada tipo de expressão
tem uma função correspondente com o mesmo nome, incluindo: path(), string(), exists(), e nocall().
Isso permite que você escreva expressões como:

"python:path(here/%s/thing % foldername)"
"python:path(string(here/$foldername/thing))"
"python:path(request/form/x) or default"

O exemplo final tem um significado um pouco diferente da expressão path, "request/form/x | default",
já que ele usará o texto default se "request/form/x" não existir ou se ele for falso.

Obtendo Objetos do Zope

Muito do poder do Zope envolve vinculação de objetos especializados. Seus Modelos de Páginas podem
usar Scripts, Métodos SQL, Catálogos, e custom content objects. Para usar esses objetos você também
tem que saber como conseguir acessá-los sem Modelos de Páginas.

As propriedades de objetos usualmente são atributos, então você pode obter um título do modelo com a
expressão "template.title". A maioria dos objetos Zope suportam aquisição, o que permite que você
obtenha atributos de objetos "pais". Isso significa que a expressão Python "here.Control_Panel" irá
adquirir o objeto Painel de Controle do Folder raiz. Métodos de objetos são atributos, como em
"here.objectIds" e "request.set". Objetos contidos em um Folder podem ser acessados como atributos
do Folder, mas desde que eles freqüentemente tenham Ids que não sejam identificadores Python
válidos, você não pode usar a notação normal. Por exemplo, você não pode usar essa expressão Python:

"python:here.penguin.gif"'.

Você deve escrever:

"python:getattr(here, penguin.gif)"

Já que Python não suporta nomes de atributos com períodos.

Alguns objetos, como request, modules, e Folders do Zope suportam itens de acesso Python, por

150 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

exemplo:

request['URL']
modules['math']
here['thing']

Quando você usa acesso a itens em um Folder, ele não tenta adquirir o nome, então terá sucesso apenas
se realmente houver um objeto que contenha esse Id no Folder.

Como foi mostrado nos capítulos anteriores, expressões path permitem que você ignore detalhes sobre
como você obtém de um objeto para o próximo. O Zope tenta acesso ao atributo, depois acesso ao item.
Você pode escrever:

"here/images/penguin.gif"

no lugar de:

"python:getattr(here.images, penguin.gif)"

e:

"request/form/x"

no lugar de:

"python:request.form['x']"

Por outro lado, expressões path não permitem que você especifique esses detalhes. Por exemplo, se
você tem uma variável formulário nomeada "get", você deve escrever:

"python:request.form['get']"

já que essa expressão path:

"request/form/get"

irá avaliar para o método "get" do dicionário formulário.

Se você preferir você pode usar expressões path dentro de expressões Python usando a função path(),
como descrito acima.

Usando Scripts

Objetos Script freqüentemente são usados para encapsular funções lógicas e manipulação complexa de
dados. Qualquer vez que você se encontrar escrevendo um monte de expressões TAL que contenham
expressões complicadas, você deve considerar que você pode fazer melhor o trabalho usando um Script.
Se você tem problemas para entender suas expressões modelo, então é melhor simplificar seu Modelo
de Página e usar Scripts para as coisas mais complexas.

Cada Script tem uma lista de parâmetros que ele espera que sejam dados quando ele for chamado. Se

151 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

esta lista estiver vazia, então você pode usar o Script ao escrever uma expressão path. Ou então, você
terá que usar uma expressão Python para suprir o argumento, como esse:

"python:here.myscript(1, 2)"
"python:here.myscript(arg, foo=request.form['x'])"

Se você quer retornar mais do que um item de dados de um Script para um Modelo de Páginas, é uma
boa idéia retorna-lo em um dicionário. Dessa forma, você pode definir uma variável para segurar todos
os dados, e usar expressões path para referir-se a cada item. Por exemplo, suponha que o script
getPerson retorne um dicionário com chaves name e age:

<span tal:define="person here/getPerson"


tal:replace="string:${person/name} is ${person/age}">
Nome tem 30</span> anos de idade.

É claro, é bom para retornar objetos Zope e listas Python também.

Chamando DTML

Diferente dos Scripts, Métodos DTML e Documentos não tem uma lista de parâmetros explicita. Em vez
disso, eles esperam que seja passado um cliente, um mapeamento, ou argumentos de palavra-chavas.
Eles usam esses parametros para construir um namespace. Veja o Capítulo 7 para mais informação
sobre chamadas de DTML.

Quando o Zope publica um objeto DTML através da web, ele passa o contexto do objeto como o cliente,
e o REQUEST como o mapeamento. Quando um objeto DTML chama outro, ele passa seu próprio
namespace como o mapeamento, e não o cliente.

Se você usa uma expressão path para interpretar um objeto DTML, ela passará um namespace com
request, here, e as variáveis do modelo que já estão nele. Isso significa que o objeto DTML será capaz de
usar os mesmos nomes como se eles estivessem sendo publicados no mesmo contexto como o modelo,
mais a variável nomes definida no modelo.

Módulos Python

A linguagem Python possui um grande número de módulos, que fornecem uma grande variedade de
capacidades para programas Python. Cada módulo é uma coleção de funções Python, dados, e classes
relacionadas a um único propósito, como cálculos matemáticos ou expressões regulares.

Vários módulos, incluindo "math" e "string", estão disponíveis em expressões Python à revelia. Por
exemplo, você pode obter o valor do pi do módulo math escrevendo "python:math.pi". Porém, para
acessá-lo de uma expressão path, você terá que usar a variável modules, "modules/math/pi".

O módulo "string" está oculto em expressões Python pela expressão "string" expression tipo função,
então você terá que acessa-lo através de variáveis modules. Você pode fazer isso diretamente na
expressão na qual você o usa, ou definir uma variável global para ele:

tal:define="global mstring modules/string"


tal:replace="python:mstring.join(slist, :)"

Na prática você raramente terá que fazer isso já que você pode usar métodos string na maior parte do
tempo ao invés de ter que depender de funções no módulo string.

Os módulos podem ser agrupados dentro de pacotes, que são simplesmente uma maneira de organizar

152 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

e nomear módulos relacionados. Por exemplo, Scripts do Zope Python-based são fornecidos por uma
coleção de módulos no subpacote "Scripts Python" do Pacote de "Produtos" do Zope. Particularmente, o
módulo "padrão" neste pacote fornece um número de funções de formatação úteis que são padrão na
tag "var" de DTML. O nome completo desse módulo é "Products.PythonScripts.standard", assim você
pode obter acesso a ele usando as expressões abaixo:

tal:define="global pps modules/Products/PythonScripts/standard"


tal:define="global pps python:modules['Products.PythonScripts.standard']"

A maior parte dos módulos Python não podem ser acessados de Modelos de Páginas, DTML, ou Scripts
a não ser que você adicione reivindicação de segurança do Zope a eles. Esse procedimento está for a do
âmbito desse livro. Veja o Guia do Programador de Zope (Zope Developer's Guide) para mais
informações.

Macros
Até agora, você tem visto como modelos de páginas podem ser usados para adicionar comportamento
dinâmico a web pages individuais. Outra característica dos modelos de páginas é a capacidade de reusar
elementos de look and feel em muitas páginas.

Por exemplo, com Modelos de Páginas, você pode ter um site que possui um padrão de look and feel.
Não importa o "conteúdo" da página, ela terá um cabeçalho padrão, barra de rolagem, roda-pé, e/ou
outros elementos da página. Esse é um requisito muito comum para web sites.

Você pode reusar elementos de apresentação nas páginas com macros. As Macros definem uma seção
de uma página que pode ser reusada em outras páginas. Uma macro pode ser uma página inteira, ou
apenas um pedaço de uma página que tem um cabeçalho ou um roda-pé. Depois que você define uma ou
mais macros em um Modelo de Páginas, você pode usá-la em outro Modelo de Páginas.

Usando Macros

Você pode definir macros com atributos de tag similares às expressões TAL. Os atributos de tag da
macro são expressões chamadas de Linguagem de Atributos de Tag de Expansão de Macro (Macro
Expansion Tag Attribute Language - METAL). Aqui está um exemplo de definição de macro:

<p metal:define-macro="copyright">
Copyright 2001, <em>Foo, Bar, and Associates</em> Inc.
</p>

Essa expressão metal:define-macro define uma macro nomeada "copyright". A macro consiste de uma
tag p e seus conteúdos (incluindo todas as tags contidas).

As macros definidas em um Modelo de Página são guardadas no atributo macro do modelo. Você pode
usar macros de outro modelo de página ao referir-se a eles através do atributo macros do Modelo de
Páginas no qual ele está definido. Por exemplo, suponha que a macro copyright está em um Modelo de
Páginas chamado "master_page". Eis como usar a macro copyright de outro Modelo de Página:

<hr>
<b metal:use-macro="container/master_page/macros/copyright">
A Macro vem aqui
</b>

Neste modelo de páginas, a tag b será completamente substituída pela macro quando o Zope carregar a

153 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

página:

<hr>
<p>
Copyright 2001, <em>Foo, Bar, and Associates</em> Inc.
</p>

Se você mudar a macro (por exemplo, se o proprietário do copyright mudar de nome) então todo o
Modelo de Páginas que usa a macro irá automaticamente refletir a mudança.

Veja como a macro é identificada por uma expressão path usando a expressão metal:use-macro. A
expressão metal:use-macro substitui o elemento da expressão pela macro nomeada.

Detalhes da Macro

As expressões metal:define-macro, e metal:use-macro são muito simples. Porém existem algumas


sutilizas melhor mencionadas.

Um nome de macro deve ser único dentro do Modelo de Páginas no qual ele é definido. Você pode
definir mais do que uma macro em um modelo, mas todas elas precisam ter nomes diferentes.

Normalmente você irá se referir a uma macro na expressão metal:use-macro com uma expressão path.
Porém, você pode usar qualquer tipo de expressão que quiser desde de que a expressão retorne uma
macro. Por exemplo:

<p metal:use-macro="python:here.getMacro()">
Replaced with a dynamically determined macro,
which is located by the getMacro script.
</p>

O uso expressões Python para alocar macros deixa você variar dinamicamente qual macro seu modelo
usa.

Você pode usar a variável default com a expressão metal:use-macro:

<p metal:use-macro="default">
Este conteúdo permanence &#8211; nenhuma macro é usada
</p>

O resultado é o mesmo do que usar default com tal:content e tal:replace, o elemento da expressão não
muda.

Se você tentar usar a variável nothing com metal:use-macro você terá um erro, já que nothing não é
uma macro. Se você quer usar nothing para condicionalmente incluir uma macro, você deve em vez
disso finalizar a expressão metal:use-macro com uma expressão tal:condition.

O Zope trata as macros primeiro quando interpreta seus modelos. Depois o Zope avalia as expressões
TAL. Por exemplo, considere essa macro:

<p metal:define-macro="title"
tal:content="template/title">
template's title
</p>

Quando você usa essa macro ela irá inserir o título de um modelo no qual a macro é usada e não o título

154 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

de um modelo no qual a macro está definida. Em outras palavras, quando você usa uma macro, é como
copiar o texto de uma macro para dentro do seu modelo e depois carregar o seu modelo.

Se você marcar a opção Expandir macros quando editar (Expand macros when editing) na Aba Edit do
Modelo de Páginas, então qualquer macros que você usar será expandido na fonte do seu modelo. Esse
é a conduta padrão do Zope, e em geral é isso que você quer, já que isso permite que você edite uma
página completa e válida. Porém, algumas vezes, especialmente quando você está editando no ZMI, ao
invés de usar uma ferramenta de edição WYSIWYG, é mais conveniente não expandir as macros quando
editar. Nesses casos, simplesmente desmarque a opção.

Usando Slots

As macros são muito mais úteis se você puder desconsiderar(override) partes delas quando usá-las.
Você pode fazer isso definindo slots na macro que você pode preencher quando usar o modelo. Por
exemplo, considere uma macro de side bar:

<p metal:define-macro="sidebar">
Links
<ul>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/support">Support</a></li>
<li><a href="/contact">Contact Us</a></li>
</ul>
</p>

Essa macro é boa, mas suponha que você gostaria de incluir alguma informação adicional nas sidebar
em algumas páginas. Um jeito de fazer isso é usando slots:

<p metal:define-macro="sidebar">
Links
<ul>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/support">Support</a></li>
<li><a href="/contact">Contact Us</a></li>
</ul>
<span metal:define-slot="additional_info"></span>
</p>

Quando você usa essa macro você pode escolher preencher o slot dessa forma:

<p metal:fill-slot="container/master.html/macros/sidebar">
<b metal:fill-slot="additional_info">
Make sure to check out our <a href="/specials">specials</a>.
</b>
</p>

Quando você interpretar esse modelo a side bar irá incluir a informação extraque você forneceu no slot:

155 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<p>
Links
<ul>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/support">Support</a></li>
<li><a href="/contact">Contact Us</a></li>
</ul>
<b>
Make sure to check out our <a href="/specials">specials</a>.
</b>
</p>

Veja como o elemento span que define o slot é substituído com o elemento b que preenche o slot.

Adequando a Apresentação Padrão

Adequando a Apresentação Padrão

Um uso comum de slot é para fornecer apresentação padrão que você pode adequar. No exemplo de slot
da última seção, a definição de slot era apenas um elemento span vazio. Porém, você pode fornecer
apresentação padrão em uma definição de slot. Por exemplo, considere essa macro para sidebar
corrigida:

<div metal:define-macro="sidebar">
<p metal:define-slot="links">
Links
<ul>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/support">Support</a></li>
<li><a href="/contact">Contact Us</a></li>
</ul>
</p>
<span metal:define-slot="additional_info"></span>
</div>

Agora a sidebar está completamente adequada. Você pode preencher os links do slot para redefinir os
links da sidebar. Porém, se você escolher não preencher o slot links então você terá links default que
aparecerão dentro do slot.

Você ainda pode usar essa técnica adicional definindo slots dentro de slots. Isso permite que você passe
por cima da apresentação padrão com um bom grau de precisão. Aqui está uma macro de sidebar que
define slots dentro de slots:

<div metal:define-macro="sidebar">
<p metal:define-slot="links">
Links
<ul>
<li><a href="/">Home</a></li>
<li><a href="/products">Products</a></li>
<li><a href="/support">Support</a></li>
<li><a href="/contact">Contact Us</a></li>
<span metal:define-slot="additional_links"></span>
</ul>
</p>
<span metal:define-slot="additional_info"></span>
</div>

Se você quiser adequar os links da sidebar pode ainda preencher o slot links para desconsirar
completamente os links, ou você pode preencher o slot additional_links para inserir alguns links a
mais depois dos links padrão. Você pode aninhar quantos slots quiser.

156 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Unindo METAL e TAL

Você pode usar expressões METAL e TAL juntas nos mesmos elementos. Por exemplo:

<ul metal:define-macro="links" tal:repeat="link here/getLinks">


<li>
<a href="link url"
tal:attributes="url link/url"
tal:content="link/name">link name</a>
</li>
</ul>

Já que expressões METAL são avaliadas antes que expressões TAL, não há conflitos. Esse exemplo
também é interessante já que ele adapta(?) uma macro sem usar slots. A macro chama o Script
getLinks para determinar os links. Assim você pode adequar os links do seu site para be redefinindo o
Script getLinks de locais diferentes dentro do seu site.

Nem sempre é fácil de compreender o melhor jeito de adequar look and feel em partes diferentes do seu
site. Em geral você deve usar slots para passar por cima de elementos de apresentação e deve usar
Scripts para fornecer conteúdo dinamicamente. No caso do exemplo dos links, é questionável se os links
são conteúdo ou apresentação. Os Scripts provavelmente fornecerão uma solução mais flexível,
especialmente se o seu site inclui objetos de conteúdo de link.

Conjunto das Macros da Página

Melhor do que usar macros para partes da apresentação dividida entre as páginas, você pode usar
macros para definir páginas inteiras. Os Slots tornam isso possível. Aqui está um exemplo de macro que
define uma página inteira:

<html metal:define-macro="page">
<head>
<title tal:content="here/title">O título</title>
</head>

<body>
<h1 metal:define-slot="headline"
tal:content="here/title">título</h1>

<p metal:define-slot="body">
Esse é o corpo da página.
</p>

<span metal:define-slot="footer">
<p>Copyright 2001 Fluffy Enterprises</p>
</span>

</body>
</html>

Essa macro define uma página com três slots, headline, body, e footer. Veja como o slot headline
inclui uma expressão TAL para determinar o conteúdo do cabeçalho dinamicamente.

Então você pode usar essa macro em modelos para diferentes tipos de conteúdo, ou diferentes partes
do seu site. Por exemplo, aqui está como um modelo para novos itens deve usar essa macro:

157 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<html metal:use-macro="container/master.html/macros/page">

<h1 metal:fill-slot="headline">
Press Release:
<span tal:replace="here/getHeadline">Headline</span>
</h1>

<p metal:fill-slot="body"
tal:content="here/getBody">
O corpo do novo item vem aqui
</p>

</html>

Esse modelo redefine o slot headline para incluir as palavras, "Press Release" e chama o método
getHeadline do objeto corrente. Ele redefine também o slot body para chamar o método getBody do
objeto corrente.

A coisa mais importante (powerful) sobre essa abordagem é que agora você pode mudar a macro page e
o modelo do press release será automaticamente atualizado. Por exemplo, você pode colocar o corpo da
página em uma tabela e adicionar uma sidebar na esquerda e o modelo de press release irá usar
automaticamente use esses novos elementos de apresentação.

Essa é uma solução muito mais flexível para controlar o visual e feel das páginas depois da solução
DTML standard_html_header e standard_html_footer. De fato, o Zope trás um estoque de
modelos de páginas no quadro raiz chamado standard_template.pt que inclui uma página inteira
de macro com um slot head e body. Aqui está como você deve usar essa macro em um modelo:

<html metal:use-macro="here/standard_template.pt/macros/page">
<div metal:fill-slot="body">
<h1 tal:content="here/title">Title</h1>
<p tal:content="here/getBody">Body text goes here</p>
</div>
</html>

O uso da macro standard_template.pt é mais similar ao uso de outros conjuntos de macro na


página. A única sutileza apontada é a path ser usada/costumar para localizar a macro. Neste exemplo a
path começa com here. Isso significa que o Zope irá procurar o objeto standard_template.pt
usando uma aquisição de inicialização no objeto que o modelo for aplicado. Isso permite que você
adapte os modelos de look and feel ao criar objetos custom standard_template.pt objects em vários
locais. Esse é exatamente o mesmo truque que você usa para adequar look and feel ao passar por cima
de standard_html_header e standard_html_footer em localizações do site. Porém, com
standard_template.pt você tem mais escolhas. Você pode escolher iniciar o path para a macro com
root ou com container, assim como com here também. Se o path começa com root então você sempre
irá obter o modelo padrão no qual está localizado o quadro raiz. Se o path começa com container
então o Zope irá procurar por um modelo padrão usando inicialização de aquisição no quadro em que o
modelo for definido. Isso permite que você adapte look feel dos modelos, mas não permite que você
customize o look e feel de objetos diferentes baseado em sua localização no site.

Cacheando Modelos
Enquanto interpretar Modelos de Páginas normalmente é bem rápido, algumas vezes não é
suficientemente rápido. Para páginas acessadas freqüentemente, ou páginas que levam muito tempo

158 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

para carregar, você pode querer to trocar alguns comportamentos dinâmicos por velocidade.
Cacheamento permite que você faça isso. Para mais infomação sobre cacheamento veja a seção
"Gerenciamento de Cache" do Capítulo 3, "Objetos Básicos".

Você pode cachear Modelos de Páginas usando um gerenciador de cache do mesmo jeito que você pode
cachear outros objetos. Para cachear um Modelo de Páginas, você deve associa-lo com um gerenciador
de cache. Você pode fazer isso indo ao vizualizador Cache do seu Modelo de Páginas e selecionando o
gerenciador de cache, ou indo até o vizualizador Associate do seu gerenciador de cache e localizando seu
Modelo de Páginas.

Aqui está um exemplo de como cachear um Modelo de Páginas. Primeiro crie um script name baseado
em Python long.py com esse conteúdo:

## Script (Python) "long.py"


##
for i in range(500):
for j in range(500):
for k in range(5):
pass
return 'Done'

O propósito desse script é apanhar uma grande quantidade de tempo de execução. Agora crie um
Modelo de Páginas que use esse script, por exemplo:

<html>
<body>
<p tal:content="here/long.py">results</p>
</body>
</html>

Agora visualize essa página. Veja como ela leva um instante para carregar. Agora vamos melhorar
radicalmente seu tempo de carregamento com cacheamento. Crie um Ram Cache Manager se você ainda
não tem um. Se assegure de criá-lo dentro do mesmo quadro como seu Modelo de Páginas, ou em um
nível mais alto. Agora visite o vizualizador Cache do seu Modelo de Páginas. Escolha o Gerenciador de
Ram Cache que você criou e clique Save Changes (Salvar as Mudanças). Clique no link Cache Settings
(Configurações de Cache) para ver como seu Gerenciador de Ram Cache está configurado. Como
padrão, sua cache guarda objetos por uma (3600 segundos). Voc~e pode querer ajustar esse número
dependendo da sua aplicação. Agora volte para seu Modelo de Páginas e visualize ela de novo. Ela deve
levar um momento para carregar. Agora recarregue (atualizar) a página, e veja ela carregar
imediatamente. Você pode recarregar a página de novo e de novo, e ela sempre carregarrá
imediatamente já que agora a página está cacheada.

Se você mudar seu Modelo de Páginas, então isso será removido da cache. Então a próxima vez que você
visualiza-lo, levará um momento para carregar. Mas depois disso vai carregar rapidamente já que será
cacheado novamente.

Cacheamento é uma técnica simples mas muito poderosa para o melhoramento da performance. Você
não tem que ser um gênio para usar cachamento e ele pode fornecer grandes aceleramentos. Seu tempo
fica bem melhor usando cacheamento para aplicações com performance critica.

Utilidades do Modelo da Página


Os Modelos de Páginas do Zope são poderosos mas simples. Diferente de DTML, Modelos de Páginas
não lhe oferecem um monte de características de comodidade para coisas como paginação, drawing
trees, sorting, etc. O criador do Modelo de Páginas queria mantê-los simples. Porém, você pode sentir

159 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

falta de alguns dos benefícios embutidos que DTML fornece. Para se dirigir a essas necessidades, o Zope
possui utilidades designadas para aumentar os Modelos de Páginas.

Paginando Grandes Conjuntos de Informação

Quando um usuário pesquisa um banco de dados e obtém centenas de resultados, freqüentemente é


melhor mostrá-los em várias páginas com apenas vinte resultados por página, ao invés de colocar todos
os resultados uma única página. Dividir grandes listas em listas menores é chamado de paginação.

Diferente de DTML, que fornece páginação incorporada dentro da linguagem, Modelos de Páginas
suportam paginação usando um objeto especial Batch que vem do módulo utilitário ZTUtils. Veja
Appendix B, "Referencia API", para mais informação sobre o módulo Python ZTUtils.

Aqui está um exemplo simples mostrando como criar um objeto Batch:

<ul tal:define="lots python:range(100);


batch python:modules['ZTUtils'].Batch(lots,
size=10,
start=0)">
<li tal:repeat="num batch"
tal:content="num">0
</li>
</ul>

Esse exemplo carrega uma lista com 10 itens (neste caso, do número 0 até 9). O objeto Batch corta uma
lista longa em grupos ou montes. Neste caso ele quebra uma lista com uma centena de itens em montes
de dez itens.

Você pode mostrar um monte diferente de dez itens passando um número inicial diferente:

<ul tal:define="lots python:range(100);


batch python:modules['ZTUtils'].Batch(lots,
size=10,
start=13)">

Esse batch começa com o décimo quarto item e termina com o vigésimo terceiro. Em outras palavras, ele
mostra os números entre 13 e 22. é importante notar que o argumento start do batch é o index (índice)
do primeiro item. Os índices contam a prtir de zero, ao invés de contra a partir do 1. Então indexa 13
pontos a partir do décimo quarto item na seqüência. Python usa indices para se referir a listas de items.

Normalmente quando você usa batches você irá querer incluir elementos de navegação na página para
permitir que os usuários se moverem de batch em batch. Aqui está um exemplo de paginação full-blow
que mostra como navegar entre batches:

160 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<html>
<head>
<title tal:content="template/title">The title</title>
</head>
<body tal:define="employees here/getEmployees;
start python:path(request/start) or 0;
batch python:modules['ZTUtils'].Batch(employees,
size=10,
start=start);
previous python:batch.previous;
next python:batch.next"> <p>
<a tal:condition="previous"
tal:attributes="href string:${request/URL0}?start:int=${previous/first}"
href="previous_url">previous</a>
<a tal:condition="next"
tal:attributes="href string:${request/URL0}?start:int=${next/first}"
href="next_url">next</a>
</p> <ul tal:repeat="employee batch" >
<li>
<span tal:replace="employee/name">Bob Jones</span>
makes $<span tal:replace="employee/salary">100,000</span>
a year.
</li>
</ul> </body>
</html>

Esse exemplo iterates sobre batches (montes) de resultados do Método ZSQL getEmployees. Ele
mostra um link de previous (anterior) e next (próximo) se necessário para que você possa ver todos os
resultados de um batch de cada vez.

Dê uma olhada na expressão tal:define no elemento body. Ela define um grupo de variáveis de
paginação. A variável employees é potencialmente uma grande lista de objetos empregados retornada
pelo Método ZSQL getEmployees. A Segunda variável, start, é configurada para o valor de
request/start ou para zero se não há variável start na pesquisa. A variável start contém
endereços de onde você está na lista de empregados. A variável batch é um monte batch de dez itens
das listas de empregados. A batch começa no local especificado pela variável start. As variáveis
previous e next se referem aos montes anteriores e os próximos (if any). Já que todas as varíveis
estão definidas no elemento body, elas estão disponíveis para todos os elementos dentro do corpo da
página.

Depois vamos olhar os links de navegação. Eles criam hyperlinks para browsear os batches anterior e
próximo. A expressão tal:condition primeiro testa para ver se há um batch de anterior e próximo.
Se há um bacth de anterior ou próximo, então o link é carregado, se não, não há nenhum link. A
expressão tal:attributes cria um link para os bacthes anterior e próximo. O link é simplesmente a
URL ou a página corrente (request/URL0) contendo uma string de pesquisa que indica o começo do
índice do batch. Por exemplo, se o batch corrente começa com índice 10, então o batch anterior
começará com um índice 0. a variável first do batch fornece seu índice de começo (staring index),
então, nesse caso, previous.start será 0.

Não é importante entender completamente como funciona esse exemplo. Simplesmente copie ele, ou
use um exemplo de paginação criado pelo Z Search Interface. Depois quando você quiser fazer uma
paginação mais complexa você pode experimentar trocar o código do exemplo. Não esqueça de
consultar o Appendix B, "Referência API" para mais informações sobre o módulo ZTUtils e objetos
Batch.

Utilidades Diferentes

O Zope fornece uma dupla de módulos Python que podem ser úteis no uso de Modleos de Páginas. Os
módulos string, math e random podem ser usados em expressões Python para o formatação de
strings, funções matemáticas e geração de números pseudo-randômicos. Esses mesmos módulos estão

161 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

disponíveis para from DTML e scripts baseados em Python. Veja o Appendix B, "Referência API " para
mais informação sobre esses módulos.

O módulo Products.PythonScripts.standard foi designado a fornecer utilidades para scripts


baseados em Python, mas também é útil para Modelos de Páginas. Ele inclui várias funções de
formatação de strings e números. Veja o Appendix B, "Referência API" para mais informação.

Como foi mencionado anteriormente neste capítulo, o módulo sequence fornece uma função sort
muito útil. Veja o Appendix B, "Referência API" para mais detalhes.

Finalmente o módulo AccessControl inclui uma função e uma classe que você irá precisar se quiser
testar o acesso e obter o usuário autenticado. Veja o Appendix B, "Referência API" para mais
informação.

Conclusão
Esse capítulo aborda todos os cantos e todas as fendas sobre Modelos de Páginas e depois de lê-lo você
poderá sentir se um pouco oprimido. Mas não se preocupe, você não precisa saber tudo que foi exposto
neste capítulo para usar efetivamente Modelos de Páginas. Você deve entender os diferentes tipos de
path e macros, mas você pode revisar o resto do material quando precisa-lo. As características
avançadas que você tem que aprender neste capítulo estarão lá para você quando você precisar. É
incentivador saber que quando você está pronto você pode fazer alguns truques muito impressionantes
com Modelos de Páginas.

11. Scripts Avançados em Zope


Este capítulo mostra scripts no Zope com Python e Perl. Nele mostramos como escrever
lógicas de aplicação em Zope usando uma ferramenta mais poderosa do que a DTML.
Trata da idéia de scripts no Zope, e foca em scripts baseados em Python e Perl. Este
capítulo mostra a você como adicionar no seu site scripts industrial-strength.

O Zope gerencia sua apresentação, lógica e dados com objetos. Até agora, você tem visto como o Zope
consegue gerenciar a apresentação com DTML e dados com arquivos e imagens. Este capítulo mostra a
você como adicionar objetos Script que permitem você escrever scripts em Python e Perl através do seu
web browser.

O que é lógica e como ela difere da apresentação? Lógica oferece as ações que modificam objetos,
enviam mensagens, testam condições e respondem à eventos, enquanto a apresentação formata e exibe
informações e relatórios. Tipicamente você usará DTML para controlar a apresentação, e o script do
Zope com Python e Perl para controlar a lógica.

Scripts no Zope
Objetos Script do Zope são objetos que encapsulam um pequeno pedaço de código escrito em uma
linguagem de programação. Atualmente, o Zope fornece Scripts baseados em Python, que são escritos
na linguagem Python, e Scripts baseados em Perl que são escritos na linguagem Perl. Objetos script são
novidades do Zope 2.3, e são o meio preferido para escrever lógica de programação (aplicação) no Zope.

Até agora, neste livro você usou muito os DTML Methods e Documents para criar simples aplicações
para web no Zope. DTML permite você executar operações simples do script bem como a manipulação
da string. A maioria das vezes, entretando, os DTML Methods deveriam ser usados para apresentações.
DTML Methods são explicados nos Capítulos 4, "Conteúdo Dinâmico com DTML" e Capítulo 8

162 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

"Variáveis e DTML Avançado".

Aqui está um visão geral dos scripts do Zope:

Scripts baseados em Python

Você pode usar o Python, uma linguagem script de objetivo geral, para controlar objetos do Zope
e executar outras tarefas. Estes scripts oferecem a você facilidades de programação para
qualquer propósito dentro do Zope.

Scripts baseados em Perl

Você pode usar o Perl, uma poderosa linguagem de processamento de textos, para escrever os
objetos do Zope e acessar as bibliotecas do Perl. Estes scripts oferecem benefícios parecidos com
aqueles Scripts baseados em Python, pórem, podem ser mais interessante para pessoas que
conhecem Perl mas não Python, ou para quem quer usar as bibliotecas do Perl para que não haja
equivalente no Python.

Você pode adicionar estes scripts em sua aplicação Zope como qualquer outro objeto

Chamando os Scripts
Os scripts Zope são chamados pela web ou por outros scripts ou objetos. Quase todos os tipos de scripts
podem ser chamados por outro tipo de objeto; você pode chamar um Script baseado em Python de um
DTML Method, ou um método embutido de um Script baseado em Perl. De fato, scripts podem chamar
scripts que chamam outros scripts, e assim por diante. Como foi visto no Capítulo 4, "Conteúdo
Dinâmico dom DTML", você pode substituir um script por um script implementado em outra
linguagem. Por exemplo, se você está usando Perl para executar uma tarefa, porém mais tarde decide
que seria melhor fazê-la em Python, você pode habitualmente substituir o script por um Script baseado
em Python com o mesmo id.

Quando você chama um script, o modo que você o chama dá ao script um contexto para executar. O
contexto de um script é importante. Por exemplo, quando você chama um script você normalmente
quer selecionar algum objeto que é o centro para a tarefa do script. Você chamaria o script no contexto
do objeto no qual você quer que carregue sua tarefa. É mais simples dizer que você está chamando o
script no objeto.

Chamando Scripts Através da Web

Você pode chamar um script diretamente da web vistando suas URLs. Você pode chamar um único
script em diferentes objetos usando diferentes URLs. Isto funciona porque usando diferentes URLs
você oferece a seus scripts diferentes contextos, e scripts podem operar de forma diferenciada
dependendo do seu contexto. Esta é uma poderosa característica que habilita você a aplicar lógica a
objetos como documentos ou pastas sem ter que embutir o código atual dentro do objeto.

Para chamar um script em um objeto da web, simplismente visite a URL do objeto, seguido pelo nome
do script. Isto coloca o script no contexto do seu objeto. Por exemplo, suponha que você tem uma
coleção de objetos e scripts como mostra na figura 8.1.

163 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 8.1 - Uma coleção de objetos e scripts

Para chamar o script feed no objeto hippo você visitaria a URL Zoo/LargeAnimals/hippo/feed. Para
chamar o script feed no objeto kangarooMouse você pode visitar a URL Zoo/SmallAnimals
/kangarooMouse/feed. Estas URLs colocam o script feed no contexto dos objetos hippo e
kangarroMouse, respectivamente.

O Zope usa uma URL como um mapa para achar qual objeto e qual script você quer chamar.

O Zope divide a URL em partes e as compara com a hierarquia do objeto, trabalhando em segundo plano
até que encontre um par para cada parte. Este processo é chamado de URL traversal. Por exemplo,
quando você dá ao Zope a URL Zoo/LargeAnimals/hippo/feed, ele inicia pela pasta raiz e procura por
um objeto chamado Zoo. Ele então vai para a pasta Zoo e procura por um objeto chamado
LargeAnimals. Então move-se para a pasta LargeAnimals e procura por um objeto chamado hippo. Ele
vai para o objeto hippo e procura por um objeto chamado feed. O script feed não pode ser encontrado no
objeto hippo e está localizado na pasta Zoo por um processo chamado aquisição.

Aquisição faz duas coisas. Primeiro ele tenta achar o objeto no repositório do objeto corrente. Se isto
não funcionar ele volta para o path da URL e tenta de novo. Neste exemplo o Zope primeiro procura
pelo objeto feed no hippo, então ele vai para o primeiro respositório, LargeAnimals, e então para o
próximo respositório, Zoo, onde fedd é finalmente encontrado.

Agora o Zope chegou no final da URL. Ele chama o ultimo objeto encontrado feed. O script feed opera
em seu contexto que é o antepenúltimo objeto encontrado, o objeto hippo. Isto é como o script feed é
chamado no objeto hippo.

Do mesmo modo você pode chamar o método wash no hippo com a URL Zoo/LargeAnimals/hippo
/wash. Neste caso o Zope adquire o método wash pela pasta LargeAnimals.

Arranjos mais complexos são possíveis. Suponha que você quer chamar o script vaccinate no objeto
hippo. Qual URL você pode usar? Se você visitar a URL Zoo/LargeAnimals/hippo/vaccinate o Zope

164 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

não será capaz de achar o script vaccinate, já que ele não está em nenhum dos repositórios do objeto
hippo.

A solução é dar o caminho para o script como parte de uma URL. Desta forma, quando o Zope usa
aquisição para achar o script ele irá achar o script certo enquanto ele percorre a URL de volta. A URL
para vacinar o hipopótamo é Zoo/Vet/LargeAnimals/hippo/vaccinate. Da mesma forma, se você quer
chamar o script vaccinate no objeto kargarooMouse você deveria usar a URL Zoo/Vet/SmallAnimals
/kargarooMouse/vaccinate.

Vamos seguir adiante e ver como o Zope anda pela URL Zoo/Vet/LargeAnimals/hippo/vaccinate. O
Zope inicia na pasta raiz e procura por um objeto chamado Zoo. Ele move-se para o pasta Zoo e procura
por um objeto chamado Vet. Move-se para a pasta Vet e procura por um objeto chamado LargeAnimals.
A pasta Vet não contém um objeto com este nome, mas ele pode adquirir a pasta LargeAnimals por seu
repositório, pasta Zoo. Então ele move-se para a pasta LargeAnimals e procura por um objeto chamado
hippo. Ele move-se então para o objeto hippo e procura por um objeto chamado vaccinate. Já que o
objeto hippo não contém um objeto vaccinate e nenhum de seus repositórios, o Zope percorre devolta
pela path da URL tentando achar um objeto vaccinate. Primeiro ele volta para a pasta LargeAnimals
acima aonde vacciante ainda não pode ser encontrada. Então ele volta para a pasta Vet acima. Aqui ele
acha um script vaccinate na pasta Vet. Já que o Zope agora chegou ao final da URL, ele chama o script
vaccinate no contexto do objeto hippo.

Quando o Zope procura por um sub-objeto enquanto percorre a URL, ele primeramente olha para o
sub-objeto no objeto corrente. Se ele não consegue achar no objeto atual, ele procura no próximo
container de objetos. Se ele não consegue encontrá-lo, ele volta pelo path da URL e procura denovo. Ele
continua este processo até ele encontrar o objeto ou criar um erro se ele não encontrar.

Este é um mecanismo muito útil, e ele permite você ser completamente significativo quando você
compõe URLs. O path que você diz para o Zope seguir neste caminho para um objeto determinará como
ele usa aquisições para procurar scripts do objeto.

Chamando Scripts Através de Outros Objetos

Você pode chamar scripts através de outros objetos. Por exemplo, é comum chamar scripts através de
DTML Methods.

Como você viu no Capítulo 8, "Variáveis e DTML Avançada", você pode chamar scripts Zope apartir de
DTML com a tag call. Por exemplo:

&ltdtml-call updateInfo>

O DTML chamará o script updateInfo. Você não tem que especificar se o script é implementado em Perl,
Python, ou qualquer outra linguagem (você pode também chamar outros objetos DTML e SQL Methods
desta maneira).

Se o script updateInfo requer parâmetros, você deve escolher tanto um nome para o namespace ligado
da DTML (veja Variáveis Binding abaixo) então o parâmetro será verificado no namespace, ou você deve
passar os parâmetros em uma expressão, como esta:

&ltdtml-call expr=”updateInfo(color=’brow’, pattern=’spotted’)”>

Chamar scripts através do Python e Perl funciona do mesmo jeito, exceto pelo fato de você sempre ter
que passar os parâmetros do script quando você chama um script do Python ou Perl. Por exemplo aqui
temos como você poderia chamar o script updateInfo pelo Python:

165 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

context.updateInfo(color=brown,
pattern=spotted)

Pelo Perl você poderia fazer a mesma coisa usando as semânticas padrões do Perl para chamar os
scripts:

$self->updateInfo(color => brown,


pattern => spotted);

Cada linguagem script possui um jeito diferente de escrever uma chamada com script, mas você não
precisa saber qual linguagem é usada no script que você está chamando. Efetivamente os objetos do
Zope podem ter scripts implementados em várias linguagens diferentes. Mas quando você chama um
script você não precisa saber como ele está implementado, você apenas precisa passar os parâmetros
apropriados.

O Zope localiza os scripts que você chama usando aquisição do mesmo jeito que ele faz quando chama
scripts da web. Retornando ao nosso exemplo de alimentação do hipopótamo da ultima secção, vamos
ver como vacinar um hipopótamo pelo Python e Perl. A Figura 8.2 mostra uma hierarquia do objeto
levemente atualizada que contém dois scripts, vaccinateHippo.py e vaccinateHippo.pl.

Figura 8.2 – Uma coleção de objetos e scripts

Suponha que vaccinate.Hippo.py é um script Python. Aqui está como você chama o script vaccinate no
objeto hippo pelo Python:

context.Vet.LargeAnimals.hippo.vaccinate()

Em outras palavras você simplesmente acessa o objeto usando o mesmo path de aquisição como você
usaria se fosse chamá-lo pela web. Em Perl, você pode dizer da mesma forma:

166 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

$self->Vet->LargeAnimals->hippo->vaccinate();

Usar scripts por outros scripts é muito parecido a chamar scripts pela web. As semânticas diferem um
pouco, mas a mesma regra de aquisição é aplicada. Mais tarde neste capítulo, você verá mais exemplos
de como scripts trabalham tanto em Perl como em Python.

Passando Parâmetros para Scripts

Todos os scripts podem ser passados por parâmetro. Um parâmetro dá à um script mais informações
sobre o que fazer. Quando você chama um script da web, o Zope tentará achar os parâmetros do script
no request da web e passá-lo para o seu script. Por exemplo, se você tem um script com parâmetros
dolphin e REQUEST, o Zope procurará por dolphin no request da web e passará o request como
parâmetro REQUEST. Em termos práticos, isto significa que é fácil fazer processamento de formulário
em seu script. Por exemplo aqui está um formulário:

<form action="actionScript">
Name <input type="text" name="name"><br>
Age <input type="text" name="age:int"><br>
<input type="submit">
</form>

Você pode facilmente processar este formulário com um script chamado actionScript que inclui name e
age na sua lista de parâmetros:

## Script (Python) "actionScript"


##parameters=name, age
##
"Process form"
context.processName(name)
context.processAge(age)
return context.responseMessage()

Não há necessidade de processar o formulário manualmente para extrair valores dele. Elementos do
formulário são passados como strings, ou listas de strings no caso de check boxes, e entradas com
seleção múltipla.

Além disso para formar variáveis, você pode especificar qualquer variável requerida como parâmetros
do script. Por exemplo, para conseguir acesso aos objetos request e response, basta incluir REQUEST e
RESPONSE na sua lista de parâmetros. Variáveis request são detalhadas no Apêndice B.

Uma coisa para observar é que a variável context refere-se ao objeto no qual seu script está sendo
chamado. Isto funciona similarmente em Scripts baseados em Perl, por exemplo:

my $self = shift;
$self->processName($name);
$self->processAge($age);
return $context->responseMessage();

Na versão Python deste exemplo, há um problema sutil. Você está provavelmente esperando um valor
inteiro ao invés de um string para a age. Você poderia converter manualmente a string para inteiro
usando o embutido int do Python:

age=int(age) # covert a string to an integer

167 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Mas esta conversão manual pode ser inconveniente. O Zope fornece um modo para você especificar
tipos de entradas do formulário no formulário, preferencialmente no script de processamento. Ao invés
de converter a variável age para um inteiro no script de processamento, você pode indicar que ele é um
inteiro no formulário:

Age <input type="text" name="age:int">

O :int apontado para o nome da entrada do formulário diz ao Zope para converter automaticamente a
entrada do formulário para um inteiro. Se o usuário de seu formulário digitar algo que não pode ser
convertido para um inteiro (como "22 going on 23"), então o Zope irá criar um exceção como mostra a
Figura 8.3.

Figura 8.3 - Erro de converção de parâmetro

É útil para o Zope ter algo para capturar erros de conversão, mas você pode não gostar das mensagens
de erro do Zope. Você deverá evitar usar os conversores do Zope se você quer fornecer suas próprias
mensagens de erro.

O Zope pode executar muitas conversões de parâmetros. Aqui está uma lista dos conversores básicos de
parâmetros do Zope.

boolean

Converte uma variável para true ou false. Variáveis que são 0, None, uma string vazia, ou uma
sequência vazia são falsas(false), todas as outras são verdadeiras(true).

int

Converte uma variável para um inteiro(integer).

long

Converte uma variável para um inteiro longo(long integer).

float

Converte uma variável para um ponto de número flutuante (floating point number).

string

Converte uma variável para uma string. A maioria das variáveis são strings por isso este

168 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

conversos é raramente usado.

text

Converte uma variável para uma string com quebra de linhas normalizadas. Diferentes browsers
em várias plataformas codificam finais de linhas de forma diferente, então este script garante
que o final da linha está consistente, não importando como eles foram codificados pelo browser.

list

Converte uma variável para um lista do Python.

tuple

Converte uma variável para uma tupla do Python. Uma tupla é como uma lista, mas não pode ser
modificada.

tokens

Converte uma string para um lista quebrando-a em espaços brancos.

lines

Converte uma string para uma lista quebrando-a em novas linhas.

date

Converte uma string para um objeto DateTime. Os formatos aceitos são bastante flexíveis. Por
exemplo 10/16/2000, 12:01:13 pm.

required

Cria uma exceção se a variável não está presente.

ignore_empty

Exclui a variável do request se a variável é uma stringa vazia.

Esses conversores funcionam mais ou menos do mesmo jeito para forçar uma variável string do
formulário transformar-se em um tipo específico. Você talvez reconheça estas converções vistas no
Capítulo 3, "Usando Objetos Básicos do Zope", aonde são discutidas estas propriedades. Estas
conversões são usadas por facilidades de propriedades do Zope para converter propriedade no tipe
certo.

Os conversores list e tuple podem ser usados em juntamente com outros conversores. Isto permite você
aplicar conversores adicioanais para cada elemento da lista ou tupla. Considere este formulário:

169 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<form action="processTimes">

<p>I would prefer not to be disturbed at the following


times:</p>

<input type="checkbox" name="disturb_times:list:date"


value="12:00 AM"> Midnight<br>

<input type="checkbox" name="disturb_times:list:date"


value="01:00 AM"> 1:00 AM<br>

<input type="checkbox" name="disturb_times:list:date"


value="02:00 AM"> 2:00 AM<br>

<input type="checkbox" name="disturb_times:list:date"


value="03:00 AM"> 3:00 AM<br>

<input type="checkbox" name="disturb_times:list:date"


value="04:00 AM"> 4:00 AM<br>

<input type="submit">
</form>

Usando os conversores list e date juntos, o Zope irá converter cada hora selecionada a uma data e então
unir todas as datas selecioandas em uma lista chamada disturb_times.

Um tipo mis complexo de conversão de formulário é converter uma sequência de inputs nos registros.
Registros são estruturas que têm atributos. Usando registros você pode unir várias entradas do
formulário em uma variável com atributos. Os conversores de registro disponíveis são:

record

Converte uma variável para um atributo de registro.

170 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

records

Converte uma variável em um atributo de registro em uma lista de registros.

default

Fornece um valor default para um atributo de registro se a variável está vazia.

ignore_empty

Pula um atributo de registro se a variável está vazia.

Aqui estão alguns exemplos de como estes conversores são usados:

<form action="processPerson">

First Name <input type="text" name="person.fname:record"><br>


Last Name <input type="text" name="person.lname:record"><br>
Age <input type="text" name="person.age:record:int"><br>

<input type="submit">
</form>

Este formulário chamará o script processPerson com um parâmetro, person. A variável person terá os
atributos fname, lname e age. Aqui está um exemplo de como você pode usar a variável person no seu
script processPerson:

## Script (Python) "processPerson"


##parameters=person
##
" process a person record "
full_name="%s %s" % (person.fname, person.lname)
if person.age < 21:
return "Sorry, %s. You are not old enough to adopt an aardvark." % full_name
return "Thanks, %s. Your aardvark is on its way." % full_name

O conversor records funciona como o conversor record, exceto pelo fato de que ele produz uma lista de
registros, melhor do que apenas um. Aqui está um exemplo deste form:

171 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<form action="processPeople">

<p>Please, enter information about one or more of your next of


kin.</p>

<p>First Name <input type="text" name="people.fname:records">


Last Name <input type="text" name="people.lname:records"></p>

<p>First Name <input type="text" name="people.fname:records">


Last Name <input type="text" name="people.lname:records"></p>

<p>First Name <input type="text" name="people.fname:records">


Last Name <input type="text" name="people.lname:records"></p>

<input type="submit">
</form>

Este form chamará o script processPeople com uma variável chamada people que é uma lista de
registros. Cada registro terá os atributos fname e lname.

Outro parâmetro de conversão útil usa variáveis do formulário para reescrever a ação do formulário.
Isto lhe permite dar um submit em um formulário para diferentes scripts dependendo de como o
formulário é preenchido. Isto é mais útil no caso de um formulário com vários botões submit. As ações
de conversão do Zope são:

action

Muda a ação do formulário. Isto é mais usado nos casos aonde você vários botões submit em um
form. Cada botão pode ser associado a um script que é chamdo quando o botão é clicado para
submenter o form.

default_action

Muda a ação do script do formulário quando nenhum outro method conversor é encontrado.

Aqui está um exemplo de formulário que usa conversores de ação:

172 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<form action="">

<p>Select one or more employees</p>

<input type="checkbox" name="employees:list" value="Larry"> Larry<br>


<input type="checkbox" name="employees:list" value="Simon"> Simon<br>
<input type="checkbox" name="employees:list" value="Rene"> Rene<br>

<input type="submit" name="fireEmployees:action"


value="Fire!"><br>

<input type="submit" name="promoteEmployees:action"


value="Promote!">

</form>

Este formulário chamará um dos scripts fireEmployees ou promoteEmployees dependendo de qual dos
dois botões submit é usado. Observe também como ele constrói uma lista de empregados como o
conversor list. Conversores de frmulário podem ser muito usados quando projeta-se aplicações para
Zope.

Scripts de Segurança
Todos os scripts que podem ser editados através da web estão sujeitos às políticas de segurança do
Zope. Os únicos scripts que não estão sujeitos à estas restrições de segurança são scripts que devem ser
editados através de sistemas de arquivos. Estes scripts não restritos incluem External Methods do
Python e Perl.

O Capítulo 7, "Usuários e Segurança", explica segurança mais detalhadamente. Você deveria consultar
as seções Papéis de Objetos Executáveis e Funções do Proxy para mais informações de quais scripts são
restritos pelas regras de segurança do Zope.

A API do Zope
Uma das principais razões para escrever um script no Zope é ter acesso conveniente a API do Zope
(Application Programmer Interface - Interface do Programador da Aplicação). A API do Zope descreve
ações embutidas que podem ser chamadas nos objetos do Zope. Você pode examinar a API do Zope na

173 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

ajuda do sistema, como mostra a Figura 8.4.

Figura 8.4 - Documentação da API do Zope.

Suponha que você gostaria de ter um script que pega um arquivo que você atualiza de um formulário e
cria um objeto File do Zope em uma pasta. Para fazer isto você precisa saber a quantidade de ações da
API do Zope. É bastante fácil para ler arquivos em Python ou Perl, mas uma vez que você tenha o
arquivo que você precisa saber que ações chamar para criar um novo objeto File em uma Pasta.

Existem muitas outras coisas que você gostaria de fazer em um script usando a API do Zope. Isto inclui
criação, modificação e remoção de objetos do Zope. Você pode ainda executar tarefas de manutenção,
como reiniciar o Zope e dar um pack no banco de dados do Zope.

A API do Zope é documentado no Apêndice B, "Referência a API" bem como na ajuda on-line do Zope. A
documentação da API mostra à você quais classes herdam de que outras classes. Por exemplo Folder
herda de ObjectManager. Isto significa que o objeto Folder tem todas as ações listadas na seção
ObjectManager da referência da API.

Usando Scripts Baseados em Python


No começo deste capítulo você viu alguns exemplos de scripts. Agora vamos dar uma olhada nestes
scripts mais detalhadamente.

A Linguagem Python

O Python é linguagem script de alto nível, orientada a objeto. A maior parte do Zope é escrito em
Python. Muitas pessoas gostam do Python porque ele é claro, simples e possibilita habilita fazer grandes
projetos.

Existem muitos recursos disponíveis para aprender Python. O site python.org tem muita documentação
sobre Python incluindo um tutorial feito pelo seu criador do Python, Guido van Rossum.

Python vem com um rico conjunto de módulos e pacotes. Você pode achar mais sobre a biblioteca
padrão do Python no web site python.org.

Outra fonte muito respeitada para material de referência é Referência Essencial do Python de David
Beazley publicado pela New Riders.

Criando Scripts Baseados em Python

174 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Para criar um Script baseado em Python escolha Script (Python) na Lista de adição de produtos. Chame
o script de hello, e click no botão Add and Edit. Você deveria ver agora a aba Edit do seu script como
mostra a Figura 8.5.

Figura 8.5 - Aba de Edição do script.

Este tela lhe permite controlar os parâmetros e o corpo do seu script. Você pode digitar os parâmetros
do seu script no campo parameter list. Digite o corpo do seu script na área de texto na parte inferior de
tela.

Entre com name="World" no campo parameter list e digite:

return "Hello %s." % name

no corpo do seu script. Isto equivale a isto na sintaxe Python padrão:

def hello(name="World"):
return "Hello %s." % name

Você pode agora testar este script indo na aba Test como mostra a Figura 8.6.

Figura 8.6 - Testando um Script.

Deixe o campo name em branco e click no botão Run Script. O Zope deveria retorar "Hello World."
Agora volte e tente entrar com o seu nome no campo Value e clique no botão Run Script. O Zope deveria
dizer oi pra você.

175 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Quando os script são chamados nos objetos do Zope, você pode obter acesso aos objetos do Zope pela
variável context. Por exemplo, este script retorna a quantidade de objetos pertencentes em um dado
objeto do Zope:

## Script (Python) "numberOfObjects


##
return len(context.objectIds())

O script chama contex.objectIds() para achar a quantidade de objetos pertencentes. Quando você
chama este script em um determinado objeto do Zope, a variável context é ligada ao objeto context.
Então se você chamou este script visitando a URL FolderA/FolderB/numberOfObjects o parâmetro
context refere-se ao objeto FolderB.

Quando estiver escrevendo sua lógica em Python você tipicamente quer pesquisar objetos do Zope,
chamar outros scripts e retornar relatórios. Por exemplo, suponha que você queria implementar um
simples sistema de workflow no qual vários objetos do Zope são unidos com propriedades que indicam
seus status. Você poderia querer produzir relatórios que resumem que objetos estão em que status.
Você pode usar Python pra buscar objetos e testar suas propriedades. Por exemplo, aqui está um script
chamado objectsForStatus com um parâmetro, status:

## Script (Python) "objectsForStatus"


##parameters=status
##
"""
Returns all sub-objects that have a given status
property.
"""
results=[]
for object in context.objectValues():
if object.getProperty(status) == status:
results.append(object)
return results

Este script faz um loop através de um sub-obejto do objeto e retorna todos os sub-objetos que têm uma
propriedade status com um determinado valor.

Você poderia então usar este script da DTML para enviar relatórios por e-mail. Por exemplo:

<dtml-sendmail>
To: <dtml-var ResponsiblePerson>
Subject: Pending Objects

These objects are pending and need attention.

<dtml-in expr="objectsForStatus(Pending)">
<dtml-var title_or_id> (<dtml-var absolute_url>)
</dtml-in>
</dtml-sendmail>

Este exemplo mostra como você pode usar DTML para apresentação ou formatação relatórios,
enquanto o Python cuida da lógica. Isto é um modelo muito importante, que você verá muito no Zope.

176 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Processando Strings

Um uso comum para scripts é fazer processamento de strings. O Python tem vários módulos padrões
para processamento de strings. Você não pode fazer processamento de expressões regulares através de
Scripts baseados em Python, mas você tem acesso ao módulo string. Você tem acesso ao módulo string
também pela DTML, mas é muito mais fácil de usá-lo através do Python. Suponha que você quer mudar
todas as ocorrências de uma determinada palavra em um documento DTML. Aqui está um script,
replaceWord, que aceita dois argumentos, word e replacement. Isto mudará todas as ocorrências de
uma determinada palavra em um DTML Document:

## Script (Python) "replaceWord"


##parameters=word, replacement
##
"""
Replaces all the occurrences of a word with a
replacement word in the source text of a DTML
Document. Call this script on a DTML Document to use
it.

Note: you'll need permission to edit a document to


call this script on the document.
"""
import string
text=context.document_src()
text=string.replace(text, word, replacement)
context.manage_edit(text, context.title)

Você pode chamar este script através da web em um DTML Document para mudar a fonte do
documento. Por exemplo, a URL Swamp/replaceWord?word=Alligator&replacement=Crocodile
chamaria o script replaceWord em um documento chamado Swamp e trocaria todas as ocorrências da
palavra Alligator por Crocodile.

O módulo string que você pode acessar pelos scripts não tem todas as características disponíveis no
módulo string padrão do Python. Estas limitações são impostas por razões de segurança. Veja o
Apêndice A para maiores informações sobre o módulo string.

Uma coisa que você talvez quisesse fazer com scripts é usar Python para procurar objetos que contêm
determinada palavra no seu texto ou como uma propriedade. Você pode fazer isto, mas o Zope tem
facilidades melhores para este tipo de trabalho, o Catalog. Veja o Capítulo 11 "Procurando e
Categorizando Conteúdo" para maiores informações sobre procurar com Catálogos.

Fazendo Matemática

Outro uso comum de scripts é executar cálculos matemáticos que seriam incômodos se feitos com
DTML. Os módulos math e random dão à você acesso através do Python a muitas funções. Estes
módulos são serviços padrões do Python como está descrito no web site Python.org.

math
Funções matemáticas como sin e cos.
random
Função de geração de números pseudo randômicos.

Uma função interessante do módulo random é a função choice que retorna uma seleção randômica de
uma seqüência de objetos. Aqui está um exemplo de como usar esta função em um script chamado

177 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

randomImage:

## Script (Python) "randomImage"


##
"""
When called on a Folder that contains Image objects this
script returns a random image.
"""
import random
return random.choice(context.objectValues(Image))

Suponha que você tem uma Pasta chamada Images que continha várias imagens. Você poderia exibir
uma imagem aleatória da pasta em DTML assim:

<dtml-with Images>
<dtml-var randomImage>
</dtml-with>

Este DTML chama o script randomImage na pasta Images. O resultado é uma tag HTML IMG que
referencia a imagem aleatória na Pasta Images.

Ligando Variáveis

Um conjunto de variáveis é criado toda vez que um Script baseado em Python é chamado. Estas
variáveis, definidas na aba Bindings, são usadas por seu script para acessar outros objetos e scripts do
Zope.

Por default, os nomes destas variáveis de ligação são setadas para valores lógicos e você não precisaria
mudá-los. Elas são explicadas aqui, assim você saberá como cada variável especial funciona, e como você
pode usar estas variáveis em seus scripts.

Context

A ligação Context usa o nome padrão context. Esta variável refere-se ao objeto em que o script é
chamado.

Container

A ligação Container usa o nome padrão container. Esta variável refere-se à pasta em que o script
está definido.

Script

A ligação Script usa o nome padrão script. Esta variável refere-se ao próprio objeto script.

Namespace

A ligação Namespace é deixada em branco por default. Esta é uma variável avançada que você
não precisará nos exemplos deste livro. Se o seu script é chamado de um DTMl Method e você
tem que escolher um nome para esta ligação, então a variável nomeada contém o namespace da
DTML explicado no Capítulo 8, "Variáveis e DTML Avançada". Além disso, se esta ligação for
setada, o script procurará por estes parâmetros no namespace da DTML quando chamado da
DTML sem passar explicitamente qualquer argumento.

Subpath

178 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

A ligação Subpath usa o nome padrão traverse_subpath. Esta é uma variável avançada que você
não precisará usar nos exemplos deste livro. Se o seu script está cruzado, siginifica que outro
path de elementos seguiu-o em uma URL, então este path de elementos está alocado em uma
lista, da esquerda pra direita, nesta variável.

Se você edita seus scripts via FTP, você será avisado que estas ligações estão listado em comentários no
topo do seu arquivo de scripts. Por exemplo:

## Script (Python) "example"


##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=name, age
##title=
##
return "Hello %s you are %d years old." % (name, age)

Você pode mudar as ligações do seu script mudando estes comentários e então atualizando o seu script.

Mostrando Expressão de Apoio

Scripts baseados em Python têm um instrumento que ajuda você imprimir informação. Geralmente
dados impressos são enviados para a saída padrão e é exibida no console. Isto não é prático para um
servidor de aplicações como o Zope, já que na maioria das vezes você não tem acesso ao console do
servidor. Scripts permitem à você usar print de qualquer jeito e retornar o que você imprimiu com a
variável especial printed. Por exemplo:

## Script (Python) "printExample"


##
for word in (Zope, on, a, rope):
print word
return printed

Este script retornará:

Zope
on
a
rope

A razão de ter uma quebra de linha entre cada palavra é que o Python adiciona uma nova linha depois de
cada string que é impressa.

Você talvez queira usar a expressão print para executar simples verificações de erros em seus scripts.
Para um controle mais complexo das saídas você provavelmente você mesmo deveria gerenciar isto
acumulando dados, modificando-os e retornando-os manualmente e de preferência contando com a
expressão print.

Restrições de Segurança

Scripts são restritos para limitar a capacidade de causar danos. O que pode causar dano? Em geral,
scripts mantêm você acessando objetos privados do Zope, fazendo mudanças que possam causar danos
aos objetos do Zope, matando o processo do Zope, e acessando o servidor Zope. Estas restrições são
implementadas por coleções de limites do que seus scripts podem fazer.

179 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Limites do Laço

Scripts não podem criar laços infinitos. Se seu script faz um loop muitas vezes, o Zope vai
expressar um erro. Esta restrição mostra todos os tipos de loops incluindo laços for e while. A
razão desta restrição é para limitar sua capacidade de pendurar o Zope criando um loop na
interface.

Limites de carregamento

Scripts não podem importar arbitrariamento pacotes e módulos. Você está limitado a importar
os módulos de que são usados PythonScripts.standard, o módulo AccessControl, aqueles
módulos disponíveis via DTML (string, random, math, sequence), e módulos que foram feitos
especificamente para estarem disponíveis para os scripts pelos autores de produtos. Veja o
Apêndice B, "Referência a API" para maior informação sobre este módulos. Se você quer ser
capaz de importar qualquer módulo Python, use um External Method, como será descrito no
capítulo.

Limites de Acesso

Você está restrito plas políticas de segurança do Zope quando acessa objetos. Em outras
palavras o usuário que está executando o script está sendo checado para ver se tem autorização
quando estiver acessando os objetos. Como todos objetos executáveis cvocê pode modificar as
funções efetivas que um usuário tem quando chamar um script usando Proxy Roles (veja o
Capítulo 7, "Usuários e Segurança", para mais informação). Além disso, você não pode acessar
objetos cujos nomes começam com underscore (sublinha), já que o Zope considera esses objetos
privados.

Escrevendo limites

Em geral você não pode mudar os atributos do objeto do Zope usando scripts. Você deveria
chamar os scripts nos objetos do Zope para mudá-los, epecialmente mudando os atributos da
instância.

A respeito desses limites, um determinado usuário poderia usar grandes quantidades de tempo de CPU
e memória usando Scripts baseados em Python. Assim, scripts mal intencionados poderiam constituir
um tipo de negação do ataque ao serviço usando vários recursos. Estes são problemas difíceis de
resolver e a DTML sofre da mesma possibilidade por mau uso. Como na DTML, você provavelmente não
poderia permitir que pessoas não confiáveis acessem os scripts.

Funções Embutidas

Scripts baseados em Python oferecem a você uma lista um pouco diferente de comandos embutidos que
você pode achar no Python. A maioria das mudanças foram projetadas para manter você seguro das
ações não seguras de execução. Por exemplo, a função open não está disponível, ela faz com que você
seja capaz de acessar o sistema de arquivos. Para parcialmente criar alguns comandos embutidos
algumas funções extras estão disponíveis.

Estes built-in restritos funcionam da mesma forma que os built-ins padrões do Python: None, abs,
apply, callable, chr, cmp, complex, delattr, divmod, filter, float, getattr, hash, hex, int, isinstance,
issubclass, list, len, long, map, max, min, oct, ord, repr, round, setattr, str, tuple. para mais informação
sobre qual desses built-ins usar, veja a Documentação do Python online.

As funções range e pow estão disponíveis funcionam da mesma forma que no Python padrão;

180 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

entretanto, elas são limitadas para fazendo com que não gerem números muito grandes e sequências.
Esta limitação ajuda a proteger contra ataques no sistema como descrito anteriormente.

Além dessas, estas funções de utilidade da DTML estão disponíveis: DateTime, e test. Veja o Apêndice
A, "Referência ao DTML" para mais inormação sobre essas funções.

Enfim, para compensar a falta de uma função type, há uma função same_type que compara o tipo de
dois ou mais objetos, retornando verdadeiro se eles são do mesmo tipo. Assim, ao invés de dizer:

if type(foo) == type([]):
return "foo is a list"

para checar se foo é uma lista, você deveria ao invés usar a função same_type para checar isto:

if same_type(foo, []):
return "foo is a list"

Agora vamos dar uma olhada nos External Methods que oferecem mais autoridade e menas restrições
que Scripts baseados em Python.

Usando Métodos Externos


Algumas vezes os obstáculos de segurança impostos pelos scripts get in your way. Por exemplo, você
deveria ler arquivos do disco, ou acessar a rede, ou usar alguma biblioteca avançada para coisas como
expressões regulares ou processamento de imagens. Nestes casos você usará External Methods.

Para criar e editar External Methods você precisa acessa o sistema de arquivos. Isto faz com que a
edição destes scripts seja mais enfadonho já que você não pode editá-los em seu browser. Entretanto
exigir acesso ao sistema de arquivos do servidor oferece um importante controle de segurança. Se um
usuário tem acesso a um sistema de arquivos do servidor eles podem causar danos ao Zope. Assim
exigindo que scripts não restritos sejam editados no sistema de arquivo do Zope assegura que somente
a pessoa que é confiável já tem acesso.

Scripts não restritos são criados e editados em arquivos no servidor Zope no diretório Extensions. Este
diretório está localizado no nível mais alto do diretório do Zope. Alternadamente você pode criar e
editar scripts não restritos em um diretório Extensions dentro de um diretório product instalado no
Zope.

Crie um arquivo chamado Example.py no diretório Extensions do Zope em seu servido. No exemplo do
arquivo Example.py, entre com o seguinte código:

def hello(name="World"):
return "Hello %s." % name

Você criou uma função Python em um módulo Python. Agora vamos usar esta função no External
Method.

Você gerencia o External Methods da mesma forma que gerencia scripts restritos exceto pelo fato que
você não pode editar scripts através da web. Ao invés de eitar código você deve dizer ao Zope onde
encontrar seu código no sistema de arquivo. Você faz isso especificando o nome de seu arquivo Python e
o nome da sua função dentro do módulo.

Para criar um External Method escolha External Method da lista de adição de produtos. Você será

181 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

levado a um formulário de adição onde você deve fornecer um id. Digite "hello" no campo Id e "hello" no
campo Function name e "Example" no campo Module name e clique no botão Add. Você deveira ver um
novo objeto External Method em sua pasta. Clique nele. Você deveria ser levado a aba Properties de seu
novo External Method como mostra a Figura 8.7.

Figura 8.7 Aba Properties do External Method.

Agora teste seu novo script indo na aba Test. Você deveria ver uma saudação. Você pode passa
diferentes nomes ao script especificando-os na URL. Por exemplo, hello?name=Spanish+Inquisition.

Este exemplo é exatamente o mesmo do exemplo hello world que você viu para usar scripts. De fato
para tarefas simples de processamento de string como estes scripts restritos oferecem uma melhor
solução já que eles são mais fáceis de se trabalhar.

As principais razões para usar um script irrestrito são acessar o sistema de arquivo ou rede ou usar
pacotes do Python que não estão disponíveis para scripts restritos.

Aqui temos um exemplo de External Method que usa a Biblioteca Imaging do Python (PIL) para criar
uma versão minimizada da Foto de um objeto Imagem existente em um Folder. Entre com o seguinte
código em um arquivo chamado Thumbnail.py no diretório Extensions:

182 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

def makeThumbnail(self, original_id, size=200):


"""
Makes a thumbnail image given an image Id when called on a Zope
folder.

The thumbnail is a Zope image object that is a small JPG


representation of the original image. The thumbnail has a
original_id property set to the id of the full size image
object.
"""

from PIL import Image


from StringIO import StringIO
import os.path

# create a thumbnail image file


original_image=getattr(self, original_id)
original_file=StringIO(str(original_image.data))
image=Image.open(original_file)
image=image.convert(RGB)
image.thumbnail((size,size))
thumbnail_file=StringIO()
image.save(thumbnail_file, "JPEG")
thumbnail_file.seek(0)

# create an id for the thumbnail


path, ext=os.path.splitext(original_id)
thumbnail_id=path + .thumb.jpg

# if there's and old thumbnail, delete it


if thumbnail_id in self.objectIds():
self.manage_delObjects([thumbnail_id])

# create the Zope image object


self.manage_addProduct['OFSP'].manage_addImage(thumbnail_id,
thumbnail_file,
thumbnail image)
thumbnail_image=getattr(self, thumbnail_id)

# set the originial_id property


thumbnail_image.manage_addProperty(original_id, original_id, string)

183 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Você deve ter o PIL instalado para este exemplo funcionar. Veja o site PythonWorks para mais
informação sobre o PIL. Para usar este código crie um External Method chamado makeThumbnail que
usa a função makeThumbnail no módulo Thumbnail.

Agora você tem um método que criará uma imagem reduzida. Você pode chamá-lo em um Folder com
uma URL como ImageFolder/makeThumbnail?original_id=Horse.gif. Isto criaria uma imagem
reduzida chamada Horse.thumb.jpg.

Você pode usar um script para fazer um loop por todas as imagens em um folder e criar imagens
reduzidas para elas. Crie um script chamado makeThumbnails:

## Script (Python) "makeThumbnails"


##
for image_id in context.objectIds(Image):
context.makeThumbnail(image_id)

Isto fará um loop em todas as imagens de um folder e criará uma imagem reduzida para cada uma.

Agora chame este script em um folder com umagens nele. Isto criará uma imagem reduzida para cada
imagem contida nele. Tente chamar o script makeThumbnails no folder novamente e você será avisado
que foi criada uma foto minimizada de suas fotos minimizadas. Isto não é bom. Você precisa mudar o
script makeThumbnails para identificar imagens minimizadas existentes e não fazer fotos minimizadas
delas. Já que todas as imagens minimizadas têm uma propriedade original_id você pode controlar por
esta propriedade como uma maneira de distribuição entre fotos minimizadas e imagens normais:

## Script (Python) "makeThumbnails"


##
for image in context.objectValues(Image):
if not image.hasProperty(original_id):
context.makeThumbnail(image.getId())

Delete todas as imagens minimizadas em seu folder e tente chamar seu script atualizado
makeThumbnails no oflder. Isto parece o que vai funcionar corretamente agora.

Agora com um pequeno DTML você pode juntar seu script e External Method. Crie um DTML Method
chamado displayThumbnails:

184 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<dtml-if updateThumbnails>
<dtml-call makeThumbnails>
</dtml-if>

<h2>Thumbnails</h2>

<table><tr valign="top">

<dtml-in expr="objectValues(Image)">
<dtml-if original_id>
<td>
<a href="&dtml-original_id;"><dtml-var sequence-item></a><br>
<dtml-var original_id>
</td>
</dtml-if>
</dtml-in>

</tr></table>

<form>
<input type="submit" name="updateThumbnails" value="Update Thumbnails">
</form>

<dtml-var standard_html_footer>

Quando você chama este DTML Method em um folder ele fará um loop em todas as imagens no folder e
mostrará todas as imagens minimizadas e linkará elas às imagens originais como mostra a Figura 8.8.

185 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 8.8 Mostrando imagens minimizadas

Este DTML Method também inclui um formulário que permite que você atualize as imagens
minimizadas. Se vocÊ adicionar, deletar ou mudar as imagens em seu folder você pode usar este
formulário para atualizar suas imagens minimizadas.

Este exemplo mostra como usar scripts, External Methods e DTML juntos. Python toma conta da lógica
enquanto o DTML controla a apresentação. Seus External Methods cuidam de pacotes externos
enquanto seus scripts fazem o processamento simples dos objetos do Zope.

Processando XML com Métodos Externos

Você pode usar External Methods para conectar algo ao Zope. Uma coisa interessante que você pode
fazer é comunicar usando XML. Você pode gerar e precessar XML com External Methods.

O Zope entende alguns tipos de mensagens XML tais como XML-RPC e WebDAV. Quando você cria
aplicações para web que se comunicam com outros sistemas você pode etar quererendo ter a abilidade
de receber mensagens XML. Você pode receber XML de várias maneiras: você pode ler arquivos XML
do sistema de arquivo ou pela rede, ou você pode definir scripts que tenham argumentos XML que
podem ser chamados por sistemas remotos.

Quando você recebe uma mensagem XML você deve processar o XML para procurar o que ele significa e
como agir sobre ela. Vamos dar uma rápida olhada em como você deveria analisar o XML manualmente
usando Python. Suponha que você quer conectar sua aplicação web a um servidor de chat do Jabber.
Você deveria querer permitir os usuários de mandar mensagens a você e receber respostas dinâmicas
baseadas no status de sua aplicação na web. Por exemplo, suponha que você quer permitir os usuários
de checar o estado dos animais usando mensagem instantânea. Sua aplicação deveria responder às
mensagens instantâneas do XML como esta:

<message to="cage_monitor@zopezoo.org" from="user@host.com">


<body>monkey food status</body>
</message>

Você deveria examinar o corpo da mensagem para procurar comandos, chame um script e retorne
respostas como esta:

<message to="user@host.com" from="cage_monitor@zopezoo.org">


<body>Monkeys were last fed at 3:15</body>
</message>

186 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Aqui está uma descrição de como você poderia implementar esta facilidade de mensagem do XML em
sua aplicação web usando um External Method:

187 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

# Uses Python 2.x standard xml processing packages. See


# http://www.python.org/doc/current/lib/module-xml.sax.html for
# information about Python's SAX (Simple API for XML) support If
# you are using Python 1.5.2 you can get the PyXML package. See
# http://pyxml.sourceforge.net for more information about PyXML.

from xml.sax import parseString


from xml.sax.handler import ContentHandler

class MessageHandler(ContentHandler):
"""
SAX message handler class

Extracts a message's to, from, and body


"""

inbody=0
body=""

def startElement(self, name, attrs):


if name=="message":
self.recipient=attrs['to']
self.sender=attrs['from']
elif name=="body":
self.inbody=1

def endElement(self, name):


if name=="body":
self.inbody=0

def characters(self, content):


if self.inbody:
self.body=self.body + content

def receiveMessage(self, message):


"""
Called by a Jabber server
"""

188 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

O External Method receiveMessage usa o pacote SAX do Python (Simple API for XML) para exeminar a
mensagem XML. A classe MessageHandler recebe retorno de chamadas quando o Python exemina a
mensagem. O controlador salva informação que ele está interessado. O External Method usa a classe
handler para criar uma instância dele, e passa-a para a função parseString. Ele então manda uma
mensagem de resposta chamando o getResponse com o corpo da mensagem. O script getResponse (que
não é mostrado aqui) aparentemente verifica o corpo atrás de comandos, pesquisa o estado das
aplicações para web e retorna alguma resposta. O método receiveMessage então cria uma mensagem
XML usando informações da resposta e do remetente e retorna-a.

O servidor remoto usaria este External Method chamando o método receiveMessage usando o comando
HTTP POST padrão. Voila, você implementou um servidor chat XML adaptado que roda sobre o HTTP.

Pegadinhas dos Métodos Externos

Apesar de você estar essencialmente irrestrito no que você pode fazer em um External Method, há
algumas coisas ainda que são difíceis de fazer.

Apesar de seu código Python estar satisfazendo, se você quiser trabalhar com o framework do Zope você
precisa respeitar suas regras. Apesar da programação com framework do Zope ser muito avançada para
ter um tópico para mostrar aqui, existem poucas coisas que deveria ser mencionadas.

Problemas podem ocorrer se você passar instâncias de suas próprias classes para o Zope e esperar que
elas trabalhem como os objetos do Zope. Por exemplo, você não pode definir uma classe em um arquivo
do script do External Method e determinar que seja como um atributo de um objeto do Zope. Isto
provoca problemas com o mecanismo de persistência do Zope. Você também não pode facilmente
passar as instâncias de sua própria classe sobre o DTMl ou scripts. O caso aqui é que suas instâncias não
teriam informação de segurança do Zope. Você pode definir e usar suas próprias classes e instâncias
para qual for sua necessidade, apenas não espere que o Zope use-as diretamente. Limite você mesmo
retornar simples estruturas do Python como strings, dicionários e listas ou objetos do Zope.

Usando Scripts Baseados em Perl


Scripts baseados em Perl permitem que você escreva scripts no Zope em Perl. Se você ama Perl e não
quer aprender Python para usar o Zope, estes scripts são para você. Usando scripts baseados em Perl
você pode usar todos os seus módulos preferidos em Perl e tratar o Zope como uma coleção de objetos
do Perl.

A Linguagem Perl

Perl é uma linguagem script de alto nível como Python. De uma ampla perspectiva, Perl e Python são
linguagens parecidas, elas têm construções de dados promitivoc parecidos e empregam construções
similares de programação.

Perl é uma linguagem popular para escrever scripts para Internet. Nos primórdios da utilização de
scripts CGI, Perl e CGI foram praticamente sinônimos. Perl continua ser a linguagem script dominante
na Internet.

Perl tem uma rica coleção de módulos para cuidar de quase todas as tarefas de computação. CPAN
(Comprehensive Perl Archive Network - Rede Compreenssiva de Arquivos Perl) é um guia confiável para
recursos do Perl.

Scripts do Zope baseados em Perl estão disponíveis para download no ActiveState. Scripts baseados em
Perl requerem que você tenha o Perl instalado, e outros pacotes, e como instalar estas coisas está além

189 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

do objetivo deste livro. Veja a documentação que vem com os scripts baseados em Perl da URL acima.
Também há mais informação oferecida por Andy McKay disponível no Zope.org.

Criando Scripts Baseados em Perl

Scripts baseados em Perl são bem parecidos a scripts baseados em Python. Ambos têm acesso a objetos
do Zope e são chamados de formas parecidas. Aqui está um programa hello world em Perl:

my $name=shift;
return "Hello $name.";

Vamos dar uma olhada em um exemplo de script mais complexo feito por Monty Taylor. Ele usa o
pacote LWP::UserAgent para devolver a URL da tira de Dilbert da rede. Crie um script baseado em Perl
chamado get_dilbert_url com este código:

use LWP::UserAgent;

my $ua = LWP::UserAgent->new;

# retrieve the Dilbert page


my $request = HTTP::Request->new(GET,http://www.dilbert.com);
my $response = $ua->request($request);

# look for the image URL in the HTML


my $content = $response->content;
$content =~ m,(/comics/dilbert/archive/images/[^"]*),s;

# return the URL


return $content

Você pode mostrar a tira do Dilbert chamando este script do DTML chamando o script dentro de uma
tag HTML IMG:

<img src="&dtml-get_dilbert_url;">

Entretanto há um problema com este código. Cada vez que você mostra o cartoon, o Zope tem que fazer
uma conexão de rede. Isto é ineficiente e dispendioso. Seria melhor para você somente buscar uma vez
por dia a URL do Dilbert.

Aqui está um script cached_dilbert_url que melhora a situação guardando o caminho de quando foi a

190 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

última chamada da URL do Dilbert com uma propriedade dilbert_url_date:

my $context=shift;
my $date=$context->getProperty(dilbert_url_date);

if ($date==null or $now-$date > 1){


my $url=$context->get_dilbert_url();
$context->manage_changeProperties(
dilbert_url => $url
dilbert_url_time => $now
);
}
return $context->getProperty(dilbert_url);

Este script usa duas propriedades, dilbert_url e dilbert_url_date. Se a URL está muito antiga, uma
nova é chamada. Você pode usar este script do DTML apenas como o script original:

<img src="&dtml-cached_dilbert_url;">

Você pode usar Perl e DTML juntos para controlar sua lógica e sua apresentação.

Segurança de Scripts Baseados em Perl

Como DTML e Scripts baseados em Python, scripts baseados em Perl compelem você no sistema de
segurança do Zope fazer qualquer coisa que você não está permitido a fazer. A segurança do script é
parecida em ambas as linguagens, mas existem alguns constrangimentos específicos do Perl.

Primeir, o sistema de segurança não permite você avaliar expressões em Perl. Por examplo, considere
este script:

my $context = shift;
my $input = shift;

eval $input

Este código pega um argumento e avalia-o em Perl. Isto significa que você chamaria este script do,
digamos um formulário HTML, e avaliaria os conteúdos de um dos elementos do formulário. Isto não é
permitido já que o elemento do formulário poderia conter código mal intencionado.

Scripts baseados em Perl também não podem determinar novas variáveis a qualquer objeto a não ser
variáveis locais que você declara com my.

DTML versus Python versus Perl


O Zope dá a você várias maneiras de escrever um script. Para pequenas tarefas usando script a escolha
de Python , Perl ou DTML provavelmente não faz grande diferença. Para maiores, tarefas orientadas
para lógica você deveria usar Python ou Perl. Você deveria escolher a linguagem que você se sente mais
confortáve. É claro, seu chefe pode querer interferir nisso.

191 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Apenas para uma comparação aqui está um simples script sugerido por Gisle Aas, o autor dos sccripts
baseados em Perl, nas três diferentes linguagens.

Em DTML:

<dtml-in objectValues>
<dtml-var getId>: <dtml-var sequence-item>
</dtml-in>
done

Em Python:

for item in context.objectValues():


print "%s: %s" % (item.getId(), item)
print "done"
return printed

Em Perl:

my $context = shift;
my @res;

for ($context->objectValues()) {
push(@res, join(": ", $_->getId(), $_));
}
join("\n", @res, "done");

Pelo fato do Zope ser implementado em Python, ele segue a filosofia do Perl que há mais de uma
maneira de fazer isto.

Scripts Remotos e Serviços de Rede


Servidores web são usados para servir conteúdo para o software dos clientes; geralmente pessoas
usando software do browser. O software cliente também pode ser outro computador que está usando
seu servidor web para acessar algum tipo de serviço.

Pelo fato do Zope expor objetos e scripts na web, ele pode ser usado para oferecer uma API para a web
poderosa, bem organizada e segura para outros clientes de aplicação remota da rede.

Há duas maneiras comuns de remotamente escrever scripts em Zope. A primeira maneira é usar um
simples protocolo com procedimento de chamada remota chamado XML-RPC. XML-RPC é usado para
executar um procedimento em uma máquina remota e obter um resultado na máquina local. XML-RPC
foi projetado para ser imparcial a linguagem, e neste capítulo você verá exemplos em Python, Perl e
Java.

A segunda maneira comum de escrever remotamente scripts em Zope é com qualquer cliente HTTP que
pode ser mecanizado com um script. Muitas bibliotecas de linguagens vêm com simples clientes HTTP
em script e há muitos programas que deixam você escrever o script do HTTP da linha de comando.

Usando XML - RPC

XML-RPC é um simples mecanismo com procedimento de chamada que funciona sobre o HTTP e usa

192 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

XML para codificar a informação. Clientes XML-RPC têm sido implementados por muitas linguagens
incluindo Python, Perl, Java, JavaScript, e TCL.

Maiores informações sobre XML-RPC podem ser encontradas no site XML-RPC.

Todos os scripts do Zope que podem ser chamados das URLs podem ser chamados pelo XML-RPC.
Basically XML-RPC oferece um sistema para preparar argumentos para scripts que podem ser
chamados da web. Como você viu anteriormente no capítulo, o Zope fornece seu próprio controle de
organização que você pode usar do HTTP. XML-RPC e a organização do Zope executam a mesma coisa.
A vantagem da organização do XML-RPC é que ele é um padrão razoável suportado que também
suporta organização de valores retornados bem como valores dos argumentos.

Aqui temos um exemplo fantástico que mostra a você como escrever scripts remotamente a mass firing
of janitors usando XML-RPC.

Aqui está o código em Python:

import xmlrpclib

server = xmlrpclib.Server(http://www.zopezoo.org/)
for employeeID in server.JanitorialDepartment.personnel():
server.fireEmployee(employee)

Em Perl:

use Frontier::Client;

$server = Frontier::Client->new(url => "http://www.zopezoo.org/");

$employees = $server->call("JanitorialDepartment.personnel");
foreach $employee ( @$employees ) {

$server->call("fireEmployee",$server->string($employee));
}

Em Java:

193 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

try {
XmlRpcClient server = new XmlRpcClient("http://www.zopezoo.org/");
Vector employees = (Vector) server.execute("JanitorialDepartment.personnel");

int num = employees.size();


for (int i = 0; i < num; i++) {
Vector args = new Vector(employees.subList(i, i+1));
server.execute("fireEmployee", args);
}

} catch (XmlRpcException ex) {


ex.printStackTrace();
} catch (IOException ioex) {
ex.printStackTrace();
}

Atualmente o exemplo acima provavelmente não vai rodar corretamente, já que você vai querer
principalmente proteger o script fireEmployee. Isto trás a tona o caso da segurança com XML-RPC.
XML-RPC não tem qualquer provisão de segurança própria, entretanto, já que ele roda sobre HTTP ele
pode alavancar controles de segurança HTTP existentes. De fato o Zope trata um request XML-RPC
exatamente como um request HTTP normal com consideração ao controle de segurança. Isto significa
que você deve oferecer autenticação em seu request XML-RPC para o Zope para garantir acesso a
scritps protegidos. O cliente Python até o momento que este livro estava sendo escrito não suportava
controle do cabeçalho de Autorização do HTTP. Entretanto isto é uma adição bastante trivial. Por
exemplo, um artigo no XML.com Internet Scripting: Zope and XML-RPC inclui um caminho para
suporte XML-RPC para Python mostrando como adicionar cabeçalhos de autorização do HTTP para seu
cliente XML-RPC.

Scripts Remotos com HTTP

Qualquer cliente HTTP pode ser usado para escrever scripts so Zope remotamente.

Nos sistemas Unix você tem várias ferramentas a seu dispor para escrever scripts do Zope
remotamente. Um exemplo simples é usar wget para chamar URLs dos scripts do Zope e usar cron para
programar as chamadas do script. Por exemplo, suponha que você tem um script do Zope que alimenta
os leões e você gostaria de chamar toda as manhãs. Você pode usar wget para chamar o script assim:

$ wget --spider http://www.zopezope.org/Lions/feed

A opção spider diz para o wget não salvar a resposta como um arquivo. Auponha que seu script é
protegido e requer autorização. Você pode passar seu nome de usuário e senha com wget para acessar
scripts protegidos:

$ wget --spider --http_user=ZooKeeper --http_pass=SecretPhrase http://www.zopezope.org/Lions/

Agora vamos usar cron para chamar este comando cada manhã as 8am. Edite seu arquivo crontab com o
comando crontab:

194 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

$ crontab -e

Então adicione uma linha para chamar wget todos os dias as 8 da manhã:

0 8 * wget -v --spider --http_user=ZooKeeper --http_pass=SecretPhrase http://www.zopezoo.

A única diferença entre usar cron e chamar wget manualmente é que você deveria usar a letra v quando
estiver usando cron já que você não se importa com a saída do comando wget.

Para nosso exemplo final vamos ser realmente perversos. Já que a rede está construída dentro de
muitos sistemas diferentes, é fácil achar um candidato não razoável para escrever scripts do Zope. Se
você tem um Internet-enabled toaster você deveria provavelmente ser capaz de escrever um script do
Zope com ele. Vamos pegar o Microsoft Word como nosso exemplo de cliente do Zope. Tudo o que
precisamos é obter o Word para concordar a tickle URL.

A maneira mais fácil de escrever um script no Zope com o Word é dizer ao word abrir um documento e
então digitar uma URL com script do Zope como nome do arquivo como mostra a Figura 8.9.

Figura 8.9 Chamando uma URL com o Microsoft Word.

O Word irá então carregar a URL e retornar os resultados chamando o script Zope. Pelo fato do Word
não deixar você POST (colocar) argumentos nesta maneira, você pode passar argumentos GET entrando
com eles como parte da URL.

Você pode até mesmop controlar este comportamento usando scripts do Visual Basic embutidos no
Word. Por exemplo, aqui temos um fragmento do Visual Basic que diz para o Word abrir um novo
documento usando uma URL do script do Zope:

Documents.Open FileName:="http://www.zopezoo.org/LionCages/wash?use_soap=1&water_temp=hot"

Você poderia usar o Visual Basic para chamar URL do script do Zope de diferentes maneiras.

A URL do Zope para fazer scripts de transações de chamada é a chave para escrever scripts
remotamente. Já que você pode controlar o Zoper tão facilmente com simples URLs você pode
facilmente escrever scripts Zope com basicamente qualquer sistema network−aware.

Conclusão

195 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

O Zope oferece scripts com Python e Perl. Com scripts você pode controlar os objetos do Zope e juntar a
lógica, os dados e a apresentação da aplicação. Você também pode executar tarefas difíveis de
programação tais como processamento de imagem e análise gramatical do XML.

No próximo capítulo você aprenderá sobre ZCatalog, mecanismos de busca embutidos do Zope.

12. Procurando e Categorizando Conteúdo


Este capítulo mostra a você como indexar e buscar objetos com o mecanismo de busca
construído no Zope, O Catalog (Catálogo). Introduz conceitos de indexação e discute
diferentes modelos para indexação e busca. Enfim, trata de meta-dados e resultados de
busca. Este capítulo mostra a você como criar uma arquitetura poderosa e fácil para usar
a informação.

O Catalog é um mecanismo de busca embutido do Zope. Ele permite a você categorizar e pesquisar
todos os tipos de objetos do Zope. Você pode também usá-lo para procurar dados externos tais como
dados relacionais, arquivos, e páginas web remotas. Além disso, para pesquisar você pode usar o
Catalog para organizar coleções de objetos.

O Catalog suporta uma interface rica de busca. Você pode executar procura de textos completos, e pode
pesquisar múltiplos índices de uma só vez. Além disso, the catalog mantém traços de meta-dados sobre
objetos indexados. Aqui estão os dois modelos de uso do ZCatalog mais comuns:

Catalogação em Massa

Catalogar uma grande coleção de objetos todos de uma vez.

Catalogação Automática
Catalogar objetos como eles são criados e localizar mudanças realizadas neles.

Começando com Catalogação em Massa


Vamos dar uma olhada em como usar o catálogo para procurar documentos. Catalogação de um grupo
de objetos todos de uma vez é chamada catalogação em massa. Catalogação em massa envolve três
passos:

Criar um ZCatalog
Encontrar objetos e catalogá-los
Criar uma interface web para procurar o catálogo.

Escolha Zcatalog da lista de adição de produtos para criar um objeto ZCatalog. Isso leva você para o
formulário de adição do ZCatalog, como mostrado a Figura 9.1.

196 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 9.1 - Formulário de adição de ZCatalog

O formulário de adição pede a você um Id e um Title. O terceiro elemento do formulário é a caixa de


seleção Vocabulary. Por enquanto, deixe essa caixa em "Create one for me". Dê a seu ZCatalog o Id
"AnimalTracker" e clique em Add para criar seu novo catálogo. O ícone do Catalog parece com uma
pasta com uma pequena lupa nele. Selecione o ícone AnimalTracker para ver a aba Contents do Catalog.

Um ZCatalog parece muito uma pasta, mas ele tem um pouco mais de abas. Seis abas no ZCatalog são
exatamente as mesmas seis abas que você encontra em uma pasta padrão. O ZCatalog tem as seguintes
abas: Contents, Catalog, Properties, Indexes, MetaData, Find Objects, Advanced, Undo, Security e
Ownership. Quando você clica em um Zcatalog, você está na aba Contents. Aqui, você pode acrescentar
novos objetos e o ZCatalog os incluirá da mesma maneira que qualquer pasta faz. Você deveria notar que
restrição não significa que o objeto está disponível para pesquisa.

Agora que você criou um ZCatalog, você pode seguir para o próximo passo, encontrar objetos e
catalogá-los. Suponha que você tem um site do zôo com informações sobre animais. Para trabalhar com
esses exemplos, crie dois DTML Documentos que contêm informações sobre répteis e anfíbios:

Title: Rã quatro-olhos chilena

A rã quatro-olhos chilena tem um par luminoso de manchas em sua anca que parece olhos
enormes. Quando sentada, as coxas da rã escondem esses olhos-manchas. Quando predadores
se aproximam, a rã abaixa sua cabeça e ergue sua anca, criando uma cabeça muito maior e mais
intimidativa. Rãs são anfíbios.

Title: Pele da jibóia (python)

Morelia spilotes variegata calcula-se que possui 2.4 metros de comprimento. É uma jibóia
tamanho médio com manchas grandes com cor preto-para-cinza, crossbands, faixas, ou uma
combinação dessas marcas em um fundo amarelado para marrom escuro. Cobras são répteis.

Visitantes de seu Zoo querem ser capazes de pesquisar informações sobre os animais do mesmo.
Ansiosos herpetologistas querem saber se você tem sua cobra favorita, para isso você deveria
oferecê-los a capacidade de pesquisar por certas palavras e mostrar todos os documentos que contêm
essas palavras. A pesquisa é uma das mais úteis e comuns atividades da web.

O ZCatalog AnimalTracker que você criou pode catalogar todos os documentos em seu site Zope e
deixar seu usuário pesquisar por palavras específicas. Para catalogar seus documentos, vá para o
ZCatalog AnimalTracker e clique na aba Find Objects.

Nessa aba, você diz ao ZCatalog em que tipo de objetos você está interessado. Você quer catalogar todos
DTML Documents então selecione DTML Document da seleção múltipla Find objects of type e clique

197 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Find and Catalog.

O ZCatalog agora começará da pasta onde ele está situado e procurará todos os DTML Documents Ele
pesquisará na pasta e então descerá para dentro de todas as sub-pastas e suas sub-pastas. Se você tem
vários desses objetos, isso pode levar um longo tempo para terminar, então seja paciente.

Depois de um período de tempo, o Catalog levará você para a view Catalog automaticamente, com uma
mensagem dizendo-lhe o que ele acabou de fazer.

Abaixo da informação de status está uma lista de objetos que estão catalogados, eles são todos DTML
Documents. Para confirmar que esses são os objetos que você está interessado, você pode clicar neles
para olhá-los.

Você completou o primeiro passo da pesquisa de seus objetos, catalogando-os em um ZCatalog. Agora
seus documentos estão no banco de dados do ZCatalog. Agora você pode seguir para o terceiro passo,
criando uma página web e formulário de resultado para consultar o ZCatalog.

Formulários de Busca e Relatório


Para criar formulários de busca e relatório, certifique-se de que você está no catálogo AnimalTracker e
selecione Z Search Irteface da lista de adição. Selecione o ZCatalog AnimalTracker como o objeto
disponível para pesquisa, como mostrado na Figura 9.2.

Figura 9.2 - Criando um formulário de pesquisa para um ZCatalog

Nomeie o Report Id "SearchResults" e o Search Input Id "SearchForm" e clique Add. Isso criará dois
novos DTML Methods no ZCatalog AnimalTracker chamados SeachForm e SearchResults.

Esses objetos estão incluídos no ZCatalog, mas eles não estão catalogados pelo ZCatalog. O
AnimalTracker catalogou apenas DTML Documents. Os métodos de busca do relatório e do formulário
são apenas uma interface de usuário para pesquisar documentos de animais no Catalog. Você pode
verificar isso notando que os formulários de pesquisa e relatório não estão listados na aba Cataloged
Objects.

Para procurar o ZCatalog AnimalTracker, selecione o método SearchForm e clique em sua aba View.
Esse formulário tem vários elementos nele. Há um elemento de pesquisa para cada índice no ZCatalog.
Índices são explicados mais adiante na próxima seção. Por enquanto, você quer usar o elemento do
formulário PrincipiaSearchSource. Você pode deixar todos os outros elementos do formulário em
branco.

Para digitar palavras no elemento PrincipiaSearchSource do formulário você pode procurar todos os

198 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

documentos catalogados pelo ZCatalog AnimalTracker. Por exemplo, digite a palavra "Répteis". O
ZCatalog AnimalTracker procurará e retornará uma tabela simples de objetos que tem a palavra
"Répteis" nele. Os resultados da pesquisa deveriam incluir a pele da jibóia. Você pode também tentar
especificar múltiplos termos de pesquisa como "afíbio réptil". Os resultados da pesquisa dessa consulta
deveriam incluir ambos, a rã quatro-olhos chilena e a pele da jibóia. Parabéns, você criou um catálogo
com sucesso, catalogou conteúdo nele e pesquisou através da web.

Configurando Catálogos
O Catalog é capaz de realizar pesquisas muito mais poderosas e complexas do que aquela que você
acabou de realizar. Vamos dar uma olhada em como o Catalog armazena informação. Isso ajudará você a
aprimorar seus catálogos para fornecerem o tipo de pesquisa que você quer.

Definindo Índices

ZCatalogs armazenam informação sobre objetos e seus conteúdos em bancos de dados rápidos
chamados índices. Índices podem armazenar e reaver grandes volumes de informação muito
rapidamente. Você pode criar diferentes tipos de índices que lembram diferentes tipos de informação
sobre seus objetos. Por exemplo, você poderia ter um índice que lembra o conteúdo de texto dos DTML
Documents, e um outro índice que lembra alguns objetos que têm uma propriedade específica.

Quando você procura um ZCatalog, você não está procurando por seus objetos um por um. Isso levaria
tempo demais se você tivesse muitos objetos. Antes de você procurar um ZCatalog, ele procura seus
objetos e lembra tudo que você disse-lhe para lembrar sobre eles. Esse processo é chamado indexação.
Daqui em diante, você pode procurar por determinados critérios e o ZCatalog retornará objetos que
atendam os critérios que você forneceu.

Um bom modo para pensar em um índice em um ZCatalog é como um índice em um livro. Por exemplo,
em um índice de livro você pode procurar a palavra Python:

Python: 23, 67, 227

A palavra Python aparece em três páginas. Os índices do Zope funcionam assim exceto pelo fato deles
traçarem o termo de pesquisa, nesse caso a palavra Python, para uma lista de todos os objetos que a
contém, em vez de uma lista de páginas em um livro.

No Zope 2.4, índices podem ser acrescentados e removidos de um Catalog usando uma moderna,
interface de índice "plugada" como mostrada a Figura 9.3:

Figura 9-3 - Administrando índices

199 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Aqui, você pode ver que ZCatalogs vêm com índices pré-definidos. Cada índice tem um nome, como
PrincipiaSearchSource, e um tipo, como TextIndex.

Quando você cataloga um objeto o Catalog usa cada índice para examinar o objeto. O catálogo consulta
atributos e métodos para encontrar um valor do objeto para cada índice. Por exemplo, no caso dos
DTML Documents catalogados com um índice PrincipiaSearchSource, o Catalog chama cada método
PrincipiaSearchSource do documento e grava o resultado em seu índice PrincipiaSearchSource. Se o
Catalog não pode encontrar um atributo ou método para um índice, então ele ignora-o. Em outras
palavras é bom se um objeto não suporta um determinado índice. Existem três tipos de índices:

TextIndex

Procura texto. Use esse tipo de índice quando você quer uma pesquisa de texto completo.

FieldIndex

Pesquisa objetos por valores específicos. Use esse tipo de índice quando você quer pesquisar
objetos data, números, ou strings específicas.

KeywordIndex

Pesquisa coleções de valores específicos. Esse índice é como um FieldIndex, mas ele permite a
você procurar coleções em lugar de valores únicos.

PathIndex

Procura por todos objetos que contém certos elementos do path da URL. Por exemplo, você
poderia procurar por todos os objetos cujos paths começam com /Animals/Zoo.

Nós examinaremos esses diferentes índices mais de perto posteriormente no capítulo. Índices novos
podem ser criados a partir da aba Indexes de um ZCatalog. Aí, você pode entrar com o name e selecionar
um type para seu novo índice. Isso cria um índice novo e vazio no ZCatalog. Para colocar informação
neste índice, você precisa ir para a aba Advanced e clicar no botão Update Catalog. Recatalogar seu
conteúdo pode demorar um tempo se você tiver muitos objetos catalogados.

Para remover um índice de um Catalog, selecione os índices e clique no botão Delete. Isso apagará o
índice e todo seu conteúdo indexado. Como sempre, essa operação não pode ser desfeita.

Definindo Meta Dados

O ZCatalog não apenas indexa informação sobre seu objeto, mas ele pode também armazenar
informação sobre seu objeto em um tabular database chamado Meta-Data Table (Tabela Meta-Dados).
A Tabela Meta-Dados funciona similarmente a uma tabela de banco de dados relacional, ela consiste de
uma ou mais colunas que definem o esquema da tabela. A tabela está preenchida com linhas de
informação sobre objetos catalogados. Essas linhas podem conter informação sobre objetos catalogados
que você quer armazenar na tabela. Suas colunas de meta dados não precisam ligar seus índices do
Catalog. Índices permitem você pesquisar; meta-dados permite você informar resultados da pesquisa.

A Tabela Meta-Dados é útil para gerar relatórios de pesquisa. Ela mantém o caminho da informação
sobre objetos que vão em seus formulários de relatório. Por exemplo, se você cria uma coluna de Tabela
Meta-Dados chamada absolute_url, então seus formulários de relatório podem usar essa informação
para criar links a seus objetos que são retornados nos resultados da pesquisa.

Para adicionar uma nova coluna da Tabela Meta-Dados, digite no nome da coluna na aba Meta-Data
Table e clique Add. Para remover uma coluna da Tabela Meta-Dados, selecione a coluna cheque a caixa e

200 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

clique no botão Delete. Isso apagará a coluna e todo seu conteúdo para cada linha. Como sempre, essa
operação não pode ser desfeita. Logo vamos ver mais de perto como procurar um Catalog.

Buscando em Catálogos
Você pode procurar um Catalog passando-o termos de procura. Esses termos de procura descrevem o
que você está procurando em um ou mais índices. O Catalog pode coletar essa informação da requisição
da web, ou você pode passar essa informação explicitamente do DTML ou Python. Em resposta para
uma requisição de pesquisa, um Catalog retornará uma lista de registros correspondendo aos objetos
catalogados que ligará os termos de pesquisa.

Buscando com Formulários

Nesse capítulo você usou o Z Search Interface para construir automaticamente um par Form/Action
(Formulário/Ação) para consultar um Catalog (o modelo Form/Action é discutido no Capítulo 4,
"Conteúdo Dinâmico com DTML"). O Z Search Interface constrói um formulário muito simples e um
relatório muito simples. Esses dois métodos são um bom lugar para começar entender como Catalogs
são consultados e como você pode personalizar e estender sua interface de pesquisa.

Suponha que você tem um catálogo que organiza notícias. Cada notícia tem conteúdos, um autor e uma
data. Seu catálogo tem três índices que correspondem a esses atributos. O índice de conteúdos é um
índice de texto e os índices autor e data são índices campo. Aqui está o formulário de pesquisa que
permitiria a você consultar certo catálogo:

201 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<form action="Report" method="get">


<h2><dtml-var document_title></h2>
Enter query parameters:<br><table> <br>

<tr><th>Content</th>
<td><input name="content" width=30 value=" "></td></tr>
<tr><th>Author</th>
<td> <input name="author" width=30 value=" "></td></tr>
<tr><th>Date</th>
<td> <input name="date" width=30 value=" "></td></tr>

<tr><td colspan=2 align=center>


<input type="SUBMIT" value="Submit Query">
</td></tr>
</table>
</form>

<dtml-var standard_html_footer>

Esse formulário consiste de três caixas de entrada chamadas content, author, e date. Esses nomes de
elementos de entrada do formulário ligam os nomes dos índices no catálogo. Esses nomes devem ligar
os nomes dos índices do catálogo para o mesmo encontrar os termos de pesquisa. Aqui está um
formulário de relatório que trabalha com o formulário de pesquisa:

202 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<table>
<dtml-in NewsCatalog>
<tr>
<td> <dtml-var author> </td>
<td> <dtml-var date> </td>
</tr>
</dtml-in>
</table>

<dtml-var standard_html_footer>

Há algumas coisas aqui que merecem uma verificação mais de perto. O principal de tudo é a tag in:

<dtml-in NewsCatalog>

Essa tag chama o Catalog NewsCatalog. Note como os parâmetros do formulário de pesquisa (content,
author, date) não são mencionados aqui. O Zope automaticamente certifica-se de que os parâmetros de
consulta do formulário de pesquisa são dados ao Catalog. Tudo que você tem a fazer é certificar-se de
que o formulário de relatório chama o Catalog. O Zope localiza os termos de pesquisa na requisição web
e passa-os para o Catalog.

O Catálogo retorna uma seqüência de Record Objects (tal como ZSQL Methods). Esses objetos de
registro correspondem a search hits, que são objetos que ligam o critério de pesquisa que você digitou
neles. Para um registro ligar-se a uma pesquisa, ele deve ligar todos os critérios para cada índice
especificado. Assim, se você digita um autor e alguns termos de pesquisa para os conteúdos, o Catalog
retornará apenas registros que liguem ambos, o autor e os conteúdos.

Objetos de registro tinham um atributo para toda coluna na tabela de banco de dados. Objetos de
registro para Catalogs funcionam muito similarmente, exceto pelo fato de um objeto Catalog Record
tenha um atributo para toda coluna na Tabela Meta-Dados. Na realidade, o propósito da Tabela
Meta-Dados é definir o esquema para objetos de registro que consultas de Catalog retornam.

Buscando Através do Python

DTML faz consulta a um Catalog de uma forma muito simples. Geralmente, o DTML certificará
automaticamente se seus parâmetros de pesquisa são passados corretamente ao Catalog.

Às vezes, entretanto, você pode não querer procurar um Catalog a partir de um formulário web; alguma
outra parte de sua aplicação pode querer consultar um Catalog. Por exemplo, suponha que você quer
acrescentar um sidebar para o Zôo Zope que mostra notícias que se relacionam apenas com os animais
na seção do site que você está atualmente olhando. Como você viu, o site Zôo Zope é construído com
Folders (pastas) que organizam todas as seções de acordo com o animal. Cada id do Folder é um nome
que especifica o grupo ou animal que a pasta contém. Suponha que você quer seu sidebar para
mostrar-lhe todas as notícias que contém o id da seção atual. Aqui está um Script chamado
relevantSectionNews que consulta o Catalog de notícias com o id da pasta atual:

203 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

## Script (Python) "relevantSectionNews"


##
" " "Returns news relevant to the current folder's id " " "
id=context.getId()
return context.NewsCatalog({content : id})

Esse script consulta o NewsCatalog ao chamá-lo como um método. O Catalog espera um mapping como
o primeiro argumento quando eles são chamados. O argumento mapeia o nome de um índice para os
termos de pesquisa que você está procurando. Nesse caso, o índice content será consultado por todas as
notícias que contêm o nome do Folder atual. Para usar isso em seu sidebar, apenas edite o
standard_html_header do Zôo Zope para usar o script relevantSectionNews:

<html>
<body>
<dtml-var style_sheet>
<dtml-var navigation>
<ul>
<dtml-in relevantSectionNews>
<li><a href="&dtml-absolute_url;"><dtml-var title> </a> </li>
</dtml-in>
</ul>

Esse método assume que você definiu absolute_url e title como colunas meta-dados no Catalog de
notícias. Agora, quando você está em uma seção particular, a sidebar mostrará uma lista simples de
links para notícias que contêm o id da seção animal atual que você está visualizando.

Buscando e Indexando Detalhes


Anteriormente você viu que o Catalog suporta três tipos de índices, índices de texto, índices de campo e
índices de palavra chave. Vamos examinar esses índices mais de perto para entender para que eles
servem e como procurá-los.

Buscando Índices de Texto

Um Text Index (índice de texto) é usado para indexar texto. Depois de indexar, você pode procurar o
índice por objetos que contêm certas palavras. Text Indexes suportam uma rica gramática de pesquisa
para fazer buscas mais avançadas que apenas procurar por uma palavra. O Text Index do ZCatalog
pode:

Procurar por expressões Booleanas como "word1 AND word2". Isso procurará por todos os
objetos que contêm ambas "word1" e "word2". Operadores Booleanos válidos incluem AND, OR,
e AND NOT.
Controlar a ordem de pesquisa com expressões usando parênteses "(word1 AND word2) OR
word3)". Isso retornará objetos contendo "word1" e "word2" ou apenas objetos que contêm o
termo "word3".
Se você usa um tipo especial de objeto Vocabulary (explicado um pouco mais adiante) você pode
pesquisar usando expressões comuns simples como "Z*", que retorna todas as palavras que
começam com "Z".

Todas essas características avançadas podem ser mescladas. Por exemplo, "((bob AND uncle) AND NOT
Zoo*)" retornará todos os objetos que contêm os termos "bob" e "uncle" mas não incluirá objetos que
contêm palavras que começam com "Zoo" como "Zoologist", "Zoology", ou "Zoo" mesmo.

Consultar um TextIndex com essas características avançadas funciona da mesma maneira que
consultá-lo com as características simples originais. No formulário de pesquisa HTML para DTML

204 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Documents, por exemplo, você poderia digitar "Koala AND Lion" e obter todos os documentos sobre
Coalas e Leões. Consultar um TextIndex a partir do Python com características avançadas funciona da
mesma forma; suponha que você quer mudar seu Script relevantSectionNews para não incluir notícias
que contenham a palavra "catastrophic":

## Script (Python) "relevantSectionNews"


##
" " " Returns relevant, non-catastropic news " " " "
id=context.getId()
return context.NewsCatalog(
{content : id + ' AND NOT catastrophic'}
}

TextIndexes são muito poderosos. Quando mesclados com o modelo de Catalogação Automática
descrito mais tarde no capítulo, eles dão a você a habilidade para automaticamente pesquisar
livremente textos em todos os objetos que você criou e editou.

Vocabulários

Vocabulários são usados pelos índices de texto. Um vocabulário é um objeto que administra opções de
indexação de texto específico da língua. Para o ZCatalog trabalhar com algum tipo de língua, ele deve
entender certos comportamentos dessa língua. Por exemplo, todas as línguas:

Tem um conceito diferente de words (palavras). Em Inglês e muitas outras línguas, palavras são
definidas por limites de espaço em branco, mas em outras línguas, como Chinês e Japonês,
palavras são definidas por seu uso contextual.
Tem conceitos diferentes de stop words (palavras de pausa). Uma palavra de pausa é uma
palavra comum que deveria ser ignorada pelos índices. A palavra francesa nous seria
extremamente comum num texto francês e deveria provavelmente ser removida como uma
palavra de pausa, mas num texto em inglês ele poderia ter sentido perfeito para catalogar essa
palavra porque ela é muito rara.
Tem conceitos diferentes de sinônimos. O par de sinônimos automobile/car (automóvel/carro)
não faria sentido em nenhuma língua, apenas em Inglês.
Tem conceitos diferentes de derivação. Em Inglês, isso é comum em índices de texto para tirar
sufixos como ing de palavras, a fim de que bake e baking liguem a mesma palavra. Isso é
chamado derivação. Esses sufixos strippings fariam sentido apenas para o Inglês, e outras
línguas deveriam querer oferecer suas próprias derivações (ou não ter nenhum).

Vocabulários Atuais

Existe vários vocabulários disponíveis atualmente para ZCatalog:

Vocabulários Simples

Vocabulários simples são muito simples e realizam o mínimo de tarefas específicas do idioma
inglês.

Vocabulários Globais

Vocabulários Globais são vocabulários mais complexos que permitem pesquisas de expressões
em texto em inglês para serem realizadas. O lado ruim deles é que consomem muito mais
memória e espaço no banco de dados que vocabulários simples.

A idéia por trás dos Vocabulários é personalizar o modo do texto em qualquer linguagem que está
indexada. Devido a isso, outras linguagens podem ser suportadas no futuro por pessoas que criam um
Vocabulário específico para sua linguagem. Criar seu próprio Vocabulário é um tópico avançado e está

205 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

além do objetivo desse livro.

Usando Vocabulários

Quando você cria um ZCatalog novo, o formulário de adição do ZCatalog tem uma caixa de seleção para
você escolher um vocabulário para usar. Se você não selecionar um vocabulário, o ZCatalog cria
automaticamente um Vocabulário Simples para você, e acrescenta-o aos conteúdos do ZCatalog (isso
pode ser visto na aba Contents do AnimalTracker que você criou para os exemplos desse capítulo).

Para usar um Vocabulário Global ou qualquer outro tipo de Vocabulário, você deve criá-lo primeiro
antes de criar o Catálogo em que você quer usá-lo. Um ZCatalog pode usar qualquer Vocabulário dentro
de seus conteúdos ou qualquer Vocabulário que ele pode encontrar acima dele na hierarquia de Pasta
do Zope.

Buscando Índices de Campo

FieldIndexes (índices de campo) diferem pouco dos TextIndexes (índices de texto). Um TextIndex
considera o valor que ele encontra em seu objeto, por exemplo os conteúdos de uma notícia, como texto.
Isto significa que ele divide o texto em palavras e indexa todas as palavras individualmente.

Um FieldIndex não divide o valor que ele encontra. Ao contrário, ele indexa inteiro o valor que ele
encontra. Isto é muito útil para localizar objetos que têm características com valores fixos.

No exemplo de notícia, você criou dois FieldIndexes, date e author. Com o formulário de pesquisa
existente, esses campos não são muito úteis. Para usa-los mais eficazmente você tem que personalizar
um pouco seu formulário de pesquisa. Antes de fazer isso entretanto, vamos considerar alguns casos de
uso para esses índices.

O índice date permite a você procurar por notícias pela data em que foram criadas. O formulário de
pesquisa existente não é muito útil entretanto porque você tem que digitar exatamente a hora que você
está procurando, até o segundo, na caixa de texto para obter êxito. Isso, obviamente, não é muito útil.
Seria melhor procurar por uma série de datas, como todas as notícias acrescentadas nas últimas 24
horas, ou todos os próximos Items do último mês.

O índice author permite a você procurar por notícias de certos autores. A menos que você saiba
exatamente o nome do autor que está procurando entretanto, não obterá quaisquer resultados. Seria
melhor ser capaz de selecionar de uma lista de todos os autores únicos indexados pelo índice author.

FieldIndexes (índices de campo) são projetados para fazer ambos, pesquisa de série e pesquisa por um
valor único no índice. Para levar vantagem dessas características, você precisa apenas mudar um pouco
seu formulário de pesquisa. Vamos tentar o primeiro exemplo, pesquisa de série com datas.

Como TextIndexes, FieldIndexes podem passar opções especiais para habilitar essas características.
Essas características especiais precisam ser passadas como elementos do formulário que conseguem
entrar nas consultas do Catalog. Aqui está o formulário de pesquisa usado na seção anterior Searching
with Forms, mas com alguns elementos novos do formulário acrescentados para habilitar pesquisa por
notícias modificadas desde "Yesterday", "Last Week", "Last Month", "Last Year" ou "Ever":

206 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<form action="Report" method="get">


<h2><dtml-var document_title></h2>
Search for News Items:<br><table>

<tr><th>Content</th>
<td><input name="content" width=30 value=""></td></tr>
<tr><th>Author</th>
<td><input name="author" width=30 value=""></td></tr>
<tr>
<td><p>modified since:</p></td>
<td>
<input type="hidden" name="date_usage" value="range:min">
<select name="date:date">
<option value="<dtml-var expr="ZopeTime(0)" >Ever</option>
<option value="<dtml-var expr="ZopeTime() - 1" > " >Yesterday</option>
<option value="<dtml-var expr="ZopeTime() - 7" > " >Last Week</option>
<option value="<dtml-var expr="ZopeTime() - 30" > " >Last Month</option>
<option value="<dtml-var expr="ZopeTime() - 365" >" >Last Year</option>
</select>
</td>
</tr>

<tr><td colspan=2 align=center>


<input type="SUBMIT" value="Submit Query">
</td></tr>
</table>
</form>
<dtml-var standard_html_footer>

Isso deveria fazer seu formulário de pesquisa parecer com a Figura 9.4.

Figura 9.4 - Pesquisa de série por Data

Este formulário HTML muda o formato da data do formulário de pesquisa antigo. Ao invés de apenas
uma caixa de texto, ele lhe oferece uma caixa de seleção onde você pode escolher uma data. Mas lembre,
isto é uma pesquisa de série. Você pode ver a parte que diz para o FieldIndex date para procurar por
série? Aqui está ela:

207 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<input type="hidden" name="date_usage" value="range:min">

Este é um tipo especial de elemento do formulário HTML chamado de elemento hidden.

Ele não mostra qualquer lugar que você olha no formulário de pesquisa, mas é ainda passado no Zope
quando você dá um submit no formulário. Este elemento especial, chamado date_usage diz para o
FieldIndex date que o valor no elemento de formulário date é um minimum range boundary (limite de
série mínimo). Isto significa que o FieldIndex não retornará apenas objetos que têm essa data, mas
retornará objetos que têm essa data ou qualquer data posterior.

Qualquer tipo de FieldIndex pode ser dito que tipo de especificadores de série usar ao acrescentar um
argumento de pesquisa adicional que acrescenta o sufixo o nome índice com"_usage". Além disso, para
especificar um limite de série mínimo, você especifica um limite de série máximo mudando o elemento
de formulário hidden para:

<input type="hidden" name="date_usage" value="range:max">

Isto fará o formulário de pesquisa retornar todas as notícias modificadas antes da data especificada, ao
invés de depois.

A sintaxe "_usage" pode ser usada também quando chamar um Catalog diretamente de um script, como
este Script, relevantRecentSectionNews:

## Script (Python) "relevantRecentSectionNews"


##
" " " Return relevant, and recent, news for this section " " "
id=context.getId()
return context.NewsCatalog(
{content : id,
date : ZopeTime() - 7,
date_usage : range:min,
}
)

Este funciona da mesma maneira que seu script relevantSectionNews antigo, exceto pelo fato dele
mostrar apenas notícias criadas na última semana.

Você pode também fornecer ambos, um limite de série mínimo e máximo. Há um problema para isto,
entretanto. Normalmente se você não especifica nenhum limite de série ou apenas um limite, o ZCatalog
usa o valor que você passa nele como o termo de pesquisa. Mas quando você fornece dois limites de
série, o ZCatalog precisa de dois valores, não um. Aqui está o Script relevantRecentSectionNews acima
com algumas modificações para fornecer uma lista de objetos data ao invés de apenas uma:

## Script (Python) "relevantRecentSectionNews"


##
" " "
Return relevant news modified in the last month, but not the
last week
" " "
id=context.getId()
return context.NewsCatalog(
{content : id,
date : [ZopeTime() - 30, ZopeTime() - 7],
date_usage : range:min:max,
}
)

Este script retornará todas as notícias relevantes modificadas no último mês, mas não na semana

208 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

passada. Quando usar dois especificadores de série, é importante certificar-se de que você obtém a
ordem dos valores corretamente para ligar a ordem dos especificadores de série. Se você fosse ligar
acidentalmente o "min" e "max", mas não ligasse as duas datas, então você não obterá resultados da
pesquisa porque está fazendo uma consulta que não tem sentido (fornecendo um valor mínimo que é
maior que o valor máximo).

O segundo caso de uso que você considerou acima estava sendo capaz de pesquisar de uma lista de
todos autores únicos. Há um método especial no ZCatalog que faz exatamente isso chamado
uniqueValuesFor. O método uniqueValuesFor retorna um lista de valores únicos para um certo índice.
Vamos mudar seu formulário de pesquisa novamente, e substituir a caixa de entrada author original
com algo um pouco mais útil:

209 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<form action="Report" method="get" >


<h2><dtml-var document_title></h2>
Search for News Items:<br><table>

<tr><th>Content:</th>
<td><input name="content" width=30 value=" "></td></tr>
<tr valign="top">
<td><p>Author:</p></td>

<td>
<select name="author:list" size=6 MULTIPLE>
<dtml-in expr="AnimalTracker.uniqueValuesFor(author)" >
<option value=" <dtml-var sequence-item>" >
<dtml-var sequence-item> </option>
</dtml-in>
</select>
</td>
</tr>

<tr>
<td><p>modified since:</p></td>
<td>
<input type="hidden" name="date_usage" value="range:min">
<select name="date:date">
<option value="<dtml-var "ZopeTime(0)">" >Ever</option>
<option value="<dtml-var "ZopeTime() - 1">">Yesterday</option>
<option value="<dtml-var "ZopeTime() - 7">">Last Week</option>
<option value="<dtml-var "ZopeTime() - 30" >">Last Month</option>
<option value="<dtml-var "ZopeTime() - 365" >">Last Year</option>
</select>
</td>
</tr>

<tr> <td colspan=2 align=center>


<input type="SUBMIT" name="SUBMIT" value="Submit Query" >
</td></tr>
</table>
</form>
<dtml-var standard_html_footer>

A nova, parte importante do código acrescentada ao formulário de pesquisa é:

210 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<select name="author:list" size=6 MULTIPLE>


<dtml-in expr="AnimalTracker.uniqueValuesFor(author)">
<option value="<dtml-var sequence-item>"<
<dtml-var sequence-item></option>
</dtml-in>
</select>

O HTML também foi mudado um pouco para fazer a apresentação na tela ter sentido.

Nesse exemplo, você está mudando o elemento author do formulário de apenas uma caixa de texto
simples para uma caixa de seleção múltipla HTML. Esta caixa contém uma lista única de todos os
autores que estão indexados no FieldIndex author. Agora, seu formulário de pesquisa deveria parecer
com a Figura 9.5.

Figura 9-5 - Pesquisa de série e Autores únicos

É isso aí. Você pode continuar a modificar esse formulário de pesquisa usando elementos de formulário
HTML para ser tão complexo quanto você gostaria. Na próxima seção, nós mostraremos-lhe como usar
o próximo tipo de índice, índices de palavra chave.

Buscando Índices de Palavra Chave

Um KeywordIndex indexa uma seqüência de palavras chave para objetos e pode ser consultado por
quaisquer objetos que tenham uma ou mais dessas palavras chave.

Suponha que você tem vários objetos Image que têm uma propriedade topics. A propriedade topics é
uma propriedade lines que lista os tópicos relevantes de uma dada Imagem, por exemplo, "Portraits",
"19th Century", e "Women" para uma foto da Rainha Victoria.

Os tópicos fornecem uma maneira de categorizar Imagens. Cada Imagem pode pertencer a uma ou mais
categorias dependendo de sua propriedade topics. Por exemplo, o retrato (portrait) da Rainha Victoria
pertence a três categorias e pode assim ser encontrado pela pesquisa por qualquer dos três termos.

Você pode usar um índice KeyWord para procurar a propriedade topics. Defina um índice KeyWord
com o nome topics em seu ZCatalog. Logo, catalogue suas Imagens. Agora você deveria ser capaz de
encontrar todas as Imagens que são retratos (portraits) criando um formulário de pesquisa e pesquisar
por "Portraits" no campo topics. Você pode também encontrar todas as fotos que representam
assuntos, como Século 19, pesquisando por "19th Century".

É importante compreender que a mesma Imagem pode estar em mais de uma categoria. Isto dá a você
muito mais flexibilidade em pesquisar e categorizar seus objetos que você obtém com um índice de
campo. Usando um índice de campo seu retrato da Rainha Victoria pode ser categorizado apenas de

211 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

uma maneira. Usando um índice de palavra chave ele pode ser categorizado de muitas maneiras
diferentes.

Freqüentemente você usará uma pequena lista de termos com índices KeyWord. Neste caso você pode
querer usar o método uniqueValuesFor para criar um formulário de pesquisa padrão. Por exemplo, aqui
está uma parte do DTML que criará uma caixa de seleção múltipla para todos os valores no índice
topics:

<select name="topics:list" multiple>


<dtml-in expr="uniqueValuesFor(topics)">
<option value="&dtml-sequence-item;"><dtml-var sequence-item> </option>
</dtml-in>
</select>

Usando esse formulário de pesquisa você pode oferecer usuários com uma série de termos de pesquisa
válidos. Você pode selecionar tantos tópicos quanto você quiser e o Zope encontrará todas as Imagens
que ligam um ou mais de seus tópicos selecionados. Cada objeto não apenas pode ter vários termos
indexados, mas você pode fornecer vários termos de pesquisa e encontrar todos os objetos que têm um
ou mais destes valores.

Buscando Índices de Caminho

Índices de Caminho permitem você procurar por objetos baseados em sua localização no Zope. Suponha
que você tem um objeto cujo caminho é /zoo/animals/Africa/tiger.doc. Você pode encontrar este objeto
com as consultas de caminho: /zoo, or /zoo/animals, or /zoo/animals/Africa. Em outras palavras, um
índice de caminho permite-lhe encontrar objetos dentro de uma dada pasta (e abaixo dela).

Se você coloca objetos relacionados dentro das mesmas pastas, você pode usar índices de caminho para
localizá-los rapidamente. Por exemplo:

<h2>Lizard Pictures</h2>

<p>
<dtml-in expr="Catalog(meta_type=Image,
path=/Zoo/Animals/Lizard)">
<a href="&dtml-absolute_url;"><dtml-var title></a>
</dtml-in>
</p>

Esta consulta procura um catálogo por todas as imagens que estão localizadas dentro da pasta
/Zoo/Animals/Lizard e abaixo. Ela cria um link para cada imagem.

Dependendo de como você optar por organizar objetos em seu site, você pode achar que índices de
caminho são mais ou memos eficazes. Se você localiza objetos dentro de seu assunto (por exemplo, se
objetos estão principalmente localizados nas pastas "home" de usuário) então índices de caminho
podem ser de valor limitado. Nestes casos, índices de palavra chave e de campo serão mais úteis.

Buscas Avançadas com Registros


Uma nova característica do Zope 2.4 é a habilidade para consultar índices mais precisamente usando
objetos registro. Objetos registro contêm informação sobre como consultar um índice. Registros são
objetos Python com atributos, ou mappings. Índices diferentes suportam atributos de registro

212 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

diferentes.

Atributos de Registros para Índices de Palavra Chave

query

Ou uma seqüência de palavras ou uma palavra única. (obrigatória)

operator

Especifica se todas palavras chave ou apenas uma precisa ligar. Valores permitidos: and , or.
(opcional, default: or)

Por exemplo:

# big or shiny
results=Catalog(categories=['big, 'shiny'])

# big and shiny


results=Catalog(categories={'query':[big,'shiny'],
'operator':'and'})

A segunda consulta liga objetos que têm ambas palavras chave "big" e "shiny". Sem usar a sintaxe de
registro você pode apenas ligar objetos que são big ou shiny.

Atributos de Registros para Índices de Campo

query

Ou uma seqüência de objetos ou um valor único para ser passado como consulta para o índice
(obrigatório).

range

Define uma pesquisa de série em um Field Index (opcional, default: não instalado).

Valores permitidos:

min

Procura por todos os objetos com valores maiores que o mínimo de valores passados no
parâmetro query.

max

Procura por todos os objetos com valores menores que o máximo de valores passados no
parâmetro query.

minmax

Procura por todos os objetos com valores menores que o máximo de valores passados no
parâmetro query e maiores que o mínimo de valores passados no parâmetro query.

213 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Por exemplo:

# items modified in the last week


results=Catalog(bobobase_modification_time={
'query':DateTime() - 7,
'usage': 'min'}
)

Esta consulta liga objetos com um bobobase_modification_time menores que DateTime() -7. Compare
esta consulta com uma definida anteriormente em relevantRecentSectionNews neste capítulo que usa
date_usage para realizar a mesma consulta.

Atributos de Registros para Índices de Texto

query

Qualquer uma seqüência de palavras (separadas por espaço em branco) ou uma palavra única
para ser passada como consulta para o índice. (obrigatório)

operator

Especifica como combinar os termos de pesquisa. (opcional, default: or).

Valores permitidos:

and

Todos os termos devem estar presentes.

or

Pelo memos um termo deve estar presente.

andnot

O primeiro termo deve estar presente, porém nenhum dos demais termos.

Não há muita razão para usar consultas de registro com índices de texto já que você pode pôr a
informação do perador na busca da string de uma maneira muito flexível.

Atributos de Registros para Índices de Caminho

query

Caminho para busca ou como uma string (e.g. "/Zoo/Birds") ou lista (e.g. ["Zoo", "Birds"]).
(obrigatória)

level

O nível de caminho para começar a pesquisar. (opcional, default: 0)

Suponha que você tem uma coleção de objetos com esses caminhos:

214 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

1. /aa/bb/aa/

2. /aa/bb/bb/

3. /aa/bb/cc/

4. /bb/bb/aa/

5. /bb/bb/bb/

6. /bb/bb/cc/

7. /cc/bb/aa/

8. /cc/bb/bb/

9. /cc/bb/cc/

Aqui estão algumas consultas de exemplo e seus resultados para mostrar como o atributo level
funciona:

query=/aa/bb, level=0 returns 1, 2, 3

query=/bb/bb, level=0 returns 4, 5, 6

query=/bb/bb, level=1 returns 2, 5, 8

query=/bb/bb, level=−1 returns 2, 4, 5, 6, 8

query=/xx, level=−1 returns none

Você pode usar o atributo level para flexibilizar partes diferentes de pesquisa do caminho.

Como no Zope 2.4.1, vocÊ também pode incluir a informação do nível em uma pesquisa sem usar um
registro. Simplesmente use uma tupla contendo a pesquisa e o nível. Aqui temos um exemplo de tupla:
("/aa/bb", 1).

Criando Registros em HTML

Você pode também realizar consultas de registro usando formulários HTML. Aqui está um exemplo
mostrando como criar um formulário de pesquisa usando registros:

215 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<form action="Report" method="get">


<table>
<tr><th>Search Terms (must match all terms)</th>
<td><input name="content.query:record" width=30 value=""> </td></tr>
<input type="hidden" name="content.operator:record" value="and">
<tr><td colspan=2 align=center>
<input type="SUBMIT" value="Submit Query">
</td></tr>
</table>
</form>

Para mais informação sobre a criação de registros em HTML veja a seção "Passando Parâmetros para
Scripts" no Capítulo 10, Script Avançado do Zope.

Pesquisas Armazenadas
Enquanto o uso principal do Catalog é fornecer pesquisa interativa, você pode também usar pesquisas
armazenadas para categorizar e organizar seu site. Por exemplo, na seção de índices de palavra chave
você viu como você pode usar o Catalog e propriedades para procurar por categorias de Images tais
como retratos. Além disso, para fornecer pesquisa interativa para categorias de Images você pode criar
páginas web com pesquisas capacitadas. Assim, por exemplo, aqui está um DTML que você poderia usar
para uma página que mostra todos seus retratos:

<dtml-var standard_html_header>

<h1>Portraits</h1>

<dtml-in expr="ImageCatalog({'topics':'Portraits'})">
<p>
<dtml-var sequence-item>
<dtml-var title_or_id>
</p>
</dtml-in>

<dtml-var standard_html_footer>

A natureza dinâmica desta página não está visível para o espectador. Contudo, apenas acrescente um
outro retrato, atualize o catálogo e essa página incluirá automaticamente a nova Image.

Esta técnica pode ser muito poderosa. Você apenas não pode organizar e mostrar recursos públicos,
mas você pode facilmente instituir sistemas workflow etiquetando objetos com propriedades para
indicar seu estado e catalogá-los. Depois é fácil para você criar páginas para pessoas diferentes que
mostram quais objetos precisam de sua atenção. Esta técnica é até mais poderosa quando usando o
modelo Automatic Cataloging.

216 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Catalogação Automática
Catalogação Automática é um modelo de uso avançado de Catálogo que mantém objetos atualizados
quando eles forem modificados. Ele requer que a medida que objetos são criados, modificados, e
destruídos, eles sejam automaticamente localizados por um ZCatalog. Isso geralmente envolve os
objetos notificando o Catalog quando eles são criados, modificados, ou apagados.

Esse modelo de uso tem várias vantagens em comparação com a catalogação em massa. A catalogação
em massa é simples mas tem desvantagens. O montante total de conteúdo que você pode indexar em
uma transação é equivalente a quantidade de memória virtual livre disponível para o processo do Zope,
mais a quantidade de armazenamento temporário que o sistema tem. Em outras palavras, quanto mais
conteúdo você quer indexar de uma só vez, melhor seu hardware tem que ser. A catalogação em massa
funciona bem para indexar alguns milhares de objetos, mas acima disso a indexação automática
funciona muito melhor.

Uma outra vantagem principal da catalogação automática é que ela pode controlar objetos que mudam.
Quando objetos evoluem e mudam, a informação de índice é sempre atual, até mesmo para mudar
rapidamente fontes de informação como caixas de mensagem.

Nessa seção, nós mostraremos a você um exemplo que cria "news" itens que pessoas podem acrescentar
em seu site. Estes itens serão automaticamente catalogados. Esse exemplo consiste de dois passos:

Criar um tipo novo de objeto para catalogar.


Criar um Catalog para catalogar os objetos criados recentemente.

A partir do Zope 2.3, nenhum dos objetos do Zope que estão prontos para usar suportam catalogação
automática. Isto é por razões de compatibilidade anteriores. Agora, você tem que definir seus próprios
tipos de objetos que podem ser catalogados automaticamente. Uma das maneiras em que isto pode ser
feito é definir uma ZClass.

Um ZClass é um objeto Zope que define tipos novos de objetos Zope. De certo modo, uma ZClass é como
desenho que descreve como os novos objetos do Zope são construídos. Considere uma notícia como as
discutidas em exemplos anteriores no capítulo. Notícias não têm apenas conteúdo, mas elas têm
também propriedades específicas que fazem delas notícias. Freqüentemente esses Items vêm em
coleções que têm suas próprias propriedades. Você quer construir um site Néws que coleciona News
Items, reveja-as, e divulgue-as online para um site web onde leitores possam lê-las.

Neste tipo de sistema, você pode querer criar um tipo novo de objeto chamado News Item. Deste modo,
quando você quer acrescentar uma notícia nova em seu site, você apenas seleciona-a a partir da lista de
adição de produtos. Se você planejou para este objeto ser catalogado automaticamente, então você pode
procurar o conteúdo de suas notícias de uma maneira melhor. Nesse exemplo, você apenas olha
rapidamente as ZClasses, que são descritas com muito mais detalhes no Capítulo 14, "Estendendo o
Zope".

Tipos novos de objetos são definidos na seção Products do Control Panel (Painel de Controle). Chega-se
lá clicando no Control Panel e então clicando no Product Management. Produtos contêm tipos novos de
ZClasses. Nesta tela, clique "Add" para acrescentar um produto New. Você será levado para o
formulário de adição de novos Productos.

Chame o Producto novo de "News" e clique "Generate". Isto levará você de volta para a aba Products
Management e você verá seu Producto novo.

Selecione o Produto News clicando nele. Este novo Produto parece muito com um Folder. Ele contém
um objeto chamado Help e tem um menu Add, bem como "abas" do Folder no topo. Para acrescentar

217 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

uma nova ZClass, abra o menu de seleção Add e selecione ZClass. Isto levará você para o formulário de
adição da ZClass, como mostra a Figura 9.6.

Figura 9.6 - Formulário de adição da ZClass

Este é um formulário complicado que será explicado com muito mais detalhe no Capítulo 14,
"Estendendo o Zope". Agora, você precisa apenas fazer três coisas para criar sua ZClass:

Especificar o Id "NewsItem". Esse é o nome da nova ZClass.


Especificar o meta_type "News Item". Esse será usado para criar a entrada no menu de adição
para seu novo tipo de objeto.
Selecionar ZCatalog: CatalogAware da caixa Base Classes da esquerda, e clique no botão com a
seta apontando para a caixa Base Classes da direita. Isto deveria fazer com que
ZCatalog:CatalogAware seja mostrado na janela da direita.

Quando você estiver pronto, não mude quaisquer das outras colocações no formulário. Para criar sua
nova ZClass, clique Add. Isto levará você de volta ao seu Produto News. Note que existe agora um objeto
novo chamado NewsItem bem como vários outros objetos. O objeto NewsItem é sua nova ZClass. Os
outros objetos são "auxiliares" que você examinará mais no Capítulo 14, "Estendendo o Zope".

Selecione o objeto ZClass NewsItem. Sua visualização deveria parecer agora com a Figura 9.7.

Figura 9-7 - A aba Methods da ZClass

Esta é a aba Methods de uma ZClass. Aqui, você pode acrescentar objetos Zope que atuarão como
métodos em seu novo tipo de objeto. Aqui, por exemplo, você pode criar DTML Methods ou Scripts e
esses objetos se tornarão métodos em quaisquer novos News Items que sejam criados. Antes de criar
quaisquer métodos contudo, vamos rever as necessidades desse novo objeto "News Item":

218 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

News Content

O News Item contém conteúdo de notícias, este é seu propósito primário. Esse conteúdo deveria
ser qualquer tipo de texto ou conteúdo de marcação como HTML ou XML.

Author Credit

O News Item deveria fornecer algum tipo de crédito para o autor ou organização que criou-a.

Date

News Items são expiráveis, assim a data em que o item foi criado é importante.

Keywords

News Items se ajustam dentro de várias listas de categorias. Por convenção, essas listas de
categorias são freqüentemente chamadas keywords.

Você pode querer que seu novo objeto News Item tenha outras propriedades, essas são apenas
sugestões. Para acrescentar propriedades novas a seu News Item clique na aba Property Sheets. Esta
leva você para a aba Property Sheets.

Propriedades são acrescentadas para novos tipos de objetos em grupos chamados Property Sheets. Já
que seu objeto não tem nenhuma property sheet definida, essa view está vazia. Para acrescentar uma
Nova Property Sheet, clique Add Common Instance Property Sheet, e dê a folha o nome "News". Agora
clique Add. Isto acrescentará uma nova Property Sheet chamada News a seu objeto. Clicar na nova
Property Sheet levará você para a aba Properties da Property Sheet News, como mostra a Figura 9.8.

Figura 9.8 - A tela de propriedades para uma Property Sheet

Esta aba é quase idêntica a aba Properties encontrada em Folders e outros objetos. Aqui, você pode criar
as propriedades de seu objeto News Item. Crie três propriedades novas dessa forma:

content

Este tipo de propriedade deveria ser texto. Cada News Item criada recentemente conterá sua
própria propriedade de conteúdo único.

author

Este tipo de propriedade deveria ser string. Essa conterá o nome do autor das notícias.

date

219 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Este tipo de propriedade deveria ser data. Ela conterá a hora e a data em que a notícia foi
atualizada pela última vez. A propriedade date requer um valor, por enquanto você pode entrar
com a string "01/01/2000".

É isso aí! Agora você criou uma Property Sheet que descreve suas News Items e que tipo de informação
elas contém. Propriedades podem ser pensadas como os dados que um objeto contém. Agora que nós
temos os dados todos setados, você precisa criar uma interface para seu novo tipo de objeto. Isto é feito
criando novas Views (abas) para seu objeto.

Clique na aba Views. Esta levará você para a aba Views, como mostra a Figura 9.9.

Figura 9.9 - A aba Views

Aqui, você pode ver que o Zope criou três abas default para você. Essas abas serão descritas com muito
mais detalhe no Capítulo 14, "Estendendo o Zope", mas por enquanto, basta dizer que elas definem as
abas que seus objetos terão eventualmente.

Para criar uma nova aba, use o formulário inferior da aba Views. Crie uma nova Aba com o nome "News"
e selecione "propertysheets/News/manage" da caixa de seleção e clique Add. Isto criará uma nova Aba
nessa tela depois das três Abas originais, como mostra a Figura 9.10.

Figura 9.10 - A nova aba News

Já que essa aba vai dar-nos a habilidade para editar a News Item, nós queremos que ela seja a primeira
aba que você vê quando seleciona o objeto News Item. Para mudar a ordem das abas, selecione a aba
News criada recentemente e clique no botão First. Isto deveria mover a nova aba do fundo para o início
da lista.

O passo final na criação de uma ZClass é definir os métodos para a classe. Métodos são definidos na aba

220 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Methods. Clique na aba Methods e você será levado para a aba Methods. Selecione DTML Method da
lista de adição e acrescente um novo DTML Method com o id "index_html". Essa será a aba default de
sua notícia. Acrescente o seguinte DTML no novo método:

<dtml-var standard_html_header>

<h1>News Flash</h1>

<p><dtml-var date> </p>

<p><dtml-var author></p>

<P><dtml-var content></p>

<dtml-var standard_html_footer>

É isso aí! Você criou seu próprio tipo de objeto chamado News Item. Quando você for para a pasta root,
você verá agora uma nova entrada em sua lista de adição.

Mas não acrescente quaisquer News Items ainda, porque o segundo passo desse exercício é criar um
Catalog que catalogará suas novas News Items. Vá para o folder raiz e crie um catálogo novo com o id
Catalog.

Como os dois exemplos anteriores de uso de um ZCatalog, você precisa criar Indexes (Índices) e uma
Table Meta-Data (Tabela Meta-Dados) que fazem sentido para seus objetos. Primeiro, apague os índices
default no novo ZCatalog e crie os seguintes índices para substituí-los:

content

Este deveria ser um TextIndex. Ele indexará o conteúdo de suas News Items.

title

Este deveria ser um TextIndex. Ele indexará o título de suas News Items.

author

Este deveria ser um FieldIndex. Ele indexará o autor da News Item.

221 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

date

Esta deveria ser um FieldIndex. Este indexará a data da News Item.

Depois de criar esses Índices, apague as colunas Meta-Dados default e acrescente essas colunas para
substituí-las:

author
date
title
absolute_url

Depois de criar os Índices e colunas de Table Meta-Data, crie uma interface de pesquisa para o Catalog
usando a ferramenta Z Search Interface descrita previamente no capítulo.

Agora você está pronto para seguir. Comece acrescentando novos News Items para seu Zope. Vá em
qualquer lugar no Zope e selecione News Item da lista de adição. Isto levará você para o Formulário de
adição para itens News.

Dê ao seu novo News Item o id "KoalaGivesBirth" e clique Add. Isto criará um novo News Item.
Selecione-o.

Note como ele tem quatro abas que ligam as quatro abas que estavam na ZClass. A primeira aba é News,
esta aba corresponde à Property Sheet News que você criou na ZClass News Item.

Entre com suas notícias na caixa contents:

Today, Bob the Koala bear gave birth to little baby Jimbo.

Entre com seu nome na caixa Author, e a data de hoje na caixa Date.

Clique Change e sua News Item deveria agora conter alguma notícia. Porque o objeto News Item é
CatalogAware, ele é automaticamente catalogado quando é modificado ou acrescentado. Verifique isto
ao olhar para a aba Cataloged Objects do ZCatalog que você criou para esse exemplo.

O News Item que você acrescentou é o único objeto que está catalogado. Quando você acrescenta mais
News Items ao seu site, eles serão automaticamente catalogados aqui. Acrescente um pouco mais de
itens, e então experimente pesquisar o ZCatalog. Por exemplo, se você procurar por "Koala" você
deveria obter como resultado o News Item KoalaGivesBirth.

Nesse ponto você pode querer usar alguns dos formulários de pesquisa mais avançados que você criou
anteriormente no capítulo. Você pode ver, por exemplo, que quando você acrescenta novos News Items
com novos autores, a lista de seleção de autores no formulário de pesquisa muda para incluir a nova
informação.

Conclusão
As características de catalogação do ZCatalog permitem-lhe procurar seus objetos por certos atributos
muito rapidamente. Isto pode ser muito útil para sites com muito conteúdo que muitas pessoas
precisam para serem capazes de pesquisar de uma maneira eficiente.

Pesquisa no ZCatalog funciona como pesquisa em um banco de dados relacional, a não ser pelo fato da
pesquisa ser mais orientada a objeto. Nem todos os modelos de dados são orientados a objeto contudo,
assim em alguns casos você pode querer usar o ZCatalog, mas em outros casos você pode querer usar

222 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

um banco de dados relacional. O próximo capítulo vai dar mais detalhes sobre como o Zope trabalha
com bancos de dados relacionais, e como você pode usar dados relacionais como objetos no Zope.

13. Conectividade de Banco de Dados


Relacionais
Este capítulo descreve como o Zope se conecta a banco de dados relacionais externos.
Mostra a você como se conectar e fazer buscas a um banco de dados. Também mostra as
características que permitem a você criar dados relacionais como se estivesse usando
objetos do Zope. Enfim, o capítulo mostra considerações de segurança e performance.

O Zope usa um banco de dados objeto para armazenar objetos do Zope. Bancos de dados relacionais tais
como Oracle, Sybase e PostgreSQL armazenar informações de modos diferentes. Bancos de dados
relacionais armazenam suas informações em tabelas, como mostra a Figura 10.1.

Figura 10.1 - Tabela de Banco de Dados Relacional

A informação na tabela é armazenada em linhas. O layout das colunas da tabela é chamado de esquema.
Uma linguagem padrão, chamada Structured Query Language (SQL - Linguagem de Busca Estruturada),
é utilizada para consultar e alterar tabelas em bancos de dados relacionais.

O Zope não armazena suas informações dessa forma. O banco de dados objeto do Zope permite muitos
tipos diferentes de objetos que têm muitos tipos diferentes de relacionamentos uns com os outros.
Dados relacionais não são facilmente mapeados em objetos uma vez que dados relacionais assumem um
modelo de dados orientado à tabelas muito mais simples. O Zope fornece vários mecanismos para
obtenção de dados relacionais e para usá-los no mundo dos objetos do Zope, incluindo Database
Adapters e SQL Methods que discutiremos detalhadamente neste capítulo.

O uso mais comum para o suporte à banco de dados relacionais do Zope é para colocar bancos de dados
relacionais existentes na web. Por exemplo, suponha que o seu Departamento de Recursos Humanos
tenha um banco de dados de empregados. Seu banco de dados vem com ferramentas para permitir os
administradores rodarem relatórios e alterarem dados. Entretanto, é difícil para os empregados verem
seus próprios registros e fazerem uma simples manutenção, como uma atualização no seu endereço
quando eles se mudam. Através do interfaceamento do seu banco de dados relacional com o Zope, seus
empregados podem usar qualquer web browser para ver e atualizar seus registros do escritório ou de

223 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

casa.

Usando o seu banco de dados relacional com Zope você obtém todos os benefícios do Zope, incluindo
segurança, apresentação dinâmica, serviços de rede, e mais. Você pode usar Zope para modelar
dinamicamente seu acesso aos dados, apresentação de dados, e administração de dados.

Para usar banco de dados relacional no Zope você deve criar dois diferentes objetos do Zope, um
Database Connection e um Z SQL Method. A Conexão de Banco de Dados diz ao Zope como conectar
com um banco de dados relacional. O Método Z SQL descreve uma ação para consulta em um banco de
dados. O Método Z SQL utiliza a Conexão de Banco de Dados para conectar-se com o banco de dados
relacional. Nós veremos mais de perto esses dois tipos de objetos nesse capítulo.

Usando Conexões de Banco de Dados


Conexões de Banco de Dados são utilizadas para estabelecer e administrar conexões com bancos de
dados relacionais externos. Conexões de Banco de Dados devem ser estabelecidas antes que os métodos
de banco de dados possam ser definidos. Outrossim, todo Método Z SQL deve ser associado com uma
conexão de banco de dados. Adaptadores de banco de dados (ou DAs, para abreviar) estão disponíveis
para os seguintes bancos de dados:

Oracle

Oracle é um banco de dados relacional comercial popular e poderoso. Este DA é escrito e tem
suporte comercial por parte da Zope Corporation. Oracle pode ser adquirido ou avaliado no web
site da Oracle.

Sybase

O Sybase é outro banco de dados relacional comercial popular. O Sybase DA é escrito e tem
suporte comercial por parte da Zope Corporation. Sybase pode ser adquirido ou avaliado no web
site da Sybase.

ODBC

ODBC é um protocolo padrão da indústria, independente de plataforma, código fonte aberto,


suportado por muitos bancos de dados comerciais. O DA ODBC é escrito e tem suporte
comercial por parte da Zope Corporation.

PostgreSQL

PostgreSQL é um banco de dados relacional de fonte aberto líder. Há vários adaptadores de


banco de dados para o PostgreSQL, incluindo ZpoPy, que é mantido pelo membro da
comunidade do Zope Thierry Michel. Você pode encontrar mais informação sobre PostgreSQL
no web site do PostgreSQL.

MySQL

MySQL é um banco de dados relacional rápido de fonte aberto. Você pode encontrar mais
informação sobre MySQL no web site do MySQL. O DA MySQL é mantido pelo membro da
comunidade Zope Monty Taylor.

Interbase

Interbase é um banco de dados relacional de fonte aberto da Borland/Inprise. Você pode


encontrar mais informação sobre Interbase no web site da Borland. Você pode também ficar

224 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

interessado no FireBird, que é uma comunidade mantida no ramo do Interbase. O adaptador


Interbase do Zope é mantido pelo membro da comunidade Zope Bob Tierney.

Gadfly

Gadfly é um banco de dados relacional escrito em Python por Aaron Waters. Gadfly está incluso
com o Zope para propósitos de demonstração e pequenos conjuntos de dados. Gadfly é rápido,
mas não é significativo para grandes quantias de informação, uma vez que lê o banco de dados
inteiro dentro da memória. Você pode descobrir mais sobre Gadfly no web site da Chordate.

Com excessão do Gadfly, todos os bancos de dados relacionais rodam como processos externos ao Zope.
Na verdade, seu banco de dados relacional não necessita rodar sempre na mesma máquina que o Zope,
pois o Zope pode conectar-se à máquina na qual o banco de dados está rodando. Instalar e configurar
bancos de dados relacionais está além do escopo deste livro. Todos os bancos de dados relacionais
mancionados têm sua própria documentação de instalação e configuração, que você deveria consultar
para detalhes específicos.

Devido ao Gadfly rodar dentro do Zope, você não necessita especificar qualquer informação de conexão
para o Zope encontrar o banco de dados. Uma vez que todos os outros tipos de bancos de dados rodam
externamente ao Zope, eles requerem que você especifique como conectar-se ao banco de dados. Esta
especificação, chamada de connection string, é diferente para cada tipo de banco de dados. A Figura
10.2, por exemplo, mostra o formulário de adição da conexão do banco de dados do PostgreSQL.

Figura 10.2 - Conexão do Banco de Dados PostgreSQL

Para o PostgreSQL, o formato de string de conexão é mostrado acima na Figura 10.2.

Para usar o banco de dados relacional de sua escolha através do Zope, você deve fazer o download e
instalar o adaptador de banco de dados para o seu banco de dados relacional específico. Adaptadores de
banco de dados podem ser baixados da sessão Products do Zope.org. A exceção para isto é o Gadfly, que
está incluso com o Zope. Todos os exemplos neste capítulo usam Gadfly, mas os procedimentos
descritos aplicam-se para todos os bancos de dados.

Após ter instalado o produto adaptador para o seu banco de dados, você pode criar uma nova conexão
de banco de dados selecionando-a em Add List. Todas as conexões de banco de dados são bastante
parecidas. Selecione o Z Gadfly Database Connection da Lista de adição. Isso levará você para o
formulário de adição para uma conexão de banco de dados Gadfly.

Selecione o data source (fonte de dados) Demo, especifique Gadfly_database_connection para o id, e
clique no botão Add. Isso criará uma nova conexão de banco de dados Gadfly. Selecione a nova conexão
clicando nela.

225 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Você está olhando a aba Status da conexão com o banco de dados Gadfly (Gadfly Database Connection).
Essa aba diz à você se você está conectado ou desconectado com o banco de dados, e tem um botão para
conectar ou desconectar. No geral o Zope administrará a conexão com o seu banco de dados para você,
então existem poucas razões para controlar manualmente a conexão. Para o Gadfly, conectar e
desconectar não tem sentido, mas para bancos de dados esternos você pode querer conectar ou
desonectar manualmente para fazer manutenção no banco de dados.

A próxima aba é a Properties. Essa aba mostra à você o datasource (a fonte de dados) e outras
propriedades da conexão com o banco de dados. Isso é útil se você quiser mover a sua conexão de banco
de dados de um datasource para outro. A figura 10.3 mostra a aba Properties.

Figura 10.3 - A aba Properties.

Você pode testar sua conexão a um banco de dados indo para a aba Test. Essa aba permite que você
digite código SQL diretamente e o execute em seu banco de dados. Essa aba é apenas para testar seu
banco de dados e emitir comandos SQL (como criação de tabelas). Esse não é o local onde você entrará
com a maior parte de seu código SQL. Os comandos SQL estão nos métodos Z SQL que são discutidos
mais tarde nesse capítulo.

Vamos criar uma tabela em seu banco de dados para usar nos exemplos desse capítulo. A aba Test da
conexão com o banco de dados permite você enviar sentenças SQL diretamente para o seu banco de
dados. Você pode criar tabelas digitando código SQL diretamente na aba Test; não há necessidade de
usar um SQL Method para criar tabelas. Crie uma tabela chamada employees com o seguinte código
SQL:

CREATE TABLE employees

(
emp_id integer,

first varchar,

last varchar,

salary float
)

Clique no botão Submit Query para rodar o commando SQL. O Zope deve retornar uma tela de
confirmação que diz à você o quê o código SQL rodou e o resultado, se houver algum.

A SQL usada aqui pode diferir dependendo do seu banco de dados. Para detalhes exatos de criação de
tabelas com seu banco de dados, consulte a documentação específica do usuário do banco de dados.

226 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Essa SQL criará uma nova tabela em seu banco de dados Gadfly, chamada employees. Essa tabela terá
quatro colunas, emp_id, first, last e salary. A primeira coluna é a identificação do empregado, que é um
único número que identifica o empregado. As próximas duas colunas tem tipo varchar que é similar à
uma string. A coluna salary tem tipo float que suporta números de ponto flutuante. Todos os bancos de
dados suportam espécies de tipos, então, consulte sua documentação para achar que espécies de tipos
seu banco de dados suporta.

Para garantir que a identificação do empregado é um único número você pode criar um índice em sua
tabela. Digite o seguinte código SQL na aba Test:

CREATE UNIQUE INDEX emp_id ON employees

(
emp_id
)

Agora você tem uma tabela e um ídice. Para examinar sua tabela, vá para a aba Browse. Esta aba deixa
você ver as tabelas de seu banco de dados e seus esquemas. Aqui, você pode ver que há uma tabela
employees, e se você clicar no símbolo de mais, (+) a tabela expande para mostrar quatro colunas,
emp_id, first, last e salary como mostra a Figura 10.4.

Figura 10.4 - Navegando na Conexão do banco de dados

Esta informação é muito útil quando se cria aplicações SQL complexas, com muitas tabelas grandes que
deixa você ver os esquemas de suas tabelas. Nem todos os bancos de dados suportam navegação em
tabelas.

Agora que você criou uma conexão de banco de dados e tem definida uma tabela, você pode criar Z SQL
Methods para operar em seu banco de dados.

Usando Métodos Z SQL


Os Z SQL Methods são objetos do Zope que executam código SQL através de uma Conexão de Banco de
Dados. Todos os Métodos Z SQL devem ser associados com uma Conexão de Banco de Dados. Z SQL
Methods podem tanto consultar bancos de dados quanto alterar dados. Z SQL Methods podem também
conter mais que um comando SQL.

Primeiro, você precisa criar um novo Z SQL Method chamado hire_employee que insere um novo
empregado na tabela employees. Quando um novo empregado é admitido, este método é chamado e um
novo registro é inserido na tabela employees que contém as informações sobre o novo empregado.

227 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Selecione Z SQL Method da Add List. Isto leverá você ao formulário de adição de Z SQL Methods, como
mostra a Figura 10.5.

Figura 10.5 - O formulário de adição para Z SQL Methods.

Como sempre, você deve especificar um id e um title para o Z SQL Method. Além disso, você precisa
selecionar uma Conexão de Banco de Dados para usar com este Z SQL Method. Dê à este novo método o
id hire_employee e selecione a Gadfly_database_connection que você criou na última seção.

Em seguida, você pode especificar argumentos para o Z SQL Method. Assim como Scripts, Z SQL
Methods podem ter argumentos. Argumentos são utilizados para construir expressões SQL. Neste caso
seu método necessita quatro argumentos, o número de identificação do empregado, o primeiro nome, o
último nome e salário do empregado. Degite "emp_id first last salary" no campo Arguments. Você pode
colocar cada argumento em sua própria linha, ou você pode colocar mais de um argumento na mesma
linha separados por espaços. Você pode também fornecer valores padrões para argumentos como mos
Scripts Python. Por exemplo, emp_id = 100 dá ao argumento do emp_id um valor padrão de 100.

O último campo do formulário é o Query template. Esse campo contém o código SQL que é executado
quando o Z SQL Method é chamado. Neste campo, entre com o seguinte código:

insert into employees (emp_id, first, last,salary) values


(<dtml-sqlvar emp_id type="int">,
<dtml-sqlvar first type="string">,
<dtml-sqlvar last type="string">,
<dtml-sqlvar salary type="float">
)

Note que este código SQL também contém DTML. O código do DTML neste modelo é utilizado para
inserir os valores dos argumentos dentro do código SQL que será executado em seu banco de dados.
Assim, se o argumento emp_id teve o valor 42, o argumento first teve o valor Bob e o seu argumento
last teve o valor Uncle e o argumento salary teve o valor 50000.00 então o modelo de query poderia
criar o seguinte código SQL:

Insert into employees (emp_id, first, last, salary) values


(42,
'Bob',
'Uncle',
50000.00
)

O modelo de query e SQL – especificamente tags DTML são explicadas melhor na próxima seção.

228 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Você tem à sua escolha três botões para clicar para adicionar seu novo Z SQL Method. O botão Add
criará o método e levará você de volta para o folder contendo o novo método. O botão Add and Edit
criará o método e o fará o objeto correntemente selecionado no Workspace. O botão Add and Test criará
o método que levará você a aba Test do método então você pode testar o novo método. Para adicionar
seu novo Z SQL Method, clique o botão Add.

Agora você tem um Z SQL Method que insere novos empregados na tabela employees. Você necessitará
outro Z SQL Method para consultar a tabela de empregados. Crie um novo Z SQL Method com o id
list_all_employees. Ele não deveria ter nenhum argumento e conter o código SQL:

select * from employees

Este simples código SQL seleciona todo as linhas da tabela employees. Agora você tem dois Z SQL
Methods, um para inserir novos empregados e um para ver todos os empregados no banco de dados.
Vamos testar seus dois novos métodos inserindo alguns novos empregados na tabela employees e
depois listando-os. Para fazer isto, clique no método hire_employees e clique na aba Test. Isto levará
você para a aba Test do método, como mostra a Figura 10.6.

Figura 10.6 - A aba Test do hire_employee.

Aqui, você vê um formulário com quatro caixas de entrada, uma para cada argumento para o Z SQL
Method hire_employee. O Zope gera automaticamente este formulário para você baseado nos
argumentos de seu Z SQL Method. Pelo fato do Método hire_employee ter quatro argumentos, o Zope
cria este formulário com quatro caixas de entrada. Você pode testar este método entrando com um
número de empregado, um primeiro nome, um último nome, e um salário para seu novo empregado.
Entre com o id do empregado "42", "Bob" para o primeiro nome, "McBob" para o último nome e um
salário de "50000.00". Então clique o botão Test. Você verá então os resultados de seu teste.

A tela diz This statement returned no results. Isto é porque o método hire_employee apenas insere
nova informação na tabela, isto não seleciona qualquer informação fora da tabela, assim não retornaram
registros. A tela também mostra à você como o modelo de query é renderizada no SQL. Como esperado,
as tags do DTML sqlvar renderizaram os quatro argumentos dentro do código válido da SQL que seu
banco de dados executou. Você pode adicionar tantos empregados quanto você quiser testando
repetidamente este método.

Para verificar que a informação que você adicionou está sendo inserida dentro da tabela, selecione o Z
SQL Method list_all_employees e clique em sua aba Test.

Esta visão diz This query requires no input, indicando que o list_all_employees não tem qualquer
argumento e assim, não requer entrada para executar. Clique no botão Submit Query para testar o
método.

229 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

O método list_all_employees retorna os conteúdos de sua tabela employees. Você pode ver todos os
novos empregados que você adicionou. O Zope automaticamente gera esta tela de relatório com tabela
para você. Em seguida nós mostraremos como você pode criar sua própria interface de usuário para
seus Z SQL Methods para integrá-los dentro do seu web site.

Chamando Métodos Z SQL

A pesquisa a um banco de dados relacional retorna uma sequência de resultados. Os itens na sequência
são chamados de linhas de resultado. Resultados de pesquisas em SQL são sempre uma sequência. Até
mesmo se a pesquisa da SQL retorna somente uma linha, aquela linha é o único item contido na lista de
resultados. Portanto, Z SQL Methods sempre retornam uma sequência de resultados que contêm zero
ou mais registros como resultado.

Os itens na sequência de resultados retornados por um Z SQL Method são chamados Result objects.
Result objects podem ser como as linhas da tabela do banco de dados transformadas em objetos do
Zope. Estes objetos têm atributos que ligam o esquema dos resultados do banco de dados.

Uma diferença importante entre result objects (objetos resultantes) e outros objetos do Zope é que os
objetos resultantes não foram criados e permanentemente adicionados ao Zope. Objetos resultantes
não são persistenes. Eles existem apenas por um curto período de tempo; tempo suficiente para você
usá-lo em uma página de resultado ou para usar seus dados para algum outro objetivo. Com o request
eles vão embora, e a próxima vez que você chamar um Z SQL Method você obtém um novo conjunto de
novos objetos resultantes.

Objetos resultantes podem ser usados do DTML para mostrar os resultados da chamada de um Z SQL
Method. Por exemplo, adicione um novo DTML Method ao seu site chamado listEmployees com o
seguinte conteúdo DTML:

<dtml-var standard_html_header>

<ul>
<dtml-in list_all_employees>
<li><dtml-var emp_id>: <dtml-var last>, <dtml-var first>
makes <dtml-var salary fmt=dollars-and-cents> a year.
</li>
</dtml-in>
</ul>

<dtml-var standard_html_footer>

Este método chama o Z SQL Method list_all_employees do DTML. A tag in é usada para interagir sobre
o objeto eachResult retornado pelo Z SQL Method list_all_employees. Z SQL Methods sempre retornam
uma lista de objetos, assim você irá quase sempre usá-los da tag DTML in a menos que você não esteja
interessado nos resultados ou se o código SQL nunca retornará nenhum resultado, como
hire_employee.

O corpo da tag in é um modelo que define o que é renderizado para cada objeto resultante na sequência
retornada pelo list_all_employees. No caso de uma tabela com três empregados, listEmployees deveria
retornar o seguinte HTML:

230 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<html>
<body>

<ul>
<li>42: Roberts, Bob
makes $50,000 a year.
</li>
<li>101: leCat, Cheeta
makes $100,000 a year.
</li>
<li>99: Junglewoman, Jane
makes $100,001 a year.
</li>
</ul>

</body>
</html>

A tag in renderiza uma lista de itens HTML para cada objeto resultante retornado pelo
list_all_employees.

Depois veremos como criar interfaces de usuário para coletar dados e passá-los para Z SQL Methods.

Fornecendo Argumentos para Métodos Z SQL

No outro tópico, você teve aprendeu a mostrar empregados com o DTML Method listEmployees que
chama o Z SQL Method list_all_employees. Agora vamos ver como construir uma interface de usuário
para o Z SQL Method hire_employee. Lembre-se que hire_employee aceita quatro argumentos, emp_id,
first, last, e salary. A aba Test no método hire_employee faz com que você chame este método, mas isto
não é muito útil para integração em uma aplicação web. Você precisa criar seu próprio formulário de
entrada de dados para seu Z SQL Method ou chamá-lo manualmente de sua aplicação.

A Z Search Interface pode criar um formulário de entrada de dados para você automaticamente. No
Capítulo 11, "Pesquisando e Categorizando Conteúdo", você usou a Z Search Interface para construir um
par form/action (formulário/ação) de métodos que automaticamente geraram um formulário HTML de
busca e a tela de relatório que pesquisou o Catálogo e retornou resultados. A Z Search Interface também
trabalha com Z SQL Methods para contruir um conjunto parecido de telas search/result
(busca/resultado).

Selecione Z Search Interface da lista de adição e especifique hire_employee como o objeto a ser
buscado. Entre com o valor "hireEmployee" para o Report Id e "hireEmployeeForm" para o Search Id de
clique Add.

Clique no hireEmployeeForm criado recentemente e clique na aba View. Entre com um employee_id,
um primeiro nome, um último nome, e salário para um novo empregado e clique em Submit. O Zope
retorna uma tela que diz "There was no data matching this query". Porque o formulário de relatório
gerado pela Z Search Interface tem objetivo de mostrar o resultado de um Z SQL Method, e o Z SQl
Method hire_employee não retorna nenhum resultado; ele apenas insere uma nova linha na tabela.
Edite o DTML Method hireEmployee um pouco para que fique mais informativo. Selecione o Method
hireEmployee. Ele deveria conter o seguinte trecho DTML:

231 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<dtml-in hire_employee size=50 start=query_start>

<dtml-if sequence-start>

<dtml-if previous-sequence>

<a href="<dtml-var URL><dtml-var sequence-query


>query_start=<dtml-var
previous-sequence-start-number>">
(Previous <dtml-var previous-sequence-size> results)
</a>

</dtml-if previous-sequence>

<table border>
<tr>
</tr>

</dtml-if sequence-start>

<tr>
</tr>

<dtml-sequence-end>

</table>
<dtml-if next-sequence>

<a href="<dtml-var URL><dtml-var sequence-query


>query_start=<dtml-var
next-sequence-start-number>">
(Next <dtml-var next-sequence-size> results)
</a>

</dtml-if next-sequence>

</dtml-if sequence-;end>

<dtml-else>

There was no data matching this <dtml-var title_or_id> query.

</dtml-in>

<dtml-var standard_html_footer>

Este é um pedaço bem grande do DTML! Todo este DTML é para construir dinamicamente um
formulário de resultado em forma de tabela em série. Já que não precisamos deste, vamos mudar o
método hireEmployee para que seja bem mais simples:

<dtml-var standard_html_header>

<dtml-call hire_employee>

<h1>Employee <dtml-var first> <dtml-var last> was Hired!</h1>

<p><a href="listEmployees">List Employees</a></p>

<p><a href="hireEmployeeForm">Back to hiring</a></p>

<dtml-var standard_html_footer>

Agora visualize hireEmployeeForm e coloque um novo empregado. Observe como o método


hire_employee é chamado da tag DTML call. Isto é porque sabemos que não há saídas no método
hire_employee. Já que não há resultados para interagir, o método não precisa ser chamado com a tag in.
Ele pode ser simplesmente chamado com a tag call.

Agora você tem uma interface de usuário completa para inserir novos empregados. Usando o sistema de

232 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

segurança do Zope, você pode agora restringir acesso a este método para um único grupo de usuários
que tem permissão de inserir novos empregados. Lembre-se sempre telas de pesquisa e relatório
geradas pela Z Search Interface são apenas ajudas que você pode facilmente adaptar para suas
necessidades.

Depois daremos uma olhada mais de perto no controle preciso das buscas SQL. Você já viu como Z SQL
Methods lhe permitem criar modelos básicos de buscas SQL. Na próxima seção você aprenderá como
fazer a maioria dos seus modelos de busca.

Pesquisas Dinâmicas com SQL


Um modelo de busca com Z SQL Method pode conter DTML que é avaliada quando o método é
chamado. Este DTML pode ser usado para modificar o código SQL que é executado pelo banco de dados
relacional. Várias SQL especificam tags DTML existentes para ajudar você na construção de buscas
complexas em SQL. Nas próximas seções você aprenderá sobre tags sqlvar, sqltest, e sqlgroup.

Inserindo Argumentos com a Tag Sqlvar

É muito importante ter certeza que você inseriu o tipo certo de dados dentro de uma coluna em um
banco de dados. Seu banco de dados vai reclamar se você tentar usar a string "12" onde o inteiro 12 for
esperado. SQL requer que diferentes tipos sejam especificados diferentemente. Para piorar, diferentes
bancos de dados têm diferentes regras de especificação.

Além disso, para evitar erros, a especificação da SQL é importante para a segurança. Suponha que você
tinha uma busca que faz um select:

select * from employees


where emp_id=<dtml-var emp_id>

Esta busca não é segura até que alguém possa colocar o código SQL dentro da sua busca entrando com
algo como 12; deixa a tabela empregados com um emp_id. Para evitar este problema você precisa
certificar-se que suas variáveis foram propriamente especificadas. A tag sqlvar faz isto para você. Aqui
está uma versão segura da busca acima que usa sqlvar:

select * from employees


where emp_id=<dtml-sqlvar emp_id type=int>

A tag sqlvar funciona similarmente a tag DTML regular var inserindo valores. Entretanto ela tem alguns
atributos da tag visadas na especificação de tipo da SQL, e se relacionando com valores nulos. A tag
sqlvar aceita vários argumentos:

name

O argumento name é idêntico ao argumento name da tag var. Este é o nome de uma varável do
Zope ou de um argumento do Z SQL Method. O valor da variável ou argumento é inserido dentro
do SQL Query Template. Um argumento name é exigido, mas o prefixo "name=" pode ser
omitido.

type

O argumento type determina o modo que a tag sqlvar deveria formatar o valor da variável ou
argumento a ser inserido no modelo de busca. Valores válidos para o tipo são string, int, float,
ou nb. nb é um valor não vazio e determina uma string com pelo menos um caracter nela. Um

233 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

argumento do tipo sqlvar é exigido.

optional

O argumento optional diz a tag sqlvar que a variável ou argumento pode não estar presente
como pode ser um valor nulo. Se a variável ou argumento não existe ou é um valor nulo, a tag
sqlvar não tenta renderizá-lo. O argumento optional da tag sqlvar é opcional.

O argumento type é a característica chave da tag sqlvar. Ele é responsável pela especificação correta da
variável inserida. Veja o Apêndice A para uma visão mais completa sobre a tag sqlvar.

Você deveria usar sempre a tag sqlvar ao invés da tag var quando inserir variáveis em um código SQL já
que ela especifica corretamente as variáveis e mantém seu SQL seguro.

Comparações de Igualdade com a Tag Sqltest

Muitas pesquisas SQL envolvem operações de comparação de igualdade. Estas são pesquisas que
pedem por todos os valores da tabela que estão em algum tipo de relação de igualdade com a entrada de
dados. Por exemplo, você pode querer buscar na tabela employees todos os empregados com um salário
maior que um certo valor.

Para ver como isto é feito, crie um novo Z SQL Method chamado employees_paid_more_than. Dê a ele
um argumento, salary, e o seguinte modelo SQL:

select * from employees


where <dtml-sqltest salary op=gt type=float>

Agora clique em Add and Test. O atributo da tag op é setado para gt, que fica como greater than. Este Z
SQL Method retornará somente registros de empregados que tem um salário maior que o aquele que
você colocou em seu formulário de entrada de dados. O sqltest constrói a sintaxe necessária da SQL para
comparar seguramente a entrada com a coluna da tabela. Digite "10000" no campo salary e clique o
botão Test. Como você pode ver a tag sqltest renderiza este código SQL:

select * from employees


where salary > 10000

A tag sqltest renderiza esta comparação do SQL levando em consideração o tipo da variável e as
particularidades do banco de dados. A tag sqltest aceita os seguintes parâmetros da tag:

name

O nome da variável a ser inserida.

type

O tipo do dado do valor a ser inserido. Este atributo é exigido e pode ser string, int, float, ou nb.
O tipo de dado nb é um valor não vazio e indica uma string que deve ter um tamanho que é maior
que 0. Quando usamos o tipo nb, a tag sqltest não vai renderizar se a variável é uma string vazia.

column

O nome da coluna da SQL, se for diferente do atributo name.

multiple

234 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Um flag indicando se valores múltiplos poedm ser fornecidos. Isto deixa você testar se a coluna é
um conjunto de variáveis. Por exemplo quando o name é uma lista de strings "Bob" , "Billy" ,
<dtml-sqltest name type="string" multiple> renderiza para esta SQL: name in ("Bob", "Billy").

optional

Um flag indicando se o teste é opcional. Se o teste for opcional e nenhum valor é oferecido para
uma variável então nenhum texto é inserido. Se o valor é uma string vazia, então nenhum texto
será inserido somente se o tipo for nb.

op

Um parâmetro usado para escolher o operador de comparação que é renderizado. As


comparações são: eq (igual a), gt (maior que), lt (menor que), ge (maior que ou igual a), le
(menor que ou igual a), e ne (diferente de).

Veja o Apêndice A para maiores informações sobre a tag sqltest. Se seu banco de dados suporta
operadores de comparação adicionais tais como like você pode usá-lo com a sqlvar. Por exemplo se
name é a string "Mc%", o código SQL:

<dtml-sqltest name type="string" op="like">

renderizado para:

name like 'Mc%'

A tag sqltest ajuda você construir buscas SQL corretas. Em geral suas buscas serão mais flexíveis e
funcionarão melhor com diferentes tipos de entrada e diferentes bancos de dados se você usar sqltest
particularmente controlando comparações de código.

Criando Pesquisas Complexas com a Tag Sqlgroup

A tag sqlgroup deixa você criar buscas com SQL que suportam uma quantia variável de argumentos.
Baseados em argumentos específicos, buscas com SQL podem ser mais específicas oferecendo mais
argumentos, ou menos específicas oferecendo menos ou nenhum arumento.

Aqui está um exemplo de uma busca com SQL inadequada:

select * from employees

Aqui está um exemplo de uma busca com SQL adequada para salário:

select * from employees


where(
salary > 100000.00
)

Aqui está um exemplo de uma busca com SQL adequada para salário e primeiro nome:

235 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

select * from employees


where(
salary > 100000.00
and
first in ('Jane', 'Cheetah', 'Guido')
)

Aqui está um exemplo de uma busca com SQL adequada para um primeiro e último nome:

select * from employees


where(
first = 'Old'
and
last = 'McDonald'
)

Todos estas três buscas podem ser efetuadas com um Z SQL Method que cria mais buscas específicas
com SQL como mais argumentos são especificados. O seguinte modelo de SQL pode construir as três
buscas acima:

select * from employees


<dtml-sqlgroup where>
<dtml-sqltest salary op=gt type=float optional>
<dtml-and>
<dtml-sqltest first op=eq type=nb multiple optional>
<dtml-and>
<dtml-sqltest last op=eq type=nb multiple optional>
</dtml-sqlgroup>

A tag sqlgroup renderiza a string where se os conteúdos da tag body contém qualquer texto e constrói
as espressões qualificadas dentro da query. Esta tag sqlgroup não renderizará a clausula where se os
argumentos não estiverem presentes.

A tag sqlgroup consiste de três blocos separados por tags and. Estas tags inserem a string amd se o
final do bloco renderiza um valor. Deste modo o número correto de ands é incluído na busca. Quanto
mais argumentos forem epecificados, mais expressões de qualificação serão adicionadas na busca. Neste
exemplo, expressões de qualificação restringem a pesquisa com tags and, mas tags or podem também
ser usadas para expandir a pesquisa.

Este exemplo mostra também atributos múltiplos nas tags sqltest. Se o primeiro ou segundo valores for
uma lista, então a SQL da direita é renderizada para especificar um grupo de valores ao invés de um
valor único.

Você também pode colocar tags sqlgroup uma dentro da outra. Por exemplo:

select * from employees


<dtml-sqlgroup where>
<dtml-sqlgroup>
<dtml-sqltest first op=like type=nb>
<dtml-and>
<dtml-sqltest last op=like type=nb>
</dtml-sqlgroup>
<dtml-or>
<dtml-sqltest salary op=gt type=float>
</dtml-sqlgroup>

Exemplos de argumentos, este modelo renderiza SQL assim:

236 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

select * from employees


where
( (first like 'A%'
and
last like 'Smith'
)
or
salary > 20000.0
)

Você pode construir expressões SQL muito complexas com a tag sqlgroup. Para um simples código SQL
você não precisa usar a tag sqlgroup. Entretnto, se você se vê criando vários Z SQl Methods diferentes
mas relacionados você deveria ver se você não pode fazer a mesma coisa com um método que usa a tag
sqlgroup.

Técnicas Avançadas
Anteriormente você viu como se conectar a um banco de dados relacional, enviando-o buscas e
comandos, e criando uma interface de usuário. Estes são os fundamentos básicos para a conexão com
um banco de dados no Zope.

Nas seções seguintes você verá mais de perto como integrar com o Zope suas buscas relacionais e como
aumentar a performance. Vamos começar olhando como passar argumentos para os Z SQL Methods
especificando-os e por aquisição. Então você verá como você pode chamar Z SQL Methods diretamente
das URLs usando a passagem para objetos resultantes. Depois você verá como deixar os objetos
resultantes mais poderosos ligando-os com as classes. Enfim, veremos sobre cacheamente para
melhorar a performance e como o Zope controla as transações com bancos de dados.

Chamando Métodos Z SQL com Argumentos Explícitos

Se você chama um Z SQL Method sem argumento do DTML, os argumentos são automaticamente
coletados do ambiente. Esta é a técnica que usamos anteriormente neste capítulo. Ela funciona bem
quando você quer pesquisar um banco de dados de um formulário de busca, mas algumas vezes você
quer manualmente ou programaticamente pesquisar um banco de dados. Z SQL Methods podem ser
chamados com argumentos explícitos do DTML ou Python. Por exemplo, para buscar o Z SQL Method
employee_by_id manualmente, o seguinte DTML pode ser usado:

<dtml-var standard_html_header>
<dtml-in expr="employee_by_id(emp_id=42)">
<h1><dtml-var last>, <dtml-var first></h1>

<p><dtml-var first>'s employee id is <dtml-var emp_id>. <dtml-var


first> makes <dtml-var salary fmt=dollars-and-cents> per year.</p>
</dtml-in>

<dtml-var standard_html_footer>

Lembre-se, o método employee_by_id retorna somente um registro, assim o corpo da tag in neste
método executará somente uma vez. No exemplo você chama o Z SQL Method como qualquer outro
método e passa para ele um argumento keyword (palavra chave) para emp_id. O mesmo pode ser feito
facilmente para Python:

## Script (Python) "join_name"


##parameters=id
##
for result in context.employee_by_id(emp_id=id):
return result.last + ', ' + result.first

237 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Este script aceita um argumento de identificação e passa-o para employee_by_id como o emp_id
argument. Ele então interage com o resultado único e junta o último nome e o primeiro nome com uma
vírgula.

Você pode oferecer mais controle sobre seus dados relacionais chamando os Z SQL Methods com
argumentos específicos. Também merece ser frisado que Z SQL Methods podem ser chamados do
DTML e Python com argumentos específicos como você chama outros métodos do Zope.

Adquirindo Argumentos Através de Outros Objetos

Z SQL pode adquirir informação sobre outros objetos e ser usado para modificar a busca com SQL.
Considere a Figura 10.7, que mostra uma coleção de Pastas no web site de uma organização.

Figura 10.7 - Estrutura de Pastas do web site de uma organização.

Suponha que cada pasta dos departamentos tem uma propriedade string department_id que identifica
o id do livro de contabilidade para aquele departamento. Esta propriedade poderia ser usada por um Z
SQL Method compartilhado a infromações sobre a busca apenas para aquele departamento. Para
ilustrar, crie vários folders um dentro do outro com diferentes propriedades string department_id e
então crie um SQL Method com o id requisition_something no folder raiz que tem três argumentos,
description, quantity, e unit_cost e o seguinte modelo de busca:

INSERT INTO requisitions


(
department_id, description, quantity, unit_cost
)
VALUES
(
<dtml-sqlvar department_id type=string>,
<dtml-sqlvar description type=string>,
<dtml-sqlvar quantity type=int>,
<dtml-sqlvar unit_cost type=float>
)

Agora crie uma Z Search Interface com um Search Id "requisitionSomethingForm" e o Report id


"requisitionSomething". Selecione o Z SQL Method requisition_something como o Searchable Object e
clique Add.

Edite o requisitionSomethingForm e remova a primeira caixa de entrada para o campo department_id.


Nós não queremos que o valor de department_id venha do formulário, queremos que venha de uma
propriedade que é adquirida.

Agora, você deveria ser capaz de ir a URL:

http://example.org/Departments/Support/requisitionSomethingForm

e requisitar algumas mochilas do departamento Support. Você também poderia ir para:

238 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

http://example.org/Departments/Sales/requisitionSomethingForm

E requisitar algumas tacky rubber key−chains com seu logo nelas para o departamento Sales. Usando o
sistema de segurança do Zope como descrito no Capítulo 7, "Usuários e Segurança", você pode agora
restringir acesso a estes formulários assim o pessoal dos departamentos pode requisitar itens apenas
para seus departamentos e de nenhum outro.

O interessante sobre este exemplo é que department_id não era um dos argumentos oferecidos para a
pesquisa. Ao invés de obter o valor desta variável de um argumento, ele adquire o valor da pasta onde o
Z SQL Method é acessado. No caso das URLs acima, o Z SQL Method requisition_something adquire o
valor das pastas Sales e Support. Isto permite que você adecue as pesquisas com SQL para diferentes
necessidades. Todos os departamentos podem compartilhar uma busca mas ela é padronizada para
cada departamento.

Usando aquisição e argumento específico você pode adequar suas pesquisas SQL a suas aplicações web.

Cruzando os Resultados dos Objetos

Anteriormente voccê forneceu argumentos para os Z SQL Methods dos formulários da web, argumentos
específicos, e aquisição. Você também pode oferecer argumentos para Z SQL Methods chamando-os da
web com URLs especiais. Isto é chamado traversing (cruzamento) para objetos resultantes. Usando
esta técnica você pode ir diretamente aos objetos resultantes usando URLs.

Para cruzar objetos resultantes com URLs, você deve ser capaz de assegurar que o SQL Method
retornará somente um objeto resultante dando um argumento. Por exemplo, crie um novo Z SQL
Method chamado employee_by_id que aceita um argumento, emp_id, e tem o seguinte Modelo SQL:

select * from employees where


<dtml-sqltest emp_id op=eq type=int>

Este método seleciona um empregado fora da tabela employees baseado no seu id de empregado. Já que
cada empregado tem um único id, somente um registro será retornado. Bancos de dados relacionais
podem oferecer estes tipos de garantias de exclusividade.

Zope oferece uma sintaxe de URL especial para acessar ZSQL Methods que sempre retorna um
resultado único. A URL consiste da URL do ZSQL Method seguido pelo nome do argumento seguido
pelo valor do argumento. Por exemplo, http://localhost:8080/employee_by_id/emp_id/42. Observe,
esta URL retornará um único objeto como resultado onde se você pesquisou o ZSQL Method do DTML e
passou para ele um argumento único ele poderia retornar uma lista de resultados que happend para
somente ter um item nele.

Infelizmente o objeto resultante que você obteve com esta URL não é muito interessante para estudar.
Não há como mostrá-la em HTML. Você ainda precisa mostrar o objeto resultante. Para fazer isto, você
pode chamar um DTML Method no objeto resultante. Isto pode ser feito usando as regras normais de
aquisição da URL descritas no Capítulo 10, "Script Avançado em Zope". Por exemplo, considere a
seguinte URL:

http://localhost:8080/employee_by_id/emp_id/42/viewEmployee

Aqui vemos o Z SQl Method employee_by_id passar o argumento emp_id por URL. O método
viewEmployee é então chamado no objeto resultante. Vamos criar um DTML Method viewEmployee e
testá-lo. Crie um novo DTML Method chamado viewEmployee e dê a ele o seguinte conteúdo:

239 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>

<h1><dtml-var last>, <dtml-var first></h1>

<p><dtml-var first>'s employee id is <dtml-var emp_id>. <dtml-var


first> makes <dtml-var salary fmt=dollars-;and-cents> per year.</p>

<dtml-var standard_html_footer>

Agora quando você for para a URL http://localhost:8080/employee_by_id/emp_id/42/viewEmployee


o DTML Method viewEmployee é ligado ao objeto resultante que é retornado pelo employee_by_id. O
método viewEmployee pode ser usado como um modelo genérico usado por diferentes Z SQL Methods
que retornam registros de empregados.

Já que o método employee_by_id aceita somente um argumento, ele não precisa especificar emp_id na
URL para qualificar o argumento numérico. Se seu Z SQL Method tem um argumento, então você pode
configurar o Z SQL Method para aceitar somente um argumento extra do elemento para o caminho ao
invés de alguns argumentos. Este exemplo pode ser mais simplificado selecionando o Z SQL Method
employee_by_id e clicando na aba Advanced. Aqui, você pode ver uma check box chamada Allow
"Simple" Direct Traversal. Selecione esta caixa e clique em Change. Agora, você pode navegar no
registro dos empregados com uma URL mais simples http://localhost:8080/employee_by_id
/42/viewEmployee. Observe como nenhum emp_id qualificatico é delcarado na URL.

Cruzamentos oferecem um jeito fácil de oferecer argumentos e ligar métodos a Z SQL Methods e seus
resultados. Depois vamos mostrar a você como ligar o conjunto de classes a objetos resultantes e
torná-los mais poderosos.

Ligando Classes com os Objetos Resultantes

Um objeto resultante tem um atributo para cada coluna nas linhas resultantes. Entretanto, objetos
resultantes não tem nenhum método, apenas atributos.

Existem duas maneiras de ligar um método a um objeto resultante. Como você viu na seção anterior,
você pode ligar DTML e outros métodos a objetos resultantes de Z SQL Method usando cruzamento
para os objetos resultantes unidos com a URL normal baseada no mecanismo de ligamento por
aquisição descrito no Capítulo 10, "Scripts Avançados em Zope". Você pode também ligar métodos a
objetos resultantes definindo uma classe Python que se misturou com a classe do objeto resultante
normal e simples. Estas classes são definidas no mesmo local dos External Methods no sistema de
arquivos, no Extensions. As classes do Python são coleções de métodos e atributos. Associando uma
classe com um objeto resultante, você pode fazer com que o objeto resultante tenha uma rica API e
interfaces de usuário.

Classes usadas para ligar métodos e outros atributos da classe a classes resultantes são chamadas de
Pluggable Brains, ou apenas Brains. Considere o exemplo da classe em Python:

class Employee:
def fullName(self):
""" The full name in the form 'John Doe' """
return self.first + ' ' + self.last

Quando objetos resultantes com esta classe Brains são criadas como resultado de uma busca em um Z
SQL Method, os objetos resultantes terão Employee como uma classe base. Isto significa que os objetos
registro terão todos os métodos definidos na classe Employee, dando-as comportamento, bem como
dados.

Para usar esta classe, crie a classe acima no arquivo Employee.py no diretório Extensions. Vá para a aba

240 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Advanced do Z SQl Method employee_by_id e digite Employee no campo Class Name, e Employee no
campo Class File e clique Save Changes. Agora você pode editar o DTML Method employeeView para
conter:

<dtml-var standard_html_header>

<h1><dtml-var fullName></h1>

<p><dtml-var first>'s employee id is <dtml-var emp_id>. <dtml-var


first> makes <dtml-var salary fmt=dollars-and-cents> per year.</p>

<dtml-var standard_html_footer>

Agora quando você fpr a URL http://localhost:8080/employee_by_id/42/viewEmployee o método


fullName é chamado pelo DTML Method viewEmployee. O método fullName é definido em uma classe
Employee do módulo Employee e é ligado ao objeto resultante retornado pelo employee_by_id.

Brains oferece uma facilidade muito poderosa que permite que você trate seus dados relacionais de um
modo que centralize o objeto. Por exemplo, você não apenas pode acessar o método fullName usando
cruzamento direto, mas você pode usá-lo em qualquer lugar que você estiver controlando ojetos
resultantes. Por exemplo:

<dtml-in employee_by_id>
<dtml-var fullName>
</dtml-in>

Para todos os objetivos práticos seu Z SQL Method retorna uma sequência de objetos espertos, não
apenas dados.

Este exemplo somente mostra um pouco do que pode ser feito com as classes Brains. Programaçao em
Python está além do escopo deste livro assim mostraremos poucas coisas aqui. Entretanto, você poderia
criar classes brains que acessam recusrsos da rede, chamam outros Z SQL Methods, executam todos os
tipos de lógica de aplicação.

Aqui está um exemplo mais poderoso de brains. Suponha que você tem uma tabela managers para ir
com a tabela employees que você já usou antes. Suponha também que você tem um Z SQL Method
manager_by_id que retorna um id do administrador dando um argumento emp_id:

select manager_id from managers where


<dtml-sqltest emp_id type=int op=eq>

Você poderia usar este Z SQL Method em sua classe brains assim:

class Employee:

def manager(self):
"""
Returns this employee's manager or None if the
employee does not have a manager.
"""
# Calls the manager_by_id Z SQL Method.
records=self.manager_by_id(emp_id=self.emp_id)
if records:
manager_id=records[0].manager_id
# Return an employee object by calling the
# employee_by_id Z SQL Method with the manager's emp_id
return self.employee_by_id(emp_id=manager_id)[0]

Esta classe Employee mostra como métodos podem usar outros objetos do Zope para tecer juntos

241 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

dados relacionais para fazer com que pareçam com uma coleção de objetos. O método manager chama
dois Z SQL Methods, um para calcular o emp_id do administrador de empregados, e outro para
retornar um novo objeto resultante representanteo o administrador. Você pode agora tratar objetos
empregados como se eles tivesse simples referências a seus objetos administrador. Por exemplo você
poderia adicionar algo como este DTML Method viewEmployee:

<dtml-if manager>
<dtml-with manager>
<p> My manager is <dtml-var first> <dtml-var last>.</p>
</dtml-with>
</dtml-if>

Como você pode ver brains podem ser ambos complexos e poderosos. Quando estiver projetando
aplicações para banco de dados relacionais você deveria tentar manter as coisas simples e adicionar a
complexidade aos poucos. É importante ter certeza de que suas classes brains não adicionam muitas
sobrecargas desnecessárias.

Cacheando Resultados

Você pode qumentar a performance de suas buscas com SQL usando o cacheamento. Cacheamento
armazena resultados dos Z SQL Method assim se você chama algum método com os mesmo argumentos
frequentemente, você não precisará se conectar ao banco de dados toda vez. Dependendo de sua
aplicação, pode aumentar drasticamente a sua performance.

Para controlar o cacheamento, vá até a aba Advanced de um SQL Method. Você tem três diferentes
controles de cache como mostra a Figura 10.8.

Figura 10.8 - Cacheando controle para Z SQL Methods

O campo Maximum number of rows received controla quantos dados cachear para cada busca. O campo
Maximum number of results to cache controla quantas buscas cachear. O Maximum time (in seconds)
to cache results controla quanto tempo buscas cacheadas são salvas por segundo. Em geral, quanto mais
você seta estes valores mais aumenta sua performance, mas mais memória o Zope irá consumir. Como
qualquer direcionamento de performance, você deveria tentar achar a melhor configuração para sua
aplicação.

Em geral você vai querer setar os resultados máximos para a cache como grandes o suficiente e o tempo
máximo para a cache como tempo suficiente para sua aplicação. Para sites com poucos hits você poderia
cachear resultados com tempos distantes, e para sites com muitos hits você deveria cachear resultados
em um curto período de tempo. Para máquinas com bastante memória você deveria aumentar o número
de resultados cacheados. Para desativar o cacheamento configure o tempo da cache para zero segundos.

242 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Para a maioria das buscas, o valor default adequado é de 1000 para o maximum number of rows
retrieved. Para buscas extremamente grandes você pode ter que aumentar este número para devolver
todos os seus resultados.

Transações

Uma transação é um grupo de operações que podem ser desfeitas todas de uma vez. Como você viu no
Capítulo 1, "Introduzindo o Zope", todas as mudanças feitas no Zope são feitas dentro de transações.
Transações garantem a integridade dos dados. Quando estamos usando um sistema que não é
transacional e uma de suas ações web mudam dez objetos, e então falha a mudança de número onze,
seus dados estão agora inconsistentes. As transações permitem que você reverta todas as mudanças
que você fez durante um request se um erro ocorrer.

Imagine o caso onde você tem uma página web que fatura as mercadorias de um cliente. Esta página
primeiro subtrai as mercadorias do inventário, e então subtrai a quantia da conta do cliente. Se a
segunda operação falha por alguma razão você quer ter certeza que a mudança no inventário não foi
efetivada.

A maioria dos bancos de dados relacionais comerciais e de código aberto suportam transações. Se seu
banco de dados relacional suporta transações, o Zope certificar-se-a que elas estão bem amarradas as
transações do Zope. Isto garante a integridade dos dados entre seu banco de dados relacional e o Zope.
Se tanto o Zope quanto seu banco de dados relacional abortar a transação, a transação inteira é
abortada.

Resumo
O Zope permite que você construa aplicações web com banco de dados relcionais. Diferente de muitos
servidores de aplicações para web, o Zope tem seu próprio banco de dados objeto e não exige o uso de
bancos de dados relacionais para armazenar informações.

O Zope deixa você usar dados relacionais apenas como você usa outros objetos do Zope. você pode
conectar seus dados relacionais a lógicas de aplicação com scripts e brains, você pode buscar seus dados
relacionais com Z SQL Methods e ferramentas de apresentação como DTLM, e você pode até mesmo
usar características avançadas do Zope como cruzamento de URL, aquisição, cancelamento e segurança
enquanto trabalha com dados relacionais.

14. Escalabilidade e ZEO


Este capítulo mostra consequências e soluções para construir e manter grandes
aplicações para a web, e enfoca resultados de gerenciamento e escalabilidade. Em
particular, o Zope Enterprise Option (ZEO) é mostrado detalhadamente. Este capítulo
mostra a você as ferramentas e técnicas que você precisa para transformar um site
pequeno em um site de larga escala, prestado serviço a milhões de visitantes.

Quando um site da Web recebe mais pedido do que pode suportar ele pode tornar-se lento e não
responder. No pior caso muitos pedidos feitos a um web site podem causar ao servidor uma sobrecarga
completa, interrupção do controle de solicitações e possivelmente até travar. Este pode ser um
problema para qualquer tipo de servidor de aplicação, mas não para o Zope. A solução óbvia para este
problema é usar mais de um computador, caso um computador falhar, o outro computador pode
continuar servindo seu site na Web.

Usar vários computadores obviamente tem seus benefícios, mas isto também tem alguns

243 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

inconvenientes. Por exmplo, se você tivesse cinco computadores rodando Zope então você deve
assegurar que todas as cinco intalações do Zope tenham as mesmas informações. Esta não é uma tarefa
muito difícil se você for o único usuário e você tiver somente alguns objetos estáticos, mas para grandes
organizações com milhares de objetos mudando rapidamente, manter cinco intalações separadas do
Zope sincronizadas manualmente seria um pesadelo. Para resolver este problema, a Zope Corporation
criou o Zope Enterprise Objects , ou ZEO. Este capítulo dá a você uma breve visão da instalação do ZEO,
mas existem muitas outras opções que não mostraremos. Para uma informação mais aprofundada veja a
documentação que vem com o pacote do ZEO, e também dê uma olhada na área de discusão do ZEO.

O que é ZEO?
ZEO é um sistema que permita que você rode seu site em mais de um computador. Isto é chamado
frequentemente de clustering (escalabilidade) e load balancing (equilíbrio da carga). Rodando o Zope
em vários computadores, você pode propagar os pedidos igualmente por todos os lados e adicionar
mais computadores quando aumentar a quantia de pedidos. Mais, se um computador falhar ou travar,
outros computadores podem ainda servir os pedidos enquanto você reparar a falha.

O ZEO roda o Zope em vários computadores e cuida para que todas as instalações do Zope
compartilhem o mesmo banco de dados todas as vezes. ZEO usa uma arquitetura cliente/servidor. As
intalações do Zope em vários computadores são os ZEO Clients (Clientes do ZEO). Todos os clientes se
conectam a um, ZEO Storage Server (Servidor Central de Armazenamento do ZEO), como mostra a
Figura 11.1.

Figura 11.1 - Ilustração simples do ZEO.

A terminologia pode ser um pouco confusa, porque normalmente você pensa no Zope com um servidor,
não como um cliente. Ao usar ZEO, os processo do Zope atuam como servidores (para pedidos da Web)
e clientes (para dados do servidor ZEO).

Os clientes e os servidores do ZEO comunicam-se usando protocolos padrão da Internet, assim podem
estar no mesmo lugar ou em diferentes paises. ZEO, na realidade, pode distribuir um site do Zope por
todo o mundo. Neste capítulo nós exploraremos algumas maneiras interessantes em que você pode
distribuir seus clientes ZEO.

Quando você deve usar ZEO

244 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

O ZEO serve muitos hits de uma maneira bem segura. Se seu site não tem milhões de hits, então
provavelmente você não precisará do ZEO. Não há regras específicas para saber quando você deveria ou
não deveria usar o ZEO, mas para a maior parte você não precisaria rodas o ZEO a menos que:

Seu site está recebendo muitos hits para seu computador gerenciá-los rapidamente. Zope é um
sistema de alta performance, e um Zope pode gerenciar milhões de hits por dia (dependendo de
seu hardware, é claro). Se você precisa servir mais hits do que isto, então você deveria usar o
ZEO.
Seu site está muito crítico e requer constante funcionamento, 24 horas por dia. Nesse caso, ZEO
permitirá que você tenha vários servidores resistentes a falhas.
Você quer distribuir seu site globalmente para diferentes mirrors clientes do ZEO.
Você quer debugar um cliente do ZEO enquanto outros servem os pedidos. Esta é uma técnica
muito avançada para colaboradores de Python e não é mostrado neste livro.

Todos estes casos são bastante avançados, de alta capacidade de uso do Zope. Instalar, configurar, e
manter sistemas como este requerem conhecimentos e recursos avançados sobre administração de
sistema. A maioria dos usuários de Zope não precisarão do ZEO, ou não podem ter a perícia necessária
para manter um sistema distribuído do servidor como ZEO. ZEO é divertido, e pode ser muito útil, mas
antes de arriscar e instalar ZEO em seu sistema você deveria decidir a sobrecarga administrativa extra
que o ZEO cria contra a simplicidade de rodar apenas o Zope sozinho.

Instalando e Rodando ZEO


A configuração mais comun do ZEO é um servidor e vários clientes do ZEO. Antes de instalar e
configurar ZEO de qualquer forma, considere os seguintes tópicos:

Todos os clientes e servidores do ZEO devem rodar a mesma versão do Zope. Certifique-se que
todos seus computadores usam a última versão. Isto é necessário, ou o Zope pode comportar-se
anormalmente ou não funcionar de nenhuma maneira.
Todos os seus clientes ZEO devem ter os mesmos Produtos externos instalados e eles devem ser
a mesma versão. Isto é necessário, ou os objetos externos podem comportar-se anormalmente
ou não trabalhar de nenhuma maneira.
Se o seu sistema Zope requer acesso a recursos externos do Zope, como servidor de e-mail ou
banco de dados relacional, assegure que todos os seus cliente ZEO possuem acesso a estes
recursos.
As conexões de rede lentas ou interrompidas entre clientes e servidores degradam o
desempenho de seus clientes ZEO. Os clientes ZEO deveriam ter uma conexão boa com seu
servidor.

ZEO não é distribuído com o Zope, você deve baixá-lo da Secção de Produtos do Zope.org.

Instalar ZEO requer um pouco de preparação manual. Para instalar o ZEO faça o download do
ZEO-1.0.tgz do site Zope.org e coloque no diretório de instalação do seu Zope. Agora, desempacote o
tarball. No Unix, iste pode ser feito com o seguinte comando:

$ tar -zxf ZEO-1.0.tgz

No Windows, você pode descompactar o arquivo com o WinZip. Antes de instalar o ZEO, certifique-se
que você fez uma cópia de segurança do seu sistema Zope.

Agora você deveria ter um diretório ZEO-1.0. Depois, você tem que copiar alguns arquivos no diretório
lib/python no nível mais alto do Zope. Isto pode ser feito em UNIX com:

$ cp -R ZEO-1.0/ZEO lib/python

245 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Se você está rodando o windows, você pode usar os seguintes comandos do DOS para copiar seus
arquivos ZEO:

C:\...Zope\>xcopy ZEO-1.0\* lib\python /S

Agora, você tem que criar um arquivo especial no diretório raiz do Zope chamado custom_zodb.py.
Neste arquivo coloque o seguinte código Python:

import ZEO.ClientStorage
Storage=ZEO.ClientStorage.ClientStorage((localhost,7700))

Isto configurarará o Zope para rodar como um cliente ZEO. Se você passar a ClientStorage uma tupla,
como este código faz, a tupla deve ter dois elementos, uma string que contém o endereço para o
servidor, e a porta que o servidor está respondendo. Neste exemplo, vamos mostrar-lhe como rodar
ambos os clientes e os servidores na mesma máquina, o nome da máquina é setado para localhost.

Agora, você tem o ZEO configurarado para rodar em um computador. Teste primeiramente iniciando o
servidor. Vá para o diretório de nível superior do Zope em um terminal windows ou DOS e digite:

python lib/python/ZEO/start.py -p 7700

Isto fará com que o servidor ZEO comece respondendo na porta 7700 do seu computador. Agora, em
outra janela, inicie o Zope como você normalmente faria, com o script z2.py:

$ python z2.py -D

------
2000-10-04T20:43:11 INFO(0) client Trying to connect to server
------
2000-10-04T20:43:12 PROBLEM(100) ZServer Computing default pinky
------
2000-10-04T20:43:12 INFO(0) ZServer Medusa (V1.19) started at Wed Oct 4 15:43:12 2000
Hostname: pinky.zopezoo.org
Port:8080

Observe como no exemplo acima, o Zope diz a você client Trying to connect to server e então
ClientStorage Connected to storage. Isto significa que seu cliente ZEO conectou-se com sucesso a seu
servidor ZEO. Agora, você pode visitar http://localhost:8080/manage (ou qualquer URL que seu
cliente ZEO estiver escutando) e logue no Zope como sempre.

Como você pode ver, tudo tem a mesma aparência. Vá ao Control Panel e click em Database
Managment. Aqui, você vê que o Zope está conectado a um ZEO Storage e que seu estado está
connected.

Rodar o ZEO em um computador é uma boa maneira de familiarizar-se com o ZEO saber como ele
funciona. Entretanto, rodar o ZEO em um computador não melhora a velocidade de seu site, e de fato,
pode retardá-lo um pouco. Para realmente obter os benefícios de velocidade que o ZEO oferece, você
precisa rodar o ZEO em diversos computadores, o que é explicado próxima seçcão.

Como Rodar ZEO em Vários Computadores


É muito parecido configurar o ZEO para rodar em vários computadores e rodar em apenas um
computador. Existem geralmente dois passos, o primeiro passo é iniciar o servidor ZEO, e o segundo

246 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

passo é iniciar um ou mais clientes ZEO.

Por exemplo, digamos que você tem quatro computadores. Um computador chamado zooserver será o
seu servidor ZEO, e os outros três computadores, chamados zeoclient1, zeoclient2 e zeoclient3, serão
seus clientes ZEO.

O primeiro passo é rodar o servidor no zooserver. Para dizer ao seu servidor ZEO escutar no socket tcp
na porta 9999 na interface zooserver, rode o servidor com este script start-py:

$ python lib/python/ZEO/start.py -p 9999 -h zooserver.zopezoo.org

Isto irá iniciar o servidor ZEO. Agora, você pode iniciar seus clientes indi em cada cliente e
configurarando cada um deles com os seguintes custom_zodb.py:

import ZEO.ClientStorage
Storage=ZEO.ClientStorage.ClientStorage((zooserver.zopezoo.org,9999))

Agora, você pode iniciar cada script z2.py do cliente como mostra na seção anterior, Instalando e
Rodando ZEO. Observe como o host e porta para cada cliente é a mesma, é por isso que todos se
conectam com o mesmo servidor. Seguindo esses procedimentos para cada um dos três clientes você
terá três diferentes instalações do Zope todas servindo o mesmo site Zope. Você pode verificar isto indo
para a porta 8080 em todos as três máquinas clientes do seu ZEO.

Você provavelmente quer rodar o ZEO em mais de um computadorassim você pode tirar vantagem do
aumento da velocidade que vai ser proporcionado. Rodar em mais computadores significa que você
pode servir mais hits por segundo que com somente um computador. Distribuir a carga de seus
visitantes entretanto requer um pouco mais de elaboração do seu sistema. A próxima seção descreve
porque, e como, você distribui a carga de seus visitantes entre muitos computadores.

Como Distribuir a Carga


No exemplo anterior você possui um servidor ZEO chamado zooServer e três clientes ZEO chamados
zeoclient1, zeoclient2 e zeoclient3. Os três clientes ZEO estão conectados ao servidor ZEO e cada cliente
está verificado para funcionar corretamente.

Agora você possui três computadores que servem conteúdo a seus usuários. O próximo problema é
como atualmente propagar os pedidos vindos da web entre os três clientes ZEO. Seus usuários apenas
sabem sobre o www.zopezoo.org, não sobre zeoclient1, zeoclient2 ou zeoclient3. Isto poderia ser uma
discussão dizer que alguns usuários usem o zeoclient1 e outros usem o zeoclient3, e isto não seria muito
bom usar seus recursos de computação. Você quer mecanizar, ou pelo menos tornar simples, o processo
de distribuição dos pedidos a seus vários clientes ZEO.

Existe várias soluções para este problema, algumas fáceis, algumas avançadase, e outras caras. A seção
seguinte vai discutir sobre as manieras mais comuns de espalhar pedidos do Web para vários
computadores usando tipos diferentes de tecnologia, alguns deles baseados em softwares livres
disponíveis ou comerciais, e alguns deles baseados em hardware especial.

Usuário Escolhe um Espelhamento

A maneira mais fácil de distribuir pedidos por vários servidores web é escolher da lista de sites mirrored
(espalhados), cada um destes é um cliente ZEO. Usar este método não requer software e hardware
extras, apenas requer manutenção de uma lista de servidores mirror. Apresentando a seus usuários um
menu de mirrors, eles podem usar para escolher que servidor usar.

247 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Note que este método de distribuição de pedidos é passiva (você não tem controle sobre que clientes
estão usando) e voluntário (seus usuários precisam fazer uma escolha voluntária para usar outro cliente
ZEO). Se seus usuários não usam mirror, então seus pedido vão para seu cliente ZEO que serve
www.zopezoo.org.

Se você não tem nenhum controle administrativo sobre seus mirrors, então esta pode ser uma solução
bem fácil. Se seus mirrors estiverem off-line, seus usuários podem sempre escolher voltar ao site
principal que você tem controle administrativo e escolher um mirror diferente.

De um modo geral, este método melhora a performance. Seus usuários podem escolher um servidor que
está geograficamente perto deles, que provavelmente resulta em acessos mais rápidos. Por exemplo, se
o seu servidor principal está em Portland, Oregon na costa oeste dos EUA e você possui usuários em
Londres, Inglaterra, eles podem escolher seu mirror de Londres e seus pedidos não precisam ir a meio
mundo e voltar.

Para usar este método, crie uma propriedade em seu folder raiz de tipo lines chamada "mirror_servers".
Em cada linha desta propriedade, ponha a URL de seus vários clientes ZEO, como mostra a Figura 11.2.

Figura 11.2 - Figura da propriedade com URLs para mirrors.

Agora, adicione algum DTML simples a seu site para mostrar uma lista de seus mirrors:

<h2>Please choose from the following mirrors:


<ul>
<dtml-in mirror_servers>
<li><a href="&dtml-sequence-item;"><dtml-var
sequence-item></a></li>
</dtml-in>
</ul>

Este DTML mostra uma lista de todos os mirrors que seus usuários podem escolher. Ao usar este
modelo, é bom colocar nome em seus computadores para ajudar seus usuários em suas escolhas pelos
mirrors. Por exemplo, se você propagar a carga geograficamente, então escolha nomes de países para
seus computadores.

Por outro lado, se você não quer que os usuários escolham um mirror voluntariamemte, você pode ter o
método index_html do seu site www.zopezoo.org rediredionando o HTTP. Por exemplo, use o seguinte
código em seu método index_html do site www.zopezoo.org:

<dtml-call expr="RESPONSE.redirect(_.whrandom.choice(mirror_servers))">

Este código redirecionará qualquer visitante para www.zopezoo.org para um servidor de mirror

248 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

aleatório.

Usando um DNS Round-Robin para Distribuir a Carga

O Domain Name System ou DNS, é um mecanismo da Internet que traduz nomes de computadores
(como "www.zope.org") dentro do endereço numérico. Este mecanismo pode mapear um nome para
vários endereços.

O método mais simples para equilibrar a carga é usar o DNS round-robin, conforme ilustrado na Figura
11.3.

Figura 11.3 - Equilíbrio da carga com o DNS round-robin.

Quando www.zopezoo.org conseguir resolver, BIND responde com o endereço para um deles
zeoclient1, zeoclient2, ou zeoclient3- mas em uma ordem trocada cada vez. Por exemplo, um usuário
pode digitar www.zopezoo.org e obter o endereço de zeoclient1, e outro usuário pode digitar
www.zopezoo.org e obter o endereço de zeoclient2. Dessa maneira seus usuários propagados por vários
clientes ZEO.

Isto não é um esquema perfeito de equilíbrio de carga, porque o DNS resolve que a informação deve ser
cacheada por outro nameservers na rede. Logo que um usuário resolver www.zopezoo.org para um
cliente particular ZEO, todos os pedidos subsequentes para aquele usuário também vão para o mesmo
cliente ZEO. O resultado final geralmente está certo, porque a soma dos pedidos são realmente
propagadas para vários clientes ZEO.

Um ponto negativo desta solução é que ela pode levar horas procurando por name servers para
atualizar as cópias da cache onde acham que o endereço está www.zopezoo.org. Se você não for
responsável pelo mecanismo de seus clientes ZEO e um falha, então 1/N ésimos de seus usuários (onde
N é o número de clientes ZEO) não serão capazes de chegar ao seu site até que as caches dos seus name
server sejam atualizadas.

Configurar seus servidores DNS para usar a solução round-robin é uma técnica avançada que não é
abordada neste livro. Uma boa referência em como fazer isso pode ser encontrada na Documentação do
Apache.

Distribuir a carga com DNS round-robin é útil, e barata, mas não é 100% eficiente. Servidores DNS
podem ter estranhas políticas de cacheamento, e você está contando com uma idéia particular no modo

249 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

de como o DNS trabalha para distribuir a carga. A próxima seç~so descreve uma maneira mais
complexa, mas muito mais poderosa de distribuição de carga chamada Layer 4 Switching.

Usando Layer 4 Switching para Distribuir a Carga

A Layer 4 switching deixa um computador de forma transparente controlar os pedidos para um farm
dos computadores. Esta é uma técnica muito avançada que está fora do escopo deste livro, mas vale a
pena indicar diversos produtos de Layer 4 switching para você.

Layer 4 switching envolvem um switch que, conforme a sua preferência, escolha de um grupo de cliente
ZEO a qualquer hora um pedido que chega, como mostra a Figura 11.4.

Figura 11.4 - Ilustração do Layer 4 switching.

Existem hardware e software para Layer 4 switching. Existem várias soluções de software, mas uma em
geral que se mantém é o Linux Virtual Server (LVS). Esta é uma extensão para o sistema operacional
Linux que faz com que o computador Linux se torne uma Layer 4 switching. Mais informações sobre
LVS podem ser encontradas em seu site.

Existe também várias soluções de hardware que reivindicam um desempenho mais elevado do que
soluções baseadas em software como LVS. A Cisco Systems tem um dispositivo de hardware chamado
LocalDirector que funciona como uma Layer 4 switching, e Alteon também fez uma Layer 4 switching
popular.

Distribuição com um Simples Ponto de Falha

Sem o ZEO, seu sistema Zope inteiro é um único ponto de falha. ZEO permite que você espalhe esse
ponto de falha para muitos computadores diferentes. Se um de seus clientes ZEO falhar, outros clientes
podem responder os pedidos em defesa dos clientes que falharam.

Note que quando isto foi escrito, o único ponto de falha não podia ser inteiramente eliminado, porque
havia ainda um servidor central de armazenamento. Os métodos descritos nesta secção, de qualquer
forma, minimiza os riscos de falhas propagando a maioria do Zope por muito computadores.

Isto significa que, enquanto ele remove alguns riscos dos seus servidores web como um único ponto de
falha, ele não elimina todos os riscos porque agora o servidor ZEO é um único ponto de falha. Existem

250 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

vários modos de distribuição com este caso.

Um método popular é aceitar um único ponto de risco de falha e suavizar aquele risco tanto quanto for
possível pelo uso de um equipamento avançado confiável para seu servidor ZEO, frequentemente faça
cópia de segurança de seus dados, e use hardware barato e em circulação para seus clientes ZEO.
Investindo a maior parte da sua infraestrutura fazendo seu servidor ZEO ficar sólido (suprimento de
força redntante, RAID, e outros métodos de segurança a falhas) você pode assegurar-se que seu
servidor ZEO permanecerá em pé, até mesmo se muitos de seus clientes ZEO baratos falharem.

Algumas aplicações, entretanto, requerem 100% de tempo absoluto. Existe ainda uma chance, com a
solução descrita acima, de seu servidor falhe. Se isto acontecer, você precisa fazer uma cópia de
segurança do servidor ZEO para corrigir a falha do servidor.

Assim como a Layer 4 switching, há vários produtos, software e hardware, que ajudam você a suavizar
este tipo de risco. Uma solução popular de software para o linux é chamada fake. Fake é uma utilidade
baseada em Linux que pode fazer uma cópia de segurança de seu computador e copiar um computador
principal com falha copiano o endereço da rede. Quando usado em conjunto com utilidades de
monitoramento como mon ou heartbeat, a cópia pode garantir quase 100% do tempo de seu servidor
ZEO e da Layer 4 switches. Usar fake nesta maneira está além do escopo deste livro.

Até agora, nós explicamos estas técnicas para suavizar o único ponto de falha:

Várias ferramentas (mirrors, DNS round-robin, Layer 4 switching) podme ser usadas para
multiplicar pedidos através de vários computadores.
Zeo pode ser usado para distribuir seu banco de dados (servidor ZEO) para vários clientes ZEO.
fake,e outras ferramentas podem ser usadas para fornecer servidores redundantes e Layer 4
switching.

A parte final do problema é o próprio servidor ZEO e onde ele armazena a sua informação. Se o seu
servidor ZEO principal falhar, como pode a cópia do seu servidor ZEO garantir que ele tem a informação
mais recente que estava contida no servidor principal? Como sempre, existem várias maneiras de
resolver este problema, e eles são mostrados na próxima seção.

Detalhes do Servidor ZEO

Antes de explicar os detalhes de como o servidor ZEO trabalha, vale a pena compreender alguns
detalhes sobre como os armazenamentos de Zope funcionam em geral.

Zope não salva qualquer um de seus objetos ou informação diretamente no disco. Ao contrário, o Zope
usa um componente de armazenamento que cuida de todos os detalhes de onde os objetos deveriam
ser salvos.

Este é um modelo muito flexível, porque o Zope não precisa estar preocupado com a abertura dos
arquivos, ou leitura e escrita de banco de dados, ou envio de dados pela rede (neste caso do ZEO). Cada
armazenamento particular cuida de sua tarefa de interesse so Zope.

Por exemplo, um simples, sistema único do Zope pode ser ilustrado na Figura 11.5.

251 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 11.5 - Zope conectado a um filestorage.

Voce pode ver que há uma aplicação Zope que está plugada em um FileStorage. Este armazenamento,
como seu nome indica, salva todas as informações em um arquivo no sistema de arquivo do
computador.

Quando o ZEO é usado, você simplesmente substitui o FileStorage por um ClientStorage como ilustra a
Figura 11.6.

Figura 11.6 - Zope com um Client Storage e um servidor Storage.

Ao invés de salvar objetos em um arquivo, a ClienteStorage envia objetos por uma conexão de rede para
um Storage Server. Como você pode ver na ilustração o servidor Storage usa o FileStorage para salvar as
informações em um arquivo no sistema de arquivos do servidor ZEO.

Storages são trocáveis e fáceis de implementar. Por causa de sua natureza mutável, os servidores de
armazenamento do ZEO podem usar ZEO ClientStorages para passar dados dos objetos para outro ZEO
Storage Server. Isto está ilustrado na Figura 11.7.

252 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 11.7 Sistema Multi-tiered ZEO.

Aqui, você pode ver vários clientes ZEO em forma de um funil pasando por três servidores ZEO, que por
sua vez agem como clientes ZEO e afunilam para o final, servidor central ZEO que salva a sua
informação em um FileStorage. Agora o servidor central ZEO é o único ponto de falha no sitema. Se
alguns de seus outros clientes, ou servidores intermediários falharem, o sistema ainda continuará
funcionando, mas se o servidor central falhar, então você precisa de uma alternativa.

Usando fake você pode ter uma estratégia de cópia de segurança para o servidor de armazenamento,
mas este método não é muito bom provado e não foi explorado pelos autores. No futuro, ZEO terá uma
característica de "servidor múltiplo", que permite que um grupo de servidores de armazenamento ajam
como um quorum, assim se um ou mais servidores de armazenamento falharem, os servidores que
permanecerem no quorum podem continuar a servir os objetos.

Existem várias vantagens para uma aproximação como esta, especialmente se voce está interessado em
criar uma rede de distribuição pesada de banco de dados objeto. Certamente, com qualquer sistema de
vantagens, existem alguns inconvenientes, que são discutidos na seção seguinte.

Interrupções dos Processos do ZEO


Para a maioria, rodar ZEO é exatamente como rodar o Zope sozinho, mas há algumas coisas que
precisam ser lembradas.

Primeira, isso exige mais para a informação ser escrita no banco de dados do Zope. Isto não retarda a
sua abilidade de usar Zope (porque Zope não obstrui você durante a operação de escrita) mas aumenta
suas possibilidades de obter um ConflictError. Erros de Conflito acontecem quando dois clientes ZEO
tentam escrever ao mesmo tempo ao mesmo objeto. Um dos clientes ZEO ganha o conflito e continua
normalmente. O outro cliente ZEO perde o conflito e tem que tentar outra vez.

Os erros de conflito não deveriam ser frequente pois isso deixa seu sistema lento. Enquanto é normal
ter poucos erros de conflito (por causa do caráter de concorrente do Zope) é anormal ter isto é anormal
ter muitos de erros de conflito. O caso pathological é quando mais de um cliente ZEO tenta escrever o
mesmo objeto várias vezes rapidamente. Neste caso, haverá muitos erros de conflito, e
conseqüentemente muitas tentativas novas. Se um cliente ZEO tenta escrever em um banco de dados
três vezes e obter três erros do conflito em uma linha, então o pedido é abortado e os dados não são
escritos.

253 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Pelo fato do ZEO levar tempo para escrever esta informação, as possibilidades de obter um
ConflictError são mais elevadas do que se você não estivesse rodando ZEO. Por causa disso, ZEO é mais
sensível ao contexto do que quando o Zope roda sem o ZEO. Você tem que lembrar disto quando você
está projetando sua rede ou aplicação. Em geral quanto mais e mais frequentemente escritas para o
banco de dados aumentam suas chances de obter um ConflictError. Por outro lado, conexões de rede
mais confiáveis e computadores mais rápidos minimizam as chances de se obter um ConflictError.
Levando em consideração estes dois fatores, os erros do conflito podem ser na maiorias das vezes
evitados.

Enfim, conforme esta anotação, não há nenhuma codificação ou autenticação embutida entre servidor
ZEO e clientes. Isto significa que você deve ter muito cuidado para quem você expõe seus servidores
ZEO. Se você deixar seu servidor ZEO aberto a toda a rede, então qualquer um pode conectar em seu
servidor ZEO e escrever dados em seu banco de dados, e pode ter maus resultados.

Entretanto este não é um problema insolucionável, porque você pode usar outras ferramentas, como
firewalls, para proteger seus servidores ZEO. Se você estiver rodando uma conexão cliente/servidor
ZEO sobre uma rede insegura e você quer a garantia que sua informação esteja mantida privada, você
pode usar ferramentas como OpenSSH e stunnel para configurar a segurança, canais de comunicação
codificadas entre seus clientes ZEO e os servidores. Como estas ferramentas funcionam e como setá-las
está além do espaço deste livro, mas ambos pacotes são documentados adequadamente em seus web
sites. Para mais informação sobre firewalls, com Linux em particular, nós recomendamos o livro de
"Firewalls do Linux" escrito por Robert Ziegler, que foi publicado pela New Riders.

Conclusão
Neste capítulo vimos sobre o ZEO, e como ZEO pode aumentar substancialemnte a capacidade de seu
website. Além de rodar ZEO em um computador para familiarizarmo-nos, vimos ZEO rodas em muitos
computadores, e várias técnicas para propagar a carga de seus visitantes entre os muitos computadores.

ZEO não é uma solução mágica, e como outro sistema projetado para trabalhar com muitos
computadores, ele adiciona outros níveis de cimplexidade a seus web site. Esta complexidade satisfaz
de qualquer forma quando você necessita servir muitos de seus conteúdos dinâmicos para seus
visitantes.

15. Estendendo o Zope


Este capítulo trata da extensão do Zope pela criação de suas próprias classes de objetos.
Discute ZClasses, e como as instâncias são construídas das classes. Descreve passo a
passo como construir uma ZClass e controle de segurança e resultados do projeto. Enfim,
discute a criação de Python base classes para ZClasses e descreve a base classes que é
colocada com o Zope. Este capítulo mostra a você como levar o Zope para o próximo
nível, modelando o Zope a suas necessidades.

Você pode estender o Zope criando seus próprios tipos de objetos que são adequados para as
necessidades da aplicação. Novos tipos de objetos são instalados no Zope pelos Products. Produtos são
estensões para o Zope que a Zope Corporation e muitos outros desenvolvedores criaram. Há milhares
de Produtos diferentes e muitos servem objetivos específicos. Uma biblioteca completa dos Produtos é a
Sessão Documentação do Zope.org.

Products podem ser desenvolvidos de duas maneiras, através da web usando ZClasses, e na linguagem
de programação Python. Products podem até ser um híbrido de produtos feitos através da web e com
código Python. Este capítulo discute a construção de novos produtos através da web, um tópico que

254 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

você já tem um breve visão no Capítulo 11, "Buscando e Categorizando Conteúdo". Desenvolver um
Produto inteiramente com programação em Python está fora do escopo deste documento e você deveria
visitar o Zope.org para documentação específica sobre desenvolvimento de Produtos.

Este capítulo mostra a você como:

Criar um novo Produto no Zope


Define ZClasses em Produtos
Integrar Python com ZClasses
Distribuir Produtos a outros usuários do Zope

O primeiro passo na customização do Zope começa na próxima seção, onde você aprende como criar
novos Produtos no Zope.

Criando Produtos Zope


Através da web os Produtos são armazenados na pasta Product Management no Painel de Controle.
Clique no Control_Panel no root folder e então clique em Products. Você está agora na tela mostrada na
Figura 12.1.

Figura 12.1 - Produtos instalados

Cada caixa azul representa um Produto instalado. Desta tela, você pode gerenciar estes Produtos.
Alguns Produtos são construídos no Zope por default ou foram instalados por você ou seu
administrador. Estes Produtos têm um ícone de caixa fechada, como mostra a Figura 12.1. Produtos com
a caixa fechada não podem ser gerenciados através da web. Você pode obter informações sobre estes
produtos clicando neles, mas você não pode mudá-los.

Você também pode criar seus próprios Produtos que você pode gerenciar através da web. Seus Produtos
deixam você criar novos tipos de objetos no Zope. Estes objetos gerenciáveis através da web tem ícones
de caixa aberta. Se você seguiu os exemplos no Capítulo 11, "Buscando e Categorizando Conteúdo",
então você tem um produto News com caixa aberta.

Porque você quer criar produtos? Por exemplo, todos os vários guardas do Zoo querem construir uma
simples e fácil forma de mostrar conteúdo sobre o Zoo. As demonstrações devem estar todas no mesmo
formato e conter uma estrutura de informação parecida, e cada uma será específica para cada animal no
Zoo.

Para efetuar isto, você poderia construir uma demonstração para um animal, e então copiá-lo e colá-lo
para cada demonstração, mas isto seria difícil e um processo manual. Todas as informações e

255 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

propriedades teriam de ser mudadas para cada demonstração nova. Ainda, haveriam milhares de
demonstrações.

Para adicionar mais algo ao problema, vamos dizer que você quer agora ter informação de cada
demonstração que diz se o animal é perigoso ou não. Você teria que mudar cada demonstração, uma a
uma, para fazer isto usando copiar e colar. Evidentemente, copiar e colar não modifica muito o zoo, e
poderia ser muito caro.

Você também precisa garantir que cada demonstração é fácil de gerenciar. Os guardas das
demonstrações individuais deveriam ser os únicos a oferecer informação, mas nenhum dos guardas do
Zoo sabem muito sobre o Zope ou como criar web sites e você certamente não quer desperdiçar tempo
ensinando-os. Você apenas quer que eles digitem algumas informações simples em um formulário sobre
seus tópicos de interesse, clique no submit, e vá embora.

Criaando um Produto do Zope, você pode executar estes objetivos rapida e facilmente. Você pode criar
facilidades para gerenciar objetos que seus guardas possam usar. você pode definir modelos de
demonstração que você pode mudar uma vez e afetar todas as demonstrações. Você pode fazer estas
coisas criando Produtos do Zope.

Criando um Produto Simples


Usando Produtos você pode resolver os problemas de gerenciamento e criação de exibição. Iremos
iniciar com um exemplo de como criar um produto simples que lhe permitirá coletar informações de
como exibir e criar uma exibição personalizada. Mais adiante no capítulo você verá maneiras mais
complexas e poderosas de usar produtos.

O principal de um produto do Zope é que ele lhe permite criar objetos em uma localização central e ele
oferece a você acesso aos seus objetos pela lista de adição de produtos. Isto lhe oferece abilidade para
construir serviços globais e torná-los disponíveis através de uma parte padrão da interface de
gerenciamento do Zope. Em outras palavras, um Produto lhe permite personalizar o Zope.

Comecemos indo até a pasta Products no Control Panel. Para criar um novo Produto, clique no botão
Add Product no folder Product Management (Gerenciamento de Produtos). Isto irá levar você ao
formulário de adição de Produtos. Digite o id "ZooExhibit" e clique em Generate. Você verá agora seu
novo Produto no Product Management. Ele deve ser uma caixa azul com a tampa aberta. A tampa
aberta significa que você pode clicar no Produto e gerenciá-lo pela web.

Selecione o Produto ZooExhibit. Isto o levará a tela de gerenciamento de Produtos.

A tela de gerenciamento de um Produto se parece e funciona como como a de um Folder exceto por
algumas diferenças:

1. Há uma nova aba, chamada Distribution, bem a direita. Isto lhe dá a abilidade de empacotar e
distribuir seu Produto. Isto é discutido mais tarde.
2. Se você selecionar a lista de adição, você verá alguns tipos novos de objetos que você pode
adicionar incluindo ZClass, Factory, e Permission.
3. A pasta com uma interrogação é a Help Folder (Pasta de Adjuda) do Produto ZooExhibit. Esta
pasta pode conter Help Topics (Tópicos de Ajuda) que ensina as pessoas como usar seu Produto.
4. Há também uma nova aba Define Permissions (Definir Permissões) que define as permissões
associadas com este Produto. Isto é avançado e não é necessário para este exemplo.

Na aba Contents crie um DTML Method chamado hello com este conteúdo:

256 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>
<h2>Hello from the Zoo Exhibit Product</h2>
<dtml-var standard_html_footer>

Este método lhe permitirá testar seu produto. Depois crie uma Factory. Selecione Zope Factory da lista
de adição de produtos. Você irá para o formulário de adição de uma Factory como mostra a Figura 12.2.

Figura 12.2 - Adicionando uma Factory

Factories criam uma ponte entre a lista de adição de produtos e o seu Produto. Dê a sua Factory o id
myFactory. No campo Add list name digite Hello e na seleção Methods, escolha hello. Agora clique
Generate. Agora clique na nova Factory e mude a Permission (Permissão) para Add Documents, Images
e Files e clique em Save Changes. Isto avisa ao Zope que você deve ter a permissão para Adicionar
documentos, Imagens e Arquivos para utilizar a Factory. Parabéns, você personalizou a interface de
gerenciamento do Zope. Vá para a pasta raiz e clique na lista de adição de produtos. Note que agora ele
inclui uma entrada chamada Hello. Escolha Hello da lista de adição de produtos. Ele chama seu método
hello.

Uma das coisas mais comuns para se fazer com métodos que você linka com factories é copiar objetos na
pasta atual. Em outras palavras seus métodos podem acessar a localização da qual eles foram chamados
e podem executar operações naquela pasta incluindo copiar objetos dentro dela. Só porque você pode
fazer tudo o que for malucos com as Factories e Produtos não significa que você pode fazer tudo. Em
geral, as pessoas esperam que quando elas selecionam alguma coisa da lista de adição de produtos que
elas serão levados a um formulário de adição onde elas especificarão o id de um novo objeto. Então elas
esperam que quando cliquem em Add o novo objeto com o id que eles especificaram seja criado em sua
pasta. Veremos como realizar estas expectativas.

Primeiro crie uma nova pasta chamada exhibitTemplate no seu Produto. Isto irá servir como um modelo
para as exibições. Também na pasta Produto crie um DTML Method chamado addForm, e um Script
Python chamado add. Estes objetos criarão novas instâncias de exibição. Agora volte para sua Factory e
mude-a de modo que o Add list name seja Zoo Exhibit e o método seja addForm.

Então o que vai acontecer é que quando alguém escolhe Zoo Exhibit da lista de adição de produtos, o
método addForm será executado. Este método deveria coletar informações sobre o id e o título da
exibição. Quando o usuário clica em Add ele deveria chamar o script que irá copiar o folder
exhibitTemplate dentro da pasta chamada e o renomeará para ter o id específico. O próximo passo é
editar o método addForm para ter este conteúdo:

257 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var manage_page_header>

<h2>Add a Zoo Exhibit</h2>

<form action="add" method="post">


id <input type="text" name="id"><br>
title <input type="text" name="title"><br>
<input type="submit" value="Add">
</form>

<dtml-var manage_page_footer>

Reconhecidamente este é um formulário de adição particularmente "frio". Ele não coleta muitos dados e
não informa ao usuário o que é uma Exibição do Zôo e por quê eles querem adicionar uma. Quando você
criar sua própria aplicação web você vai querer fazer melhor do que este exemplo.

Note que este método não inclui o cabeçalho e rodapé padrão do HTML. Pela convenção Zope, telas de
gerenciamento não usa os mesmos cabeçalhos e rodapés que seu site usa. Ao invés disso as telas de
gerenciamento usam manage_page_header e manage_page_footer. O cabeçalho e rodapé visualizados
no gerenciamento asseguram que a visualização do gerenciamento tenha uma aparência e semntido
comum.

Note também que a ação do formulário é o script adicionar. Agora cole o seguinte corpo no script
adicionar:

## Script (Python) "add" ##parameters=id, title, REQUEST=Nome ##

" " " Copie o modelo de exibição para a pasta chamada " " "

#Clone o modelo, dando-lhe o novo id. Isto será colocado #no contexto atual (o lugar de onde o factory
foi chamado). exhibit=context.manage_clone ( container.exhibitTemplate, id)

# Mude o título do clone exhibit.manage_changeProperties (title=title)

Se nós somos chamados através da web, redirecione devolta para o contexto if REQUEST is not None:
try: u=context.DestinationURL() except: u=REQUEST ['URL1'] REQUEST.RESPONSE.redirect
(u+/manage_main?update_menu=1)

Este script clona o exhibitTemplate e copia-o para a pasta atual com o id específico. Então ele muda a
propriedade título da nova exibição. Finalmente ele retorna para a tela principal de gerenciamento de
pastas pela chamada manage_main.

Parabéns, você agora estendeu o Zope pela criação de um novo produto. Você criou uma maneira de
copiar objetos no Zope através da lista de adição de produtos. No entanto, esta solução ainda sofre
alguns problemas que nós discutiremos em breve no capítulo. Mesmo que você possa editar o modelo
de exibição em um lugar centralizado, ele ainda é somente um modelo. Então se você adicionar uma
nova propriedade ao modelo, ele não afetará a qualquer das exibições existentes. Para mudar exibições

258 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

existentes você terá que modificar cada uma manualmente.

ZClasses leva você a um passo maior para permitir-lhe a ter um modelo central que define um novo tipo
de objeto, e quando você muda o modelo, todos os objetos desse tipo mudam com ele. Este modelo
central é chamado de ZClass. Na próxima seção, nós mostraremos como criar ZClasses que definem
uma nova ZClasse Exhibit.

Criando uma ZClasse


Criando ZClasses

ZClasses são ferramentas que ajudam você a construir novos tipos de objetos no Zope, por definição
uma classe. Uma classe é como BLUEPRINT para objetos. Quando define uma classe, você está
definindo o que um objeto será quando ele for criado. Uma classe pode definir métodos, propriedades, e
outros atributos.

Os Objetos que você cria de uma cerat classe são chamados de instâncias de uma classe. Por exemplo,
há apenas uma classe Pasta, mas você pode ter muitas instancias Pasta em seu aplicativo.

Instâncias possuem os mesmos métodos e propriedades que suas classes. Se você mudar a classe, então
todas as instâncias refletirão a mudança. Diferente dos modelos que você criou na última seção, as
classes continuam a exercer controle sobre as instâncias. Tenha em mente que isto somente funciona
em uma via, se você mudar uma instância, nenhuma mudança será feita na classe ou qualquer outra
instância.

Uma boa analogia com o mundo real para ZClasses são modelos de processador de textos. Muitos
processadores de texto vem com um conjunto de modelos predefinidos que você pode usar para criar
um certo tipo de documento, como um resumo. Existem centenas de milhares de resumos no mundo
baseados no Modelo de Resumos do Microsoft Word, mas há somente um modelo. Assim como o
modelo de Resumos é para todos aqueles resumos, uma ZClasse é um modelo para qualquer número de
objetos Zope similares.

ZClasses são classes que você pode construir através da web usando a interface de gerenciamento do
Zope. Classes podem também ser escritas em Python, mas isto não é abrangido neste livro.

ZClasses podem herdar atributos de outras classes, herança permite a você definir uma nova classe que
é baseada em outras classes. Por exemplo, digamos que você queira criar um novo tipo de objeto
documento que tenha propriedades especiais onde interessar a você. Ao invés de construir todas as
funcionalidades de um documento do nada, você pode apenas herdar todas as funcionalidades da classe
Documento DTML e adicionar somente as novas informações que interessam a você.

Herança também permite construir generalização de relacionamento entre classes. Por exemplo, você
pode criar uma class chamada Animal que contenha informações que um animal possue em geral.
Então, você pode criar as classes Réptil e Mamífero ambas as quais herdam de Animal. Tomando
proveito dos mesmos, você pode criar duas classes Lagarto e Cobra adicionais, as quais ambas herdam
de Réptil, como mostrado na Figura 12-3.

259 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Figura 12-3 - Exemplo de classes

ZClasses podem herdar muitos dos objetos que você usou neste livro. Adicionalmente, ZClasses podem
herdar de outras ZClasses definidas no mesmo Produto. Nós usaremos esta técnica e outras neste
capítulo.

Antes de partir para o próximo exemplo, você pode renomear o Produto ZooExhibit existente na sua
pasta de Produtos Zope para alguma coisa, como ZooTemplate então que não conflitará com este
exemplo. Agora, crie um novo Produto na pasta Produtos chamado ZooExhibit.

Selecione ZClass da lista de adição da visualização do conteúdo de ZooExhibit e vá para o formulário de


adição de ZClasses. Este formulário é complexo, e possue muitos elementos. Nós veremos cada um
deles:

ID
Este é o nome da classe a ser criada. Por exemplo, escolha o nome ZooExhibit.

Meta Type
O Meta Type de um objeto é um nome para o tipo deste objeto. Este pode ser algo curto mas descritivo
sobre o que o objeto faz. Por exemplo, escolha o meta type “Zôo Exhibit”.

Base Classes
Base Classes definem uma seqüência de classes de onde você quer que sua classe herde atributos. Sua
nova classe pode ser através de como extensão ou começando derivada da funcionalidade de sua base
de classes. Você pode escolher uma ou mais classes classe da lista da esquerda e clique o botão à para
introduzi-lo em sua lista de base de classes. O botão ß remove qualquer base de classes que você
selecionar na direita. Para este exemplo não selecione qualquer base de classes. Mais tarde neste
capítulo, nós iremos explanar algumas das bases de classes mais interessantes, como ObjectManager.

Criar objetos construtores?


Usualmente você quer deixar esta opção marcada a menos que queira tome o cuidado de criar um
formulário/ação construtor e um próprio objeto Factory. Se você quer que o Zope faça este task para
você, deixe-o marcado. Marque esta caixa principal que este formulário criará 5 objetos, uma Classe, um
Formulário Construtor, uma Ação Construtora, uma Permissão e um Factory. Para este exemplo, deixe
esta caixa marcada.

Agora clique em Add. Isto o levará de volta ao Produto ZooExhibit e você verá 5 novos objetos, como

260 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

mostrado na Figura 12-4.

Os cinco objetos criados pelo Zope estão todos configurados apropriadamente para o trabalho, você não
precisa mudá-los por enquanto. Aqui esta uma breve descrição de cada objeto que foi criado:

ZooExhibit

Esta é a própria ZClasse. Seu ícone é uma caixa branca com duas linhas horizontais. Este é o símbolo
tradicional de uma classe.

ZooExhibit_addForm

Este método DTML é o Formulário construtor para uma Zclass. Ë um formulário simples que aceita um
id e título. Você pode personalizar este formulário para aceitar qualquer tipo de entrada que seu objeto
requeira. Isto é bastante similar ao formulário de adição que nós criamos no primeiro exemplo.

ZooExhibit_add
Este método DTML é chamado pelo formulário construtor, ZooExhibit_addForm. Este método
atualmente cria seu novo objeto e configura seu id e título. Você pode personalizar este formulário para
fazer modificações mais avançadas para seu objeto baseado em parâmetros de entrada do
ZooExhibit_addForm. Isto tem a mesma funcionalidade que o script Python que nós criamos no
exemplo anterior.

ZooExhibit_add_permission
A curiosa STICK-PERSON vista conduzindo a caixa azul é uma Permissão. Ela define uma permissão
que você pode associar com a adição de novos objetos ZooExhibit. Isto vai proteger a habilitação para
adicionar novas exibições do Zôo. Se você clicar nesta Permissão, poderá ver que o nome desta nova
permissão é “Add ZooExhibit”.

ZooExhibit_factory
O pequeno FACTORY com um ícone de chamíne é um objeto FACTORY. Se você clicar neste objeto,
você pode modificar o texto que aparece na lista de adição para este objeto na caixa Add lista name. O
Method é o método que é chamado quando um usuário seleciona o Add list name da lista de adição.
Usualmente isto é o fomulário construtor para seu objeto, netse caso, ZooExhibit_addForm. Você pode
associar a permissão que o usuário deve ter para adicionar este objeto, neste caso,
ZooExhibit_add_permission. Ao invés disso você pode também especificar uma permissão regular do
Zope.

É isso, você criou sua primeira ZClasse. Clique na nova ZClasse e clicque na tabela Basic. O Basic mostra
na sua ZClasse algumas informações que você especificou no formulário de adição de ZClasses. Você

261 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

não pode mudar a base de classe sde uma ZClasse. Como você aprendeu anteriormente no capítulo,
estas configurações incluem:

meta-type
O nome de sua ZClasse como aparece na lista de adição de produtos.

class id
O único identificador de sua classe. Você deve apenas mudar isso se você quer usar sua definição de
classe para instâncias existentes em outras ZClasse. Neste caso você deve copiar o id de classe da classe
antiga para a nova classe.

icon
O caminho para suas imagens de ícones de classes. Há uma pequena razão para mudar isto. Se você
quer mudar o ícone da classe na sua nova classe.

Apartir este ponto, você pode começar criando novas instâncias da ZClasses ZooExhibit. Primeiro
pense, você provavelmente quer um lugar comum onde todas as exibições são definidas, então vá para a
raìz de sua pasta e selecione Folder da lista de adição e crie uma nova pasta com o id "Exibições". Agora,
clique na pasta Exibições que você acabou de criar e arraste a lista de adição. Como você pode ver,
ZooExhibit agora é uma lista de adição.

Vá adiante e selecione ZooExhibit da lista de adição e crie uma nova exibição com o id "Coelhos". Após
criar a nova exibição selecione-a clicando nela.

Como você pode ver seu objeto já possue três opções, Undo, Ownership e Security. Você não tem que
definir estas partes de seu objeto, o Zope fará isso para você. Na próxima seção, nós adicionaremos mais
algumas opções para você editar seu objeto.

Criando Visualizações de sua ZClasse

Todos os objetos Zope são divididos em telas lógicas chamadas Views. Views são comumente usados
quando você trabalha com objetos Zope na interface de gerenciamento, as telas indicadas em todos os
objetos Zope são views. Alguns views como Undo, são padrão e vem com o Zope.

Views são definidas na visualização Views de uma ZClasse. Vá até sua ZClasse ZooExhibit e clique no
indicador Views. A visualização Views vista como Figura 12-5.

Nesta visualização você pode ver três visualizações que vem automaticamente com seu novo objeto,
Undo, Ownership, e Security. Elas estão configuradas automaticamente para você convenientemente,
desde então todos os objetos tem estas interfaces, mas você pode mudá-las ou remove-las daqui se você

262 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

realmente quiser (você geralmente não quer).

A tabela de visualização está dividida em três colunas, Name, Method, e Help Topic. O Name é o nome
da visualização e é o rótulo que desenha na tabela de visualização na interface de gerenciamento. O
Method é o método de classe ou folha de propriedades que propicia a chamada para desenhar a
visualização. O Help Topics é onde você associa um objeto Help Topic com esta visualização. Tópicos de
Ajuda serão explanados mais tarde.

Visualizações também trabalham com o sistema de segurança para fazer com que os usuários somente
vejam as visualizações em um objeto que eles tem permissão de ver. Segurança será explicado em
detalhes um pouco mais adiante, mas é bom saber neste momente que as visualizações agora somente
separa uma interface de gerenciamento em blocos lógicos, mas eles também controlam quem pode ver
cada visualização.

A coluna Method na visualização de métodos selecionou caixas as quais lhe permitem escolher cada
visualização de cada gênero de método. A associação de métodos com uma visualização pode ser entre
outros um objeto na visualização Methods, ou uma folha de propriedades na visualização de folhas de
propeiedades.

Criando Propriedades na sua ZClasse

Propriedades são coleções de variáveis que seu objeto usa para armazenar informações. Um objeto
ZooExhibit, por exemplo, necessitaria de propriedades para conter informações sobre a exibição, como
qual animal está na exibição, uma descrição, e quem são os zeladores.

Propriedades para ZClasses trabalham com um pequeno diferencial de propriedades em objetos Zope.
Em ZClasses, Propriedades vem em grupos nomeados chamados Proprerty Sheets. Uma tabela de
propriedades é o caminho de organizar um conjunto de propriedades relatadas juntas. Vá até sua
ZClasse ZooExhibit e clique na tabela Propriety Sheets. Para criar uma nova tabela, clique Add Common
Instance Sheet. Isto levará você ao formulário de adição da Tabela de propriedades. Chame sua nova
Tabela de Propriedades de "ExhibitProprieties" e clique Add.

Agora você pode ver que sua nova tabela, ExhibitProprieties, foi criada na visualização Propriety Sheets
de sua ZClasse. Clique na nova tabela para gerenciá-la, como mostra a Figure 12-6.

Como você pode ver, esta tabela parece muito com a visualização das propriedades nos objetos Zope.
Aqui, você pode criar novas propriedades nesta folha. Propriedades na tabela de propriedades são
exatamente como as propriedades nos objetos Zope, ele tem um name, um type e um value.

Crie trê novas propriedades nesta tabela:

263 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

animal
Esta propriedade pode ser do tipo String. Ele irá armazenar o nome do animal deste atributo de exhibit.

description
Esta propriedade pode ser do tipo text. Ela irá armazenara descrição da exhibit.

caretakers
Esta propriedade pode ser do tipo lines. Ela irá armazenar uma lista de nomes de tratadores para a
exhibit.

Tabelas de Propriedades tem duas utilizações. Como você viu com este exemplo, eles são uma
ferramenta para organizar conjuntos relacionados de proprieades sobre seus objetos, segundo que, eles
são usados para gerar formulários HTML e ações para editar este conjunto de propriedades. O
formulário de edição HTML é gerado automticamente, você somente necessita associar um visualizador
com a tabela de Propriedades para ver o formulário de edição da tabela. Por exemplo, retorne para a
ZClasse ZooExhibit e clique na tabela Views e crie uma nova visualização com o nome Edit e associe com
o método propertysheets/ExhibitProperties/manage_edit.

Desde que você possa usar a Tabela de Propriedades para criar telas de edição você deve querer criar
mais que uma Tabela de Propriedade para sua classe. Usan do mais que uma tabela você pode controlar
cada uma das propriedade que são mostradas juntas para propósitos de edição. Você pode também
separar propriedades privadas de públicas em diferentes tabelas pela associação deles com permissões
diferentes.

Agora, volte para seu diretório Exhibits e também procure por uma instancia ZooExhibit existente ou
crie uma nova. Como você pode ver, uma nova Visualização chamada Edit foi adicionada ao seu objeto,
como mostrado na Figura 12-7.

Este formulário de edição foi gerado para você automaticamente. Você somente necessita criar a Tabela
de Propriedades, e então associá-las a tabela com uma visualização. Se você adicionar outra propriedade
para a tabela de Propriedades ExhibitProperties, todas as suas instancias receberão automaticamente
um novo formulário de edição atualizado, porque quando você modifica uma ZClasse, todas as
instancias da classe herdam a mudança.

Isto é importante para enteder que mudanças feitas na classe refletem em todas as suas instancias, mas
mudanças em uma instancia não refletem em uma classe ou em qualquer outra instancia. Por exemplo,
na visualização Edit para sua instancia ZooExhibit (não a classe), entre "Coelho com garras" para a
propriedade animal, a descrição "Garras, coelho carnívoro que atormentava cavaleiros medievais
próximos. Eles são conhecidos por seus dentes afiados e pontiagudos." e dois tratadores "Tim" e
"qualquer outro". Agora clique em Save Changes.

264 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Como você pode ver, suas mudanças foram obviamente efetuadas nesta instancia, mas o que aconteceu
com a classe? Volte para a ZClasse ZooExhibit e observe a ta bela de propriedades ExhibitProperties.
Nada foi mudado! Mudanças na instancia não tem efeito na classe.

Você pode também fornecer valores padrão para as propriedades na Tabela de Propriedades. Você
poderia, por exemplo, entrar o texto "Descreva sua exibição nesta caixa" na propriedade description da
ZClasse ZooExhibit. Agora, volte para seu diretório Exhibits e crie um novo objeto ZooExhibit e clique na
visualização Edit. Aqui, você ve que o valor fornecido na tabela de propriedades não mudou. Valores
padrão permitem a você configurar informações usuais nas propriedades da ZClasse que podem depois
ser mudadas uma base instancias-por-instancia.

Você pode querer voltar para sua ZClasse e clicar na tabela Views e modificar a visualização "Edit" para
fazer a primeira visualização clicando no botão First. Agora, quando você clica na sua instancia, ela irá
mostrar a visualização Edit primeiro.

Criando Métodos na sua ZClasse

A visualização Methods de sua ZClasse permite a você definir os métodos para as instâncias de suas
ZClasses. Vá para a sua ZClasse ZooExhibit e clique na tabela Methods. A visulaização Methods é como
na Figura 12-8.

Você pode criar qualquer tipo de objeto Zope na Visualização Methods, mas geralmente somente
objetos CALLABLE (Métodos DTML e Scripts, por exemplo) são adicionados.

Métodos são utilizados para vários propósitos:

Apresentação Quando você associa uma visualização com um método, o método é chamado quando
um usuário seleciona a visualização em uma instância. Por exemplo, se você tem um método DTML
chamado showAnimalImages, e uma visualização chamada Images, você pode associar o método
showAnimalImages com a visualização Images. Toda vez que alguém clicar na visualização Images na
instância de sua ZClasse, o método showAnimalImages será chamado.

Lógica Métodos não são necessariamente associados com visualizações. Métodos que são
frequentemente criados definem como você pode trabalhar com seu objeto. Por exemplo, considere o
método isHungry da ZClasse ZooExhibit definida na seção anterior. Ela não define uma visualização
para ZooExhibit, ela apenas fornece informações muito específicas sobre ZooExhibit. Métodos em uma
ZClasse pode chamar cada um dos outros assim como qualquer outro método Zope, então métodos
lógicos podem ser usados a partir de um método de apresentação, mesmo que ele não defina uma
visualização.

265 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Objetos Compartilhados Como foi apontado recentemente, você pode criar qualquer tipo de objeto na
visualização Methods de uma ZClasse. Todas as instâncias de sua ZClasse compartilhará os objetos na
visualização Methods. Por exemplo, se você criar uma ZGadfly Connection na visualização Methods de
sua ZClasse, então todas as instâncias da classe compartilhará a mesma conexão Gadfly. Objetos
compartilhados pode ser usuados para a lógica da classe ou métodos de apresentação.

Um bom exemplo de um método de apresentação é um método DTML que mostra uma Exibição de
Zoológico para sua visualização em um website. Isto é frequentemente chamado public interface para
um objeto e é usualmente associado com a visualização View encontrada na maioria dos objetos Zope.

Crie um novo método DTML na tabela Methods de sua ZClasse ZooExhibit chamad index_html. Como
todos os objetos nomeados index_html, esta será a apresentação padrão para o objeto nele definido, ou
seja, instâncias de sua ZClasse. Insira o seguinte DTML no método index_html que você acabou de
criar.

<!--
<dtml-var standard_html_header>
<h1><dtml-var animal></h1>
<p><dtml-var description></p>
<p>The <dtml-var animal> caretakers are:<br>
<dtml-in caretakers>
<dtml-var sequence-item><br>
</dtml-in>
</p>
<dtml-var standard_html_footer>
-->

Agora, você pode visitar uma de suas instâncias ZooExhibit diretamente através da web, por exemplo,
http://www.zopezoo.org/Exhibits/FangedRabbits/ mostrará a interface pública para a exibição Coelho
com garras.

Você pode utilizar scripts baseado em Python ou baseados em Perl, e cada um dos métodos lógicos Z
SQL implementados. Seus objetos lógicos podem chamar outros, e podem ser chamados por um
método de apresentação. Para criar um método isHungry, primeiro crie duas novas propriedades na
página de propriedades ExhibitProperties chamada "last_meal_time" que é do tipo date e
"isDangerous" que é do tipo boolean. Isto adiciona dois novos campos para sua visualização Edit onde
você pode digitar a última vez que o animal foi alimentado e selecionar se o animal é ou não perigoso.

Aqui está um exemplo de uma implementação do método isHungry em Python:

## Script (Python) "isHungry" ## """ Returns true if the animal hasn't eaten in over 8 hours """ from
DateTime import DateTime if (DateTime().timeTime() - container.last_meal_time.timeTime() > 60 60
8): return 1 else: return 0

O recipiente deste método se refere a uma instância da ZClasse. Então você pode usar o recepiente em
uma instância ZClasse do mesmo modo como você usa em métodos Python normais.

Você pode chamar este método de seu método de DISPLAY index_html usando este recorte de DTML:

<dtml-if isHungry>
<p><dtml-var animal> is hungry</p>
</dtml-if>

Você pode até chamar um número de métodos lógicos de seu método de DISPLAY. Por exemplo, você
pode melhorar o mostra de fome desse modo:

266 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-if isHungry>
<p><dtml-var animal> is hungry.
<dtml-if isDangerous>
<a href="notify_hunger">Tell</a> an authorized
caretaker.
<dtml-else>
<a href="feed">Feed</a> the <dtml-var animal>.
</dtml-if>
</p>
</dtml-if>

Seu método DISPLAY agora chama métodos lógicos para decidir quais ações são apropriadas e criar
links para aquelas ações. Para mais informações na Propriedades, veja o capítulo 3, "Usando Objetos
Básicos do Zope".

ZClasses ObjectManager

Se você escolheu ZClasses:ObjectManager como uma base de classes para suas ZClasses então
instâncias de suas classes estarão habilitadas a conter outros objetos Zope, apenas como pastas. Classes
recipientes são identicas a outras ZClasses com a exceção que elas possuem uma visualização adicional
Subobjects.

Desta visualização você pode controlar que tipos de objetos suas instâncias podem conter. Por exemplo
se você criou uma classe recipiente FAQ, você deve restringí-la para alimentar objetos Perguntas e
Respostas. Selecione um ou mais meta-types da lista de seleção e clique no botão Change. Os objetos
devem aparecer na lista de pastas de controle de caixas marcadas se são ou não instâncias de sua classe
recipiente e são mostradas no painel de navegação como objetos expandíveis.

ZClasses recipientes podem ser muito poderosas. Um padrão muito comum para aplicações web é ter
duas classes que trabalham juntas. Uma classe implementa o comportamento e alimentação básica dos
dados. A outra classe contém instâncias da classe básica e fornece métodos para organizar e listar o
conteúdo das instâncias. Você pode modelar muitos problemas deste modo, por exemplo um
gerenciador de ingressos pode conter problemas de ingressos, ou um repositório de documentos pode
conter documentos, ou um roteador de objetos pode conter regras de roteamento, e assim por diante.
Tipicamente as classes recipientes fornecerão métodos para adicionar, deletar, e restaurar ou localizar
objetos recipientes.

Controles de Segurança da ZClasse

Quando são construídos novos tipos de objetos, a seguarnça pode representar uma importante função.
Por exemplo, as três funções seguintes são necessárias no seu Zoo:

Administrador
Esta função existe por padrão no Zope. Este é você, e alguém mais o qual você queira que esteja
habilitado para gerenciar completamente seu sistema Zope.

Tratadores
Após você criar uma instância ZooExhibit, você quer que os usuários com a função tratador esteja
habilitado para editar exibições. Somente usuários com esta função devem estar habilitados para ver a
visualização Edit de uma instância ZooExhibit.

Anonimo
Esta função existe por padrão em Zope. Pessoas com a função anonimo devem estar abilitadas para
visualizar a exibição, mas não gerenciá-la ou mudá-la de qualquer maneira.

Como você aprendeu no capítulo 7, "Usuários e segurança", criar novas funções é fácil, mas como você

267 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

pode controlar quem pode criar e editar novas instâncias? Para fazer isto, você deverá definir algumas
políticas de segurança na ZClasse ZooExhibit que controla o acesso a ZClasse e sua folha de
propriedades e métodos.

Controlando o Acesso a Métodos e Folhas de Propriedades

Por padrão, o Zope tenta ser sensível sobre a segurança das classes. Você pode, no entanto, querer
controlar o acesso a instâncias de sua ZClasse de um modo especial.

Por exemplo, os tratadores do Zoológioco estão realmente interessados em ver a visualização Edit (e
possivelmente a visualização Undo, a qual nós mostraremos depois), mas definitivamnete não a
visualização de Segurança ou Proprietário. Você não quer os tratadores do Zoológico mudando as
configuraçòes de segurança em suas Exibições: você não quer até mesmo que eles vejam estes aqueles
aspectos de uma Exibição, você apenas quer dar a eles a habilidade de editar uma exibição e nada mais.

Para fazer isto, você necessita criar um novo objeto Zope de permissão no produto ZooExhibit (não a
ZClasse, permissões são definidas somentre nos produtos). Para fazer isto, vá para o produto
ZooExhibit e selecione Zope Permissiaon da lista de adição. Dê a nova permissão o Id
"edit_exhibit_permission" e o nome "Edit Zoo Exhibits" e clique em gerar.

Agora, selecione sua ZClasse ZooExhibit, e clique na tabela Permissions. Isto levará você para a
visualização das permissões como mostrado na figura 12-9.

Esta visualização mostra para você quais permissões sua ZClasse usa e deixa você escolher permissões
adicionais para usar. Na direita está uma lista de todas sa permissões padrão Zope que sua ZClasse
herad automaticamente. Na esquerda estão múltiplas caixas de seleção onde você pode adicionar novas
permissões para sua classe. Selecione a permissão Edit Zoo Exhibits nesta caixa e clique em Save
Changes. Isto avisa a sua ZClasse que ela é interessante nesta permissão bem como as permissões na
direita.

Agora, clique na tabela Property Sheets e selecione a folha de propriedades ExhibitProperties. Clique na
tabela Define Permission.

Você quer informar a esta folha de propriedades que somente os usuários que possuem a permissão
Edit Zoo Exhibit que você criou podem gerenciar as propriedades na folha ExhibitProperties. Nesta
visualização, arraste para baixo a caixa selecionada e escolha Edit Zoo Exhibit. Isto irá mapear o Edit
Zoo Exhibits para a permissão Manage Properties na folha. Esta lista de permissões você pode
selecionar a partir da visualização da ZClasse Permissions de onde você está, e devido a você selecionar
a permissão Edit Zoo Exhibit na tela, ela aparece na lista para você selecionar. Note que todas as opções

268 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

padrão para disable cad uma permite que a folha de propriedades não possa ser editada por qualquer
um.

Agora, você pode voltar para sua pasta Exhibits e selecionar a visualização Security. Aqui, você pode ver
que sua nova permissão está na esquerda na lista de permissões habilitadas. O que você quer fazer
agora é criar uma nova função chamada Tratador e mapear esta nova função para a permissão Edit Zoo
Exhibits.

Agora, os usuários devem ter a função tratador em ordem para ver a visualização Edit em qualquer de
suas instâncias ZooExhibits.

Acesso para objetos na visualização dos métodos de sua Zclasse são controladas da mesma maneira.

Controlando o Acesso a Instâncias de sua ZClasse

A seção anterior explicou como você pode controlar o acesso a instâncias dos métodos e propriedades
de sua ZClasse. O controle de acesso está controlando quem pode criar novas instâncias de sua ZClasse.
Como você viu recentemente no capítulo, instâncias são criadas por FACTORIES. FACTORIES são
associados com permissões. No caso do Zoo Exhibit, a permissão Add Zoo Exhibits controla a
habilitação para criar instâncias de Zoo Exhibit.

Normalmente somente Administradores terão a permissão Add Zoo Exhibit, então somente
Administradores estarão habilitados a criar novas Zoo Exhibits.No entanto, como todas as permissões
Zope, você pode mudar cada uma das funções que tem esta permissão em diferentes lugares do seu site.
É importante perceber que estas permissões são controladas separadamente da permissão Edit Zoo
Exhibits. Isto torna possível permitir que algumas pessoas assim como os tratadores modifiquem, mas
não criem Zoo Exhibits.

Fornecendo Ajuda Sensível ao Contexto à sua ZClasse

Na tela Views de sua ZClasse, você pode ver que cada visualização pode ser associada com um Help
Topic. Isto permite a você fornecer um link para um tópico de Ajuda diferente dependendo em qual
visualização o usuário está. Por exemplo, criaremos um tópico de ajuda para a visualização Edit da
ZClasse ZooExhibit.

Primeiro, você precisa criar objeto de tópico de ajuda atual. Isto é feito indo até o produto ZooExhibit
que contém a ZClasse ZooExhibit, e clicando na pasta Help. O ícone deverá ser visto como uma pasta
com uma interrogação azul marcada nela.

Dentro desta pasta especial, puxe para baixo a lista de adição e selecione Help topic. Dê a este tópico o
id "ExhibitEditHelp" e o título "Ajuda para a edição de Exibições" e clique em Add.

Agora você verá que a pasta Help contém um novo objet de tópico de ajuda chamado ExhibitEditHelp.
Você pode clicar neste objeto e editá-lo, ele trabalha apenas como um documento DTML. Neste
documento, você deve colocar a informação de ajuda que você quer mostrar para seus usuários:

<dtml-var standard_html_header>
<h1>Help!</h1>
<p>To edit an exhibit, click on either the <b>animal</b>,
<b>description</b>, or <b>caretakers</b> boxes to edit them.</p>
<dtml-var standard_html_footer>

Agora que você criou o tópico de ajuda, você necessita associar com a visualização Edit de sua ZClasse.
Para fazer isto, selecione a ZClasse ZooExhibit e clique na tabela Views. À direita, na mesma linha como
a visualização Edit é definida, puxe para baixo a caixa selecionada de ajuda e selecione ExhibitEditHelp

269 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

e clique em Change. Agora vá para uma de suas instâncias ZooExhibit, a visualização Edit agora tem um
link Help! que você pode clicar para observar seu tópico de ajuda para esta visualização.

Na próxima seção, você verá como ZClasses podem ser combinadas com classes padrão Python para
extendê-las funcionalmente em Python puro.

Usando Classes Básicas do Python


ZClasses dão a você uma interface de gerenciamento web para desenvolver novos tipos de objetos em
Zope. No início deste capítulo, nós mostramos a você como você pode selecionar de uma base de classes
para subclasses de sua ZClasse. A maioria desta classes bases estão atualmente escritas em Python, e
nesta seção você verá como você pode obter suas próprias classes Python e incluí-las na lista a qual sua
ZClasse pode extender seus métodos.

Escrever classes base Python é fácil, mas envolve alguns detalhes de instalação. Para criar uma classe
base Python você necessita acessar ao sistema de arquivos. Crie um diretório dentro de seu diretório
lib/python/Products chamado AnimalBase. Neste diretório crie um arquivo chamado Animal.py com
este conteúdo:

class Animal: """ A base class for Animals """ _hungry=0 def eat(self, food, servings=1): """ Eat food """
self._hungry=0 def sleep(self): """ Sleep """ self._hungry=1 def hungry(self): """ Is the Animal hungry?
""" return self._hungry

Esta classe define conjunto de métodos relacionados e um atributo padrão. Note que como método
externo, os métodos desta classe podem acessar atributos privados.

Próximo você necessita registrar sua classe base com Zope. Criar um arquivo init.py no diretório
AnimalBase com este conteúdo:

from Animal import Animal def initialize(context): """ Register base class """
context.registerBaseClass(Animal)

Agora você necessita reiniciar o Zope em ordem para ele encontrar sua base de classes. Após reiniciar o
Zope você pode verificar que sua base de classes está registrado em um conjunto de diferentes
maneiras. Primeiro vá até a pasta Products no painel de controle e procure por um pacote AnimalBase.
Você deverá ver um produto com uma caixa fechada. Se você ver a caixa aberta, isto significa que há
alguma coisa errada com seu produto AnimalBase.

Clique na visualização traceback para ver um TRACEBACK Python mostrando qual é o problema Zope
que está ocorrendo no Zope na tentativa de registrar sua base de clases. Uma vez que você resolver
qualquer problema que sua base de classes possa ter você necessitará reiniciar o Zope novamente.
continue este processo até que o Zope carregue com sucesso seu produto. Agora você pode criar uma
nova ZClasse e você deve ver AnimalBase:Animal como uma opção no campo de seleção da base de
classes.

Para testar sua nova base de classes crie uma ZClasse que herde de AnimalBase:Animal. Enfeite seu
animal do modo como desejar. Crie um métopdo DTML chamado care com este conteúdo:

270 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<dtml-var standard_html_header>
<dtml-if give_food>
<dtml-call expr="eat(cookie)">
</dtml-if>
<dtml-if give_sleep>
<dtml-call sleep>
</dtml-if>
<dtml-if hungry>
<p>I am hungry</p>
<dtml-else>
<p>I am not hungry</p>
</dtml-if>
<form>
<input type="submit" value="Feed" name="give_food">
<input type="submit" value="Sleep" name="give_sleep">
</form>
<dtml-var standard_html_footer>

Agora crie uma instância de sua classe animal e teste seu método care. O método care permite que você
alimente seu animal e deixe-o dormir chamando métodos definidos em sua base de classes Python.
Note também como após alimentar seu animal ele não está com fome, mas se você der a ele uma soneca
ele acorda faminto.

Como você pode ver, criar seus próprios produtos e ZClasses é um processo envolvente, mas simples
para entender uma vez que você compreende o básico. Com ZClasses sozinhas, você pode criar algumas
belas aplicações Web complexas corretas em seu navegador web.

Na próxima seção, você verá como criar uma distribuição de seu produto, então você poderá
compartilhar ela com outros ou cedêr-la para uma personalização.

Distribuindo Produtos
Agora que você criou seu próprio produto que permite a você criar qualquer número de exibições no
Zope. Supomos que você tem um amigo em outro Zoológico o qual está impressionado com o seu novo
sistema de exibições online, e quer obter um sistema similar para o seu Zoológico.

Talves você até pertença a "Associação americana de sustentação dos Zoológicos" e você quer estar apto
a dar seu produto a qualquer interessado em um sistema de exibições similar ao seu. Zope deixa você
distribuir seus produtos como um, pacote fácil de transportar que outros usuários podem copiar de
você e instalar em sistema Zope.

Para distribuir seu produto, clique no produto ZooExhibit e selecione a tabela Distribuição. Isto levará
você para a visualização Distribution.

O formulário nesta visualização permite a você controlar a distribuição que você quer criar. A caixa
Version deixa você especificar a versão para a distribuição de seu produto. Para toda a distribuição que
você faz, o Zope irá incrementar este número para você, mas pode querer especificá-lo você mesmo.
Apenas deixe-o para o padrão de "1.0" a menos que você queira mudá-lo.

Os próximos dois radio buttons permite que você selecione ou não se você quer que outros estejam
habilitados para personalizar e redistribuir o produto. Se você quer que eles personalizem ou
resistribuam seu produto sem nenhuma restrição, selecione o button Allow Redistribution. Se você não
quer permitir que eles estejam habilitados a redistribuir seu produto, selecione o button Disallow
redistribution and allow the user to configure only the selected objects:. Se você não permitir a
redistribuição, você pode escolher em uma base objeto por objeto qual de seus usuários podem
personalizar seu produto. Se você não quer que eles estejam aptos a mudar qualquer coisa, então não
selecione qualquer dos ítens nesta lista. Se você quer que eles estejam habilitados a mudar a ZClasse
ZooExhibit, então selecione somente a ZClasse. Se você que que eles estejam habilitados a modificar

271 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

tudo (mas ainda não estão habilitados a redistribuir seu produto) então selecione todos os objetos desta
lista.

Agora, você pode criar uma distribuição de seu produto clicando em Create a distribution archive. O
Zope irá agora gerar automaticamente um arquivo chamado ZooExhibit-1.0.tar.gz. Este produto pode
ser instalado em qualquer Zope assim como qualquer outro produto, descompactando-o no diretório
raiz de sua instalação Zope.

Não esqueça que quando você distribuir seu produto você também necessitará incluir qualquer arquivo
igual aos arquivos de métodos externos e bases de classes Python que sua classe contar. Estas
requisições tornam a distribuição mais difícil e por esta razão pessoas algumas vezes tentam evitar
contar com arquivos Python quando criam através da web produtos para distriobuição.

16. Apêndice A: Referência da DTML


Dtml é um linguagem de marcação para modelos de documentos, uma útil apresentação
e modelo de linguagem o qual sucede com respeito a o Zope. Esse apêndice é a referência
para todos os DTMLs suas tags e como elas trabalham.
call: Chamando um Método
A tag call permite você inserir de fora o resultado dentro do produto DTML.

Sintaxe

sintaxe da tag call

<dtml-call Variavel|expr="Expressao">

Se a tag call usa uma variável, o método que os argumentos são transferidos automaticamente pelo
DTML da mesma forma que var tag. Se o método é especificado na expressão, então você deve passar o
argumento você mesmo.

Exemplos
Chamando por nome variável

<dtml-call AtualizarInformacao>

Esta chamada a AtualizarInformacao objeto automático de documento passageiro.

Chamando por Expressão

<dtml-call expr="RESPONSE.setHeader(content-type, text/plain)">

Veja Também
tag var
comment: Comentários do DTML
A tag Comment permite você fazer comentários em seu documento DTML. Você pode além disso usar
temporariamente desativando tags no DTML comentando -as e deizando de fora.

272 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Sintaxe
sintaxe tag comment

<dtml-comment>

</dtml-comment>

A tag comment é um bloco tag.O conteúdo deste bloco não são executaveis nem são inseridos no
produto DTML.

Exemplos
Documentar DTML

<dtml-comment>
Isto é um comentário não executável e aparece no documento final.
</dtml-comment>

Comentando out DTML

<dtml-comment>
Este DTML é incapacitado e não dispõe de ser executado.
<dtml-call someMethod>
</dtml-comment>

functions: Funções do DTML


Funções

abs(número)

Devolve o valor absoluto de um número. O argumento pode ser um inteiro smples ou longo
ou um número de ponto flutuante. Se o argumento é um número complexo, sua magnitude
é devolvida.

chr(inteiro)

Devolve uma string de um caráter cujo código ASCII é um inteiro, por exemplo, chr(97)
retorna a string a. Este é o inverso de ord (). O argumento deve estar no alcance 0 a 255,
inclusive;ValueError será elevado se o inteiro está fora deste alcance.

DateTime ()

Retorna um Zope DateTime objeto que determina argumentos de constução. Veja o


DateTime referência de API para mais informação em argumentos de construção.

divmod(número, número)

Tendo dois números como argumentos devolve um par de números que consistem no

273 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

quociente deles e resto quando usando divisão longa. Com tipos de operações misturados,
se aplicam as regras para operadores de aritmética binários. Para planície e inteiros longos,
o resultado é igual a (a / b, a % b). Para números de ponto flutuantes é o resultado (q, a %
b), onde q normalmente é math.floor(a / b) mas pode ser 1 menos que isso. math.floor(a / b)
mas pode ser 1 menos que isso. ath.floor(a / b) mas pode ser 1 menos que isso. th.floor(a /
b) mas pode ser 1 menos que isso. Em todo caso q * b + a % b é muito perto de a, se a%
b é diferente de zero isto tem o mesmo sinal como b, e 0 <= abs(a% b) <abs(b).

float(number)

Converte uma string ou um número para ponto flutuante. Se o argumento é uma string,
tem que conter um decimal possivelmente válido ou número de ponto flutuante,
possivelmente embutido em whitespace,; isto se comporta idêntico a string.atof(number).
Caso contrário, o argumento pode ser um inteiro claro ou longo ou um número de ponto
flutuante, e um número de ponto flutuante com o mesmo valor (dentro de Python o ponto
flutuante é preciso) é devolvido.

getattr(object, string)

Devolve o valor do nome atribuído do objeto. nome deve ser uma string. Se a string é o
nome de um do objeto atributos, o resultado é o valor daquele atributo. Por exemplo,
getattr(x, foobar ") é equivalente a x.foobar. Se o atributo nomeado não existe, se
determinado é devolvido default, caso contrário AttributeError é elevado.

getitem(variável, render=0)

Retorna o valor de uma variável de DTML. Se render é verdadeiro, a variável é renderizada.


Veja a função render.

hasattr(objeto, string)

Os argumentos são um objeto e uma string. O resultado é 1 se a string for o nome de um dos
atributos do objeto, 0 se não. (Isto é implementado chamando getattr(objeto, nome) e
vendo se eleva uma exceção ou não.) hash(objeto) Devolva o valor hash do objeto (se tem
um). valores hash são inteiros. Eles são usados pararapidamente comparar dicionário chave
durante um lookup de dicionário. Valores numéricos que comparam igual têm o mesmo
valor de hash (até mesmo se eles são de tipos diferentes, por exemplo 1 e 1.0).

has_key(variável)

Retorna verdadeiro se a DTML contém variável nomeada.

hex(inteiro)

Retorna um número inteiro (de qualquer tamanho) para uma string de hexadecimal. O
resultado é uma expressão de Python válida. Nota: isto sempre rendimentos um literal não
assinado, por exemplo em uma máquina 32-bit , hex(-1) se rende 0xffffffff. Quando avaliou
em uma máquina com o mesmo palavra tamanho, este literal é avaliado como -1; com uma
palavra de tamanho diferente, pode virar para cima como um número positivo grande ou

274 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

eleva uma exceção de OflowError.

int(número)

Converte uma string ou número para um inteiro claro. Se o argumento é uma string, tem
que conter um número decimal possivelmente válido representado como um inteiro de
Python, possivelmente encaixado em whitespace; isto se comporta idêntico para
string.atoi(number [, radix] ). O parâmetro de radix dá a base para a conversão e
pode ser qualquer inteiro entre 2 a 36. Se radix é especificado e o número não é uma string,
TypeError é elevado. Caso contrário, o argumento pode ser um inteiro claro ou longo ou um
número de ponto flutuante. Conversão de números de ponto flutuantes para inteiros é
definida pela semântica de C; normalmente a conversão trunca para zero.

len(sequecia)

Devolve o tamanho (o número de itens) de um objeto. O argumento pode ser uma série de
(string, tuple ou lista) ou um mapeamento (dicionário).

max(s)

Com um único argumento s, devolve o maior item de uma sequência não vazia (por
exemplo, uma string, tuple ou lista). Com mais de um argumento, devolve o maior dos
argumentos.

min(s)

Com um único argumento s, devolva o menor item de uma sequência nã vazia (por exemplo,
uma string, tuple ou lista). Com mais que um argumento, devolve o menor dos argumentos.

namespace([name=value]...)

Retorna um DTML namespace objeto novo. São empurrados Keyword argumento


name=value pares no namespace novo.

oct(inteiro)

Converte um número de inteiro (de qualquer tamanho) para uma string de octal. O
resultado é uma expressão de Python válida. Nota: isto sempre produz um literal não válido
, por exemplo em uma máquina 32-bit , oct(-1) se rende 037777777777. Quando avaliou em
uma máquina com o mesmo tamanho de palavra , este literal é avaliado como -1; a um
palavra de tamanho diferente, pode virar para cima como um número positivo grande ou
eleva uma exceção de OverflowError.

ord(character)

Devolva o valor de ASCII de uma string de um caracter. Por exemplo, ord ("a ") retorna o
inteiro 97. Este é o inverso de chr ().

275 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

pow(x, y [,z])

Devolve x ao power y; se z está presente, retorna x para o power y, modulo z (processo mais
eficiente que pow(x, y)%z). Os argumentos têm que ter tipos numéricos. Com tipos de
operand misturados, se aplicam as regras para operadores de aritmética binários. O tipo de
operand efetivo também é o tipo do resultado; se o resultado não é nenhum expressible
neste tipo, a função eleva uma exceção; por exemplo, pow(2, -1) ou pow(2, 35000) não é
permitido.

range([start,] stop [,step])

Esta é uma função versátil para criar listas que contêm progressões de aritmética. Os
argumentos devem ser inteiros claros. Se o argumento step é omitido, o default é 1. Se o
argumento start é omitido, o default é 0. Retorna de forma completa uma lista de inteiros
claros [start, start + step, start + 2 * step, ...]. Se step é positivo, o
último elemento é o maior start + i step menor que stop; se step é negativo, o último
elemento é o maior start + i step maior que stop. step não deve ser nenhum zero (ou
então ValueError é elevado).

round(x [,n])

Devolve o valor de ponto flutuante que x arredondou a dígitos de n depois do ponto de


fração decimal. Se n é omitido, o default recebe zero. O resultado é um número de ponto
flutuante. São arredondados valores ao múltiplo de 10 para superioridade menos n; se dois
múltiplos são igualmente arredonda equivalente a diferente de 0 (assim por exemplo
round(0.5) é 1.0 e round(-0.5) é -1.0).

render(object)

Objeto render. Para DTML este objeto avalia o DTML codifica com o namespace atual. Para
outros objetos, isto é equivalente a str(object).

reorder(s [,with] [,without])

Reordena os itens em s de acordo com a ordem dada em with e without os itens


mencionados em without. Os itens de s não mencionados em with é removido. s, with, e
without são todos qualquer sequência de string ou sequência de key-value tuples, with
ordena e mostra nas keys. Esta função é útil para construir listas selecionadas ordenadas.

SecurityCalledByExecutable()

Retorna verdadeiro se o objeto atual (por exemplo DTML documento ou método) está
sendo chamado por um executável (por exemplo, outro DTML documento ou método, uma
escritura ou um método de SQL).

SecurityCheckPermission(permission, objeto)

Confira se o contexto de segurança permite a determinada permissão no determinado

276 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

objeto. Por exemplo, SecurityCheckPermission (" Adiciona Documentos,


Imagens, e Arquivos ", isto ()) devolveria verdadeiro se o usuário atual
estivesse autorizado para criar documentos, imagens, e arquivos na localização atual.

SecurityGetUser()

Retorna o objeto do usuário atual. Isto normalmente está igual ao objeto


REQUEST.AUTHENTICATED_USER. Porém, o Objeto de AUTHENTICATED_USER é
inseguro desde que pode ser substituído.

SecurityValidate([object] [,parent] [,name] [,value])

Retorna verdadeiro se o valor é acessível ao usuário atual. objeto é o objeto no que o valor
teve acesso, o pai é o recipiente do valor, e nome é nomeado usado para o acesso do valor
(por exemplo, se fosse obtido por getattr). Você pode omitir alguns dos argumentos,
porém é melhor fornecer todos os argumentos disponíveis.

SecurityValidateValue(object)

Retorna verdadeiro se o objeto é acessível ao usuário atual. Esta função é o mesmo que
chamar SecurityValidate(None, None, None, objeto).

str(object)

Devolve uma string que contém um bem representado de um objeto. Para string, isto
devolve a própria string.

test(condição, resultado [,condição, resultado]... [,default])

Objetos capturados em uma ou mais condição, resulta par e retorna o resultado da primeira
condição verdadeira. Só um resultado é devolvido, mesmo que mais de uma condição for
verdade. Se nenhuma condição é verdade e um default é determinado, o default é
devolvido. Se não a condição é verdade e não há nenhum default, Nenhum é devolvido.

unichr(número)

Devolve uma string de unicode que representa o valor de número como um caracter de
unicode. Este é o inverso de ord () para unicode caracter.

unicode(string [, codificando [, erros]])

Decodifica string que usa o codec pora codificar. Reparação de erros é acabado de acordo
com os erros. O comportamento do default é para decodificar UTF-8 em modo rígido,
significado que codificando erros elevam ValueError.

17. Apêndice C: Referência de Modelos de

277 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Página do Zope
Zope Page Templates é uma ferramenta de geração HTML/XML. Este apêndice é uma
referência dos padrões Zope Page Templates: Tag Attribute Language (TAL), TAL
Expression Sintaxe (TALES) e Macro Expansion TAL (METAL).
Visão geral da TAL
O padrão Template Attribute Language (TAL) é uma linguagem de atributos usada para criar modelos
(templates) dinâmicos. Ele permite substituir, repetir ou omitir elementos de um documento.

As instruções (instruçãos) TAL são atributos XML do espaço de nomes (namespace) TAL.Estes
atributos podem ser aplicados a um documento XML ou HTML de forma a fazê-lo agir como um
modelo.

Uma TAL instrução (instrução TAL) tem um nome (o atributo nome)


e um corpo (o valor do atributo). Por exemplo, uma instrução content
será como tal:content=&quot;string:Hello&quot;. O elemento onde uma instrução é
definida é um instrução element. A maioria das instruções TAL
requere expressões, mas a sintaxe e semântica dessas expressões não são parte
da TAL. TALES é recomendada para este propósito.

Namespace da TAL

O URI e alias recomendado para O espaço de nomes TAL são atualmente definidos como:

xmlns:tal="http://xml.zope.org/namespaces/tal"

Isso não é uma URL mas meramente um identificador único. Não espere que um
browser resolva este endereço com sucesso.

Zope não requer uma instrução de espaço de nomes XML quando cria modelos
com um conteúdo do tipo text/html. Entretanto, requer uma instrução de espaço
de nomes XML para todos os outros tipos de conteúdo.

Expressões da TAL

Estas são as instruções tal:

- tal:attributes - muda atributos do elemento dinamicamente.

- tal:define - define variáveis.

- tal:condition - testa condições.

- tal:content - altera o conteúdo de um elemento.

- tal:omit-tag - remove um elemento, sdeixando seu conteúdo.

- tal:on-error - manipula erros.

- tal:repeat - repete um elemento.

278 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

- tal:replace - altera o conteúdo de um elemento e o remove, deixando seu conteúdo.

Expressões usadas em instruções podem retornar valores de qualquer tipo,


embora a maioria das instruções aceitarão apenas strings, ou converterão
valores para uma representação de string. A linguagem de expressão deve definir
um valor denominado nothing que não é uma string. Em particular, este valor é útil
para deletar elementos ou atributos.

Ordem das operações

Quando há apenas uma instrução TAL por elemento, a ordem na


qual eles são executados é simples. Começando pelo elemento raiz,
cada instrução de elemento é executada, então cada um dos seus filhos
é visitado, em ordem, para fazer o mesmo.

Qualquer combinação de instruções podem aparecer nos mesmos elementos,


excetuando-se content e replace que não podem aparecer juntos.

Quando um elemento tem múltiplas instruções, elas são executadas na ordem seguinte:

1. 'define'

2. 'condition'

3. 'repeat'

4. content or 'replace'

5. 'attributes'

6. 'omit-tag'

Desde que a instrução on-error é invocada apenas quando um erro ocorre,


ela não aparece na lista.

O raciocínio por trás desta ordem é o seguinte: você frequentemente quer


utilizar variáveis em outras instruções, então define vem antes.
A próxima coisa a fazer é decidir se esse elemnto será mesmo incluido, então
condition vem a seguir; desde que a condição pode depender de variáveis
recém declaradas, ela vem após define. É de valor poder substituir várias partes
de um elemento com diferentes valores em cada iteração de uma repetição, então
repeat é o próximo. Não faz sentido substituir atributos e descartá-los, então
attributes vem por último. As instruções restantes conflitam, porque
substituem ou editam um elemento da instrução.

Veja também

Visão Geral de TALES

Visão Geral de METAL

279 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

tal:attributes

tal:define

tal:condition

tal:content

tal:omit-tag

tal:on-error

tal:repeat

tal:replace

attributes: Trocando os atributos de um elemento


Sintaxe

tal:attributes sintax::

argument ::= attribute_instrução [; attribute_instrução]*


attribute_instrução ::= attribute_name expression
attribute_name ::= [namespace ':'] Name
namespace ::= Name

*Nota: A inclusão de ponto e vírgula (;) em um elemento 'expression'


deve ser dobrada (;;).*

Descrição

A instrução tal:attributes substitui o valor de um atributo


(ou cria um atributo) com um valor dinâmico. Você pode qualificar o
nome de um atributo com um prefixo de espaço de nomes, por exemplo, html:table, se
você está gerando um documento XML com múltiplos espaços de nomes. O valor para cada
expressão é convertido para uma string se necessário.

Se uma expressão associada a uma atribuição a um atributo retorna


nothing, então o atributo é deletado do elemento da instrução.
Se a expressão retorna default, então este atributo não é modificado.
Cada atribuição é independente, então atributos podem receber valores
em uma mesma instrução na qual alguns atributos são deletados e outros não.

Se você usa tal:attributes em um elemento com um comando tal:replace, a


instrução tal:attributes é ignorada.

Se você usa tal:attributes em um elemento com uma instrução tal:repeat,


a substituição é feita em cada repetição do elemento e a expressão de substituição é
calculada novamente para cada repetição.

280 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Exemplos

Substituindo um link::

<a href="/sample/link.html"
tal:attributes="href here/sub/absolute_url">

Substituindo dois atributos::

<textarea rows="80" cols="20"


tal:attributes="rows request/rows;cols request/cols">

condition: Condicionando a inserção ou remoção de um


elemento
Sintaxe

tal:condition sintax::

argument ::= expression

Descrição

A instrução tal:condition inclui o elemento no modelo somente se a condição


é satisfeita e omite caso contrário. Se a expressão retorna verdadeiro, então o
processamento normal do elemento continua, caso contrário o elemento é imediatamente
removido do modelo. Por isso, nothing é falso e default é verdadeiro.

Nota: Zope considera variáveis ausentes, None*, zero, strings vazias e sequências
vazias como falso; todos os outros valores equivalem a verdadeiro.*

Exemplos

Testar uma variável antes de inserí-la (o primeiro exemplo testa pela existência
e verdade, enquanto que o segundo testa apenas pela existência)::

<p tal:condition="request/message | nothing"


tal:content="request/message">message goes here</p>

<p tal:condition="exists:request/message"
tal:content="request/message">message goes here</p>

Testar para condições alternativas::

<div tal:repeat="item python:range(10)">


<p tal:condition="repeat/item/even">Even</p>
<p tal:condition="repeat/item/odd">Odd</p>
</div>

content: Trocando o conteúdo de um elemento

281 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Sintaxe

tal:content sintax::

argument ::= (['text'] | structure) expression

Descrição

Ao invés de substituir um elemento por inteiro, você pode inserir texto ou estrutura
no lugar de seus filhos atrvés de tal:content. O argumento da expressão é exatamente
igual ao de tal:replace e é interpretado da mesma forma. Se a expressão retorna nothing,
a instrução é deixada sem filhos. Se a expressão retorna default, então o conteúdo do
elemento não é modificado.

*Nota: O comportamento de substituição default é text.*

Exemplos

Inserindo o nome do usuário::

<p tal:content="user/getUserName">Fred Farkas</p>

Inserindo HTML/XML::

<p tal:content="structure here/getStory">marked <b>up</b>


content goes here.</p>

Veja também

'tal:replace'

define: Definindo variáreis


Sintaxe

tal:define sintax::

argument ::= define_scope [; define_scope]*


define_scope ::= (['local'] | global) define_var
define_var ::= variable_name expression
variable_name ::= Name

*Nota: A inclusão de ponto e vírgula (;) em um elemento 'expression'


deve ser dobrada (;;).*

Descrição

A instrução tal:define define variáveis. Você pode definir dois


diferentes tipos de variáveis TAL: local e global. Quando você define uma local
em um elemento de instrução, você so pode utilizar esta variável neste elemento e nos
elemntos por ele contidos. Se você redefine uma variável local em um elemento contido,
a nova definição esconde a anterior dentro do elemento contido. Quando você define

282 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

variáveis globais, você pode utilizá-la em qualquer elemento que segue a definição.
Se você redefine uma global, sua definição é substituída para o restante do modelo.

Nota: variáveis locais são o default

Se uma expressão associada a uma variável retorna nothing, então esta variável tem o
valor nothing, e pode ser usada como tal em expressões seguintes. Da mesma forma,
se a expressão retorna default, então esta variável tem o
valor default, e pode ser usada como tal em expressões seguintes.

Exemplos

Definindo uma variável global::

tal:define="global company_name string:Zope Corp, Inc."

Definindo duas variáveis, onde a segunda depende da primeira::

tal:define="mytitle template/title; tlen python:len(mytitle)"

omit-tag: Removendo um elemento, deixando seu conteúdo


Sintaxe

tal:omit-tag sintax::

argument ::= [ expression ]

Descrição

A instrução tal:omit-tag deixa o conteúdo de uma tag no lugar enquanto omite as


tags de início e fim.

Se a expressão retorna falso, então o processamento normal do elemento prossegue


e a tag não é omitida. Se retornar verdadeiro ou se não houver expressão, a instrução
da tag é substituída por seu conteúdo.

Nota: Zope considera variáveis ausentes, None*, zero, strings vazias e sequências
vazias como falso; todos os outros valores equivalem a verdadeiro.*

Exemplos

Omitindo uma tag incondicionalmente::

<div tal:omit-tag="" comment="This tag will be removed">


<i>...but this text will remain.</i>
</div>

Omitindo uma tag condicionalmente::

<b tal:omit-tag="not:bold">I may be bold.</b>

283 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

O exemplo acima omitirá a tag b se avariável bold é falsa.

Criando tags de dez parágrafos, sem tag de fechamento::

<span tal:repeat="n python:range(10)"


tal:omit-tag="">
<p tal:content="n">1</p>
</span>

on-error: Manipulando erros


Sintaxe

tal:on-error sintax::

argument ::= (['text'] | structure) expression

Descrição

A instrução tal:on-error provê manipulação de erros para o modelo.


Qual uma expressão TAL produz um erro, seu interpretador busca por uma
instrução tal:on-error no mesmo elemento, no elemento que o contém e assim
por diante. A primeira tal:on-error encontradaé invocada e tratada como
uma instrução tal:content.

Uma variável local error é criada. Esta variável tem os seguintes atributos:

type -- tipo da exceção

value -- a instãncia da exceção

traceback -- o objeto de traceback

O tipo mais simples de instrução tal:on-error possui uma string literal


de erro ou nothing para uma expressão. Um manipulador mais complexo pode
chamar um script que examina o erro e emite uma mensagem de erro ou propaga
a exceção a frente.

Exemplos

Mensagem de erro simples::

<b tal:on-error="string: Usuário não definido!"


tal:content="here/getUsername">Ishmael</b>

Remivendo elementos com erros::

<b tal:on-error="nothing"
tal:content="here/getUsername">Ishmael</b>

Chamando um script de manipulação de erro::

284 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

<div tal:on-error="structure here/errorScript">


...
</div>

Abaixo como este script ficaria::

## Script (Python) "errHandler"


##bind namespace=_
##
error=_['error']
if error.type==ZeroDivisionError:
return "<p>Não posso dividir por zero.</p>"
else
return """<p>Um erro ocorreu.</p>
<p>Tipo do erro: %s</p>
<p>Valor: %s</p>""" % (error.type, error.value)

Veja também

"Python Tutorial: Errors and


Exceptions":http://www.python.org/doc/current/tut/node10.html

"Python Built-in
Exceptions":http://www.python.org/doc/current/lib/module-exceptions.html

repeat: Repetindo um elemento


Sintaxe

tal:repeat sintax::

argument ::= variable_name expression


variable_name ::= Name

Descrição

A instrução tal:repeat replica uma sub-árvore de seu documento


uma vez para cada item em uma sequência. A expressão deve retornar
uma sequência. Se a sequência for vazia, então o elemento é deletado,
caso contrário é repetido para cada valor na sequência. Se a expressão
for default, então o elemento não é modificado e nenhuma nova
variável é definida.

A expressão variable_name é usada para definir uma variável local


e uma de repetição. Para cada repetição, a variável local recebe o
elemento atual e a de repetição recebe um objeto de iteração.

Variáveis de repetição

Você utiliza variáveis de repetição para acessar informação sobre


a repetição atual (como o índice de repetição). A variável de

285 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

repetição tem o mesmo nome que a variável local, mas só é acessível


através da variável embutida denominada repeat.

As informações a seguir são disponibilizadas da variável de repetição:

o index - número de repetição, começando de zero.

o number - número de repetição, começando de um.

o even - verdadeiro para repetições indexadas por pares (0, 2, 4, ...).

o odd - verdadeiro para repetições indexadas por ímpares (1, 3, 5, ...).

o start - verdadeiro para a repetição inicial (index 0).

o end - verdadeiro para repetição final.

o first - verdadeiro para o primeiro elemento em um grupo - veja nota abaixo

o last - verdadeiro para o último elemento em um grupo - veja nota abaixo

o length - tamanho da sequência, que será o número total de repetições.

o letter - número de repetição como uma letra minúscula: "a" -


"z", "aa" - "az", "ba" - "bz", ..., "za" - "zz", "aaa" - "aaz",
e assim por diante.

o Letter - versão upper-case de letter.

o roman - número de repetição como numeral romano minúsculo:


"i", "ii", "iii", "iv", "v", etc.

o Roman - versão upper-case de roman.

Você pode acessar o conteúdo da variável de repetição usando


expressões de caminho (path expressions) ou expressões Python.
Em expressões de caminho, você escreve um caminho de três partes
consistindo de do nome repeat, o nome da variável da instrução
e o nome da informação que você deseja, por exemplo, repeat/item/start.
Em expressões Python, você usa a noatação normal de dicionário para
obter a variável de repetição, então o atributo para obter a informação,
por exemplo, "python:repeat['item'].start".

Note que first e last são usados em sequências ordenadas.


Eles tentam dividir a sequência em um grupode itens com o mesmo
valor. Se você provê um caminho, então o valor obtido seguindo este
caminho de um item de sequência é usado para agrupamento, caso contrário
o valor do item é utilizado. Você pode prover um caminho passando-o
como parâmetro, como em "python:repeat['item'].first(color)", ou
apendando-o ao caminho da variável de repetição como em "repeat/item/first/color".

Exemplos

286 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

Iterando sobre uma sequência de strings::

<p tal:repeat="txt python:one, two, three">


<span tal:replace="txt" />
</p>

Inserindo uma seuência de linhas de tabela e usando a variável de repetição para


numerar as linhas::

<table>
<tr tal:repeat="item here/cart">
<td tal:content="repeat/item/number">1</td>
<td tal:content="item/Descrição">Dispositivo</td>
<td tal:content="item/preço">R$1.50</td>
</tr>
</table>

Repeats aninhados::

<table border="1">
<tr tal:repeat="row python:range(10)">
<td tal:repeat="column python:range(10)">
<span tal:define="x repeat/row/number;
y repeat/column/number;
z python:x*y"
tal:replace="string:$x $y = $z">1 1 = 1</span>
</td>
</tr>
</table>

Inserir objetos. Separar grupos de objetos por meta-tipo através de uma regra entre eles::

<div tal:repeat="object objects">


<h2 tal:condition="repeat/object/first/meta_type"
tal:content="object/meta_type">Meta Tipo</h2>
<p tal:content="object/getId">ID do Objeto</p>
<hr tal:condition="repeat/object/last/meta_type" />
</div>

Note que os objetos no exemplo acima devem já estar ordenados por meta-tipo.

replace: Trocando um elemento


Sintaxe

tal:replace sintax::

argument ::= (['text'] | structure) expression

Descrição

287 de 288 23/11/2010 14:42


O Livro do Zope — TcheZope.org http://www.tchezope.org/documentacao/manual/o-livro-do-zope/referen...

A instrução tal:replace substitui um elemento com conteúdo dinâmico.


Substitui o elemento com um texto ou uma estrutura (unescaped markup).
O corpo da instrução é uma expressão com um prefixo de tipo opcional.
O valor da expressão é convertido para uma "escaped string" se você prefixar
a expressão com text ou omitir o prefixo e é inserido sem modificações
se você prefixar com structure. "Escaping" consiste de converter
"&amp;" para "&amp;amp;", "&lt;" para "&amp;lt;" e "&gt;" para "&amp;gt;".

Se o valor é nothing, então o elemento é simplesmente removido. Se o valor é default,


então o elemento não é modificado.

Exemplos

As duas formas de inserir o título de um modelo::

<span tal:replace="template/title">Título</span>
<span tal:replace="text template/title">Título</span>

Inserindo HTML/XML::

<div tal:replace="structure table" />

Inserindo nada::

<div tal:replace="nothing">Este elemento é um comentário.</div>

Veja também

'tal:content'

288 de 288 23/11/2010 14:42

Você também pode gostar