You are not logged in Log in Join
You are here: Home » Members » dedalu » Construir uma lista de itens e pre�os (zclass e zcatalog)

Log in
Name

Password

 

Construir uma lista de itens e pre�os (zclass e zcatalog)

It's a portuguese how-to teaching about zclasses and zcatalog. It's based on kedai " How-To: Build a simple ZClass ", but not is an translation.

O produto em quest�o foi desenvolvido por Thiago e H�lio para a Escola de Veterin�ria da UFMG. O objetivo era criar uma lista de itens e pre�os que pudesse ser pesquisada e que fosse facilmente administrada.

Considera��es

Assumimos que voc� tem bom conhecimento do Zope, sendo desnecess�ria a explica��o minuciosa dos passos apresentados.

Utilizamos Zope 2.3.2, em um sistema operacional Linux, para o desenvolvimento. Vers�es anteriores n�o devem ser problema, entretanto.

Metas

Ao fim desse Como-Fazer, teremos um objeto PrecosFolder, que guardar� objetos PrecosItem, e um cat�logo desses itens. Teremos tamb�m um m�todo para apresentar os itens e seus pre�os numa tabela, bem como um formul�rio de busca e um m�todo para apresentar os resultados em um ou mais PrecosFolder.

O que faremos:

  1. Criar as zclasses PrecosFolder e, dentro dela, PrecosItem
  2. Adicionar propriedades personalizadas
  3. Modificar os scripts de constru��o de PrecosFolder para:
    • editar as propriedades e
    • criar um zcatalog
  4. Modificar os scripts de constru��o de PrecosItem para:
    • criar um Id automaticamente,
    • editar as propriedades e
    • catalogar automaticamente os itens
  5. Permitir edi��o dos objetos:
    • determinar quais abas do Zope ser�o exibidas e
    • criar um script para recatalogar o citem ap�s edi��o
  6. Criar visualiza��es padr�o para os objetos
  7. Testar
  8. Mais...

1. Criar as classes

Em 'Control_Panel/Products', adicione um novo produto ('Add Product') com Id "PrecosFolder" e Title "Lista de Pre�os".

Dentro do produto PrecosFolder rec�m criado adicione uma nova zclass. Preencha com "PrecosFolder" o Id, o Title e o Meta Type. Para que a nova classe possa conter objetos, selecione 'ZClasses:ObjectManager' como classe base. Certifique-se para que as op��es 'Create constructor objects?' e 'Include Standard Zope persistent object base classes?' estejam marcadas.

Clique em 'Add'. Voc� ter� criado a classe PrecosFolder e seus construtores.

Entre na classe PrecosFolder que voc� criou e adicione, novamente, uma zclass. Preencha Id, Title e Meta Type com "PrecosItem". Deixe marcadas as op��es 'Create constructor objects?' e 'Include Standard Zope persistent object base classes?'. Selecione 'ZCatalog: CatalogAware' como classe base. Isso permitir� que PrecosItem seja indexada pelo cat�logo que iremos criar na inst�ncia de PrecosFolder. Clique em 'Add'.

Como resultado voc� obter� a seguinte estrutura:

Estrutura

2. Adicionar propriedades personalizadas

Dentro da classe PrecosFolder, clique na aba 'Property Sheets' e em 'Add Common Instance Property Sheet'. Preencha o Id com "PrecosFolder" e clique em 'Add'.

Entre na rec�m criada folha de propriedades PrecosFolder e adicione o seguinte:

NameTypeValue
"Title"string 

Dentro da classe PrecosItem, de forma semelhante � ilustrada acima, adicione o seguinte � folha de propriedades PrecosItem da classe PrecosItem:

NameTypeValue
"nome"string 
"preco"string 

3. Modificar os scripts de constru��o de PrecosFolder

Tudo o que precisamos fazer � modificar o formul�rio e o m�todo que constroem o objeto para que as propriedades sejam adequadamente preenchidas e para que um zcatalog seja criado automaticamente.

3.1. Editar as propriedades

Substitua o conte�do de PrecosFolder_addForm por:

<html>
<head><title>Adicionar PrecosFolder</title></head> 
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555"> 
<h2>Adicionar PrecosFolder</h2> 
<form action="PrecosFolder_add">
<table> 
<tr>
<th>Id</th> 
<td><input type="text" name="id" /></td> 
</tr> 
<tr>
<th>Titulo</th> 
<td><input type="text" name="title" /></td> 
</tr> 
<tr>
<td colspan="2">
<input type="submit" value=" Adicionar " />
</td>
</tr> 
</table>
</form> 
</body>
</html>

Agora vamos modificar o m�todo inicial para que o objeto tenha o t�tulo que foi inclu�do no formul�rio.

Substitua o conte�do de PrecosFolder_add por:

<html>
<head><title>Adicionar PrecosFolder</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555">

<dtml-with "PrecosFolder.createInObjectManager(REQUEST['id'], REQUEST)">
       <dtml-call "propertysheets.PrecosFolder.manage_editProperties(REQUEST)">
</dtml-with>

<dtml-if DestinationURL>
    <dtml-call "RESPONSE.redirect(DestinationURL+'/manage_workspace')">
<dtml-else>
    <dtml-call "RESPONSE.redirect(URL2+'/manage_workspace')">
</dtml-if>
</body>
</html>

Explicando:
dtml-with "PrecosFolder.createInObjectManager(REQUEST['id'], REQUEST)"
cria o objeto e o seleciona como escopo das vari�veis para que
dtml-call "propertysheets.PrecosFolder.manage_editProperties(REQUEST)"
modifique a folha de propriedades PrecosFolder com base nas vari�veis passadas pelo objeto REQUEST.

3.2. Criando um zcatalog

Adicione o seguinte c�digo a PrecosFolder_add no primeiro dtml-with, para que o zcatalog seja criado dentro do PrecosFolder (e n�o no diret�rio corrente):

<dtml-call "manage_addProduct['ZCatalog'].manage_addZCatalog('catalogoItens','',
              'create_default_catalog_',REQUEST)">
<dtml-with "catalogoItens">
  <dtml-call "manage_delColumns(['summary',],REQUEST,RESPONSE,URL1)">
  <dtml-call "manage_addColumn('nome',REQUEST,RESPONSE,URL1)">
  <dtml-call "manage_addColumn('preco',REQUEST,RESPONSE,URL1)">
  <dtml-call "manage_addIndex('nome','TextIndex',REQUEST,RESPONSE,URL1)">
</dtml-with> 

4. Modificar os scripts de constru��o de PrecosItem

PrecosItem exige uma abordagem mais complicada. Para facilitar a administra��o, optamos por criar Ids automaticamente a partir do nome dado ao item. Como usamos acentua��o e o Id precisa ser compat�vel com o padr�o para URLs, fizemos um script para retirar todos os acentos e caracteres n�o padr�o. Al�m disso, no ato da inclus�o, editaremos as propriedades do objeto e o incluiremos no zcatalog.

4.1. Criar um Id automaticamente

Vamos criar um script python chamado "ide" dentro da classe PrecosFolder, para que possa ser utilizado pelo m�todo PrecosItem_add. Preencha 'Parameter List' com "nome" e o corpo do script com:

id=''
dicionario={' ' : '_', '!' : '_', '"' : '_', 
'#' : '_', '$' : '_', '%' : '_', '&' : '_', 
'\'' : '_', '(' : '_', ')' : '_', '*' : '_', 
'+' : '_', ',' : '_', '-' : '_', '.' : '_', 
'/' : '_', '0' : '0', '1' : '1', '2' : '2', 
'3' : '3', '4' : '4', '5' : '5', '6' : '6', 
'7' : '7', '8' : '8', '9' : '9', ':' : '_', 
';' : '_', '<' : '_', '=' : '_', '>' : '_', 
'@' : '_', 'A' : 'a', 'B' : 'b', 'C' : 'c', 
'D' : 'd', 'E' : 'e', 'F' : 'f', 'G' : 'g', 
'H' : 'h', 'I' : 'i', 'J' : 'j', 'K' : 'k', 
'L' : 'l', 'M' : 'm', 'N' : 'n', 'O' : 'o', 
'P' : 'p', 'Q' : 'q', 'R' : 'r', 'S' : 's', 
'T' : 't', 'U' : 'u', 'V' : 'v', 'W' : 'w', 
'X' : 'x', 'Y' : 'y', 'Z' : 'z', '[' : '_', 
'\\' : '_', ']' : '_', '^' : '_', '_' : '_', 
'`' : ' ', 'a' : 'a', 'b' : 'b', 'c' : 'c', 
'd' : 'd', 'e' : 'e', 'f' : 'f', 'g' : 'g', 
'h' : 'h', 'i' : 'i', 'j' : 'j', 'k' : 'k', 
'l' : 'l', 'm' : 'm', 'n' : 'n', 'o' : 'o', 
'p' : 'p', 'q' : 'q', 'r' : 'r', 's' : 's', 
't' : 't', 'u' : 'u', 'v' : 'v', 'w' : 'w', 
'x' : 'x', 'y' : 'y', 'z' : 'z', '{' : '_', 
'|' : '_', '}' : '_', '~' : '_', ',' : '_', 
'^' : '_', '*' : '_', '-' : '_', '-' : '_', 
'~' : '_', '�' : '_', '�' : '_', '�' : '_', 
'�' : '_', '�' : '_', '�' : '_', '�' : '_', 
'�' : '_', '�' : '_', '�' : '_', '�' : '_', 
'�' : '_', '�' : '_', '�' : '_', '�' : '_', 
'�' : '_', '�' : '_', '�' : '_', '�' : '_', 
'�' : '_', '�' : '_', '�' : '_', '�' : '_', 
'�' : '_', '�' : '_', '�' : '_', '�' : '_', 
'�' : '_', '�' : '_', '�' : '_', '�' : '_', 
'�' : 'a', '�' : 'a', '�' : 'a', '�' : 'a', 
'�' : 'a', '�' : 'a', '�' : 'ae', '�' : 'c', 
'�' : 'e', '�' : 'e', '�' : 'e', '�' : 'e', 
'�' : 'i', '�' : 'i', '�' : 'i', '�' : 'i', 
'�' : '_', '�' : 'n', '�' : 'o', '�' : 'o', 
'�' : 'o', '�' : 'o', '�' : 'o', '�' : '_', 
'�' : '_', '�' : 'u', '�' : 'u', '�' : 'u', 
'�' : 'u', '�' : 'y', '�' : '_', '�' : '_', 
'�' : 'a', '�' : 'a', '�' : 'a', '�' : 'a', 
'�' : 'a', '�' : 'a', '�' : 'ae', '�' : 'c', 
'�' : 'e', '�' : 'e', '�' : 'e', '�' : 'e', 
'�' : 'i', '�' : 'i', '�' : 'i', '�' : 'i', 
'�' : '_', '�' : 'n', '�' : 'o', '�' : 'o', 
'�' : 'o', '�' : 'o', '�' : 'o', '�' : '_', 
'�' : '_', '�' : 'u', '�' : 'u', '�' : 'u', 
'�' : 'u', '�' : 'y', '�' : '_', '�' : 'y', 
'Y' : 'y'}
 
for letra in nome:
	id = id + dicionario[letra]
return id

N�o se preocupe, criamos quase toda a tabela ascii para voc�... � s� copiar :)

4.2. Editar as propriedades

Substitua o conte�do de PrecosItem_addForm por:

<html> 
<head><title>Adicionar PrecosItem</title></head> 
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555"> 
<h2>Adicionar PrecosItem</h2> 
<form action="PrecosItem_add">
<table> 
<tr><th>Item</th> 
    <td><input type="text" name="nome" /></td> 
</tr> 
<tr><th>Pre�o</th> 
    <td><input type="text" name="preco" /></td> 
</tr> 
<tr><td colspan="2" align="center">
<input type="submit" value=" Adicionar " />
</td></tr> 
</table>
</form> 
</body>
</html> 

Substitua o conte�do de PrecosItem_add por:

<html>
<head><title>Adicionar PrecosItem</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555">
<dtml-call "REQUEST.set('id',ide(nome))">
<dtml-with "PrecosItem.createInObjectManager(REQUEST['id'], REQUEST)">
     <dtml-call "propertysheets.PrecosItem.manage_editProperties(REQUEST)">
</dtml-with>
<dtml-if DestinationURL>
     <dtml-call "RESPONSE.redirect(DestinationURL+'/manage_workspace')">
<dtml-else>
     <dtml-call "RESPONSE.redirect(URL2+'/manage_workspace')">
</dtml-if>
</body>
</html>

Acabamos de possibilitar a cria��o de itens com seus respectivos nome e pre�o. Como precisamos de um Id, o criamos partir do nome, alterando os caracteres especiais. Isso foi feito na linha dtml-call "REQUEST.set('id',ide(nome))".

4.3. Catalogar automaticamente os itens

Insira , entre as tags dtml-with "PrecosItem.createInObjectManager(REQUEST['id'], REQUEST)" e /dtml-with o seguinte c�digo:
<dtml-call "manage_editCataloger('catalogoItens')">
<dtml-call reindex_object>

5. Permitir edi��o dos objetos

Como criamos propriedades personalizadas tanto para PrecosFolder quanto para PrecosItem, teremos que alterar tamb�m as abas do Zope que aparecem quando clicamos numa inst�ncia do objeto. No caso de PrecosItem, teremos que criar um formul�rio e um m�todo capazes de recatalogar a inst�ncia editada.

5.1. Determinar quais abas do Zope ser�o exibidas

Antes de definir as abas, vamos definir um m�todo padr�o de exibi��o (e que ser� utilizado como a aba 'View'). Dentro da classe PrecosFolder, crie um m�todo com Id "index_html":

<dtml-var standard_html_header>
<dtml-var MostrarTabela>
<dtml-var standard_html_footer>

O m�todo MostrarTabela ser� criado posteriormente. Optamos por mant�-lo como um m�todo separado pois poder� ser reutilizado em outros casos.

Dentro da classe PrecosFolder, clique na aba 'Views'. Por padr�o haver� apenas "Contents". Adicionaremos as seguintes:

NameMethod
Propertiespropertysheets/PrecosFolder/manage
Viewindex_html
Securitymanage_access
Undomanage_undo

Poderemos assim administrar todas as caracter�sticas de PrecosFolder, incluindo permiss�es de acesso e capacidade de desfazer mudan�as.

5.2. Recatalogar o item ap�s edi��o

Para PrecosItem, entretanto, o formul�rio padr�o 'propertysheets/PrecosItem/manage' n�o � suficiente, j� que n�o reindexa o item no zcatalog.

Dentro da classe PrecosItem, adicione um m�todo com Id "PrecosItemEditForm":

<dtml-var manage_page_header>
<dtml-var manage_tabs>
<form action="PrecosItemEdit">
<table> 
<tr><th>Item</th> 
    <td><input type="text" name="nome" value="&dtml-nome;" /></td> 
</tr> 
<tr><th>Pre�o</th> 
    <td><input type="text" name="preco" value="&dtml-preco;" /></td> 
</tr> 
<tr><td colspan="2" align="center">
<input type="submit" value=" Editar " />
</td></tr> 
</table>
</form>
<dtml-var manage_page_footer>

Adicione, com Id "PrecosItemEdit", o m�todo que processar� o formul�rio acima:

<html>
<head><title>Edit PrecosItem</title></head>
<body bgcolor="#FFFFFF" link="#000099" vlink="#555555">
<dtml-call "propertysheets.PrecosItem.manage_editProperties(REQUEST)">
<dtml-call "manage_editCataloger('catalogoItens')">
<dtml-call reindex_object>
<dtml-if DestinationURL>
  <dtml-call "RESPONSE.redirect(DestinationURL+'/manage_workspace')">
<dtml-else>
  <dtml-call "RESPONSE.redirect(URL2+'/manage_workspace')">
</dtml-if>
</body>
</html>

Dentro da classe PrecosItem, clique na aba 'Views'. Por padr�o haver� "Undo", "Ownership" e "Security". Apague se desejar. Adicionaremos apenas:

NameMethod
EditPrecosItemEditForm

6. Criar visualiza��es padr�o para os objetos

Falta criar o m�todo MostrarTabela, dentro da classe PrecosFolder, e ensinar como criar um formul�rio de busca.

Dentro da classe PrecosFolder, crie um m�todo com Id "MostrarTabela" (modifique as cores segundo sua conveni�ncia):

<table width="100%" border="0" align="center" cellspacing="0">
<tr><td align="center" bgcolor="#5f633d" colspan="2">
<b><dtml-var title_or_id></b>
</td></tr>
<dtml-in catalogoItens sort=id>
<dtml-if sequence-odd>
<tr bgcolor="#ffffff">
<dtml-else>
<tr>
</dtml-if>
	<td align="left" valign="top"><dtml-var nome></td>
	<td align="right" valign="top"><dtml-var preco></td>
</tr>
</dtml-in>
</table>

Como dissemos anteriormente, esse m�todo MostrarTabela poderia ser reutilizado. Ele ser� �til para mostrar os resultados de uma busca. Dentro da classe PrecosFolder, crie um m�todo com Id "searchResults":

<dtml-call "REQUEST.set('nome', chaveBusca(txtbusca))">
<dtml-var MostrarTabela>

O m�todo searchResults utiliza um pequeno script python com Id "chaveBusca" cujo objetivo � acrescentar "*s" �s palavras da busca. Crie-o, com "entrada" como 'Parameter':

from string import split, rstrip
chaves=split(entrada)
chave=''
for i in chaves:
        chave=chave+i+'* '
rstrip(chave)
return chave

7. Testar

Agora crie inst�ncias de PrecosFolder. Note que cada uma delas j� cont�m um zcatalog.

Crie inst�ncias de PrecosItems para suas PrecosFolders. Note que elas s�o catalogadas automaticamente.

Altere os pre�os de seus itens e veja o que acontece com o cat�logo.

Caso voc� deseje ter uma p�gina exibindo todas as listas de pre�o, coloque os seguintes documentos e m�todos no mesmo diret�rio de suas PrecosFolders:

index_html
tipo: DTML Document
conte�do:

<dtml-var standard_html_header>
<h1>Listas de pre�os</h1>
<table width="100%" border="0" align="center">
<tr>
<td align="center" bgcolor="#5f633d" class="cab" colspan="2">Listas</td>
</tr>
<dtml-with expr="PARENTS[0]">
<dtml-in expr="objectValues('PrecosFolder')" sort=title>
	<tr><td>
	<a href="&dtml-absolute_url;"><dtml-var title_or_id></a>
	</td></tr>
</dtml-in>
</dtml-with>
<tr><td align="right"><a href="manage">[editar]</a></td></tr>
<tr><td align="center">
<form action="Results" method="get">
<b>Item:</b> 
<input name="txtbusca" width="30" value="" /> 
<input type="SUBMIT" name="SUBMIT" value="Procurar" />
</form>
</td></tr>
</table>
<dtml-var standard_html_footer>

Results
tipo: DTML Method
conte�do:

<dtml-var standard_html_header>
<dtml-comment>
	Faz a busca em todos os itens do tipo
	PrecosFolder cont�guos.
</dtml-comment>

<dtml-in "objectValues('PrecosFolder')" sort=title>
	<dtml-var searchResults>
	<br /> <br />
</dtml-in "objectValues('PrecosFolder')">
<dtml-var standard_html_footer>

Mais...

Por quest�es est�ticas, seria interessante acrescentar �cones aos objetos que criamos (aqui usamos icon e icon. Para isso, entre em '/Control_Panel/Products/PrecosFolder', clique na aba 'Basic', clique em 'Browse...' e selecione uma figura em formato gif 16x16 para dar upload. Fa�a o mesmo para PrecosItem.

Futuramente alteraremos as permiss�es de seguran�a de PrecosFolder automaticamente para que usu�rios do tipo owner possam adicionar, editar e excluir itens.