1.
Referências Básicas do Archetypes
Um nível acima
Introdução
O Archetypes é um framework para desenvolvimento de novos tipos de conteúdos no Plone. O poder do Archetypes está, primeiramente, na geração automática de formulários; segundo, no fornecimento de uma biblioteca de tipos de campos estocados, formulários widgets, e validadores de campos; terceiro, na facilidade de integração de campos customizados, widgets, e validadores; e quarto, na transformação automática em conteúdo rico.
O projeto está hospedado em Archetypes Project no SourceForge. A última versão deste documento sempre pode ser encontrada no diretório docs do Archetypes.
Instalação
Requerimentos
O Archetypes está atualmente testado e rodando em vários ambientes usando a seguinte combinação:
- Zope 2.6.2+
- CMFPlone 1.0.4
- CMF 1.3.1
Usando o tarball
-
Faça download da última versão estável em Archetypes Project no Sourceforge.
-
Decompacte-o dentro do diretório Products da sua instalação de Zope. Ele conterá os seguintes diretórios:
Archetypes
ArchExample -
Você deverá instalar os pacotes validation e generator disponíveis na página Archetypes Project antes de isntalar o próprio Archetypes.
AVISO: Estes pacotes eram usados para serem instalados como produtos Zope, este não é mais o caso. Eles devem ser instalados como pacotes regulares do Python (veja nos pacotes o arquivo README para mais informações).
-
Reinicie o seu Zope.
-
Verifique no Control Panel do seu Zope se todos foram importados corretamente.
-
Boa sorte!
Checagem pelo CVS
Usando Windows
Se você quer obter a última versão do Archetypes do CVS, aqui está como fazê-lo.
- Obtenha o TortoiseCVS de http://prdownloads.sourceforge.net/tortoisecvs/TortoiseCVS-1-2-2.exe
- Faça o download e instale o programa.
- Reinicie se necessário.
XXX Necessita mais informações aqui.
Usando *nix
Curto e grosso:
cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/archetypes login
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/archetypes co Archetypes
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/archetypes co ArchExample
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/archetypes co validation
cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/archetypes co generator
Schema
O coração de um archetype é o seu Schema, que é uma seqüência de campos. O Archetypes inclui três schemas estocados: BaseSchema, BaseFolderSchema, e BaseBTreeFolderSchema. Todos os três incluem dois campos, 'id' e 'title', assim como os campos metadado padrão.
O Schema trabalha com uma definição do que o seu objeto conterá e como será apresentada a informação contida. Quando o Zope é iniciado, durante a inicialização do produto, o Archetypes lê o schema da classe registrada e automaticamente gera métodos para acessar e modificar cada campo definido no Schema.
Campos
Você adiciona campos adicionais a um schema usando um dos tipos de campos disponíveis (available field types). Esses campos compartilham uma série de propriedades (abaixo, estão esses valores padrões), que podem ser modificadas por você na instanciação. Seus campos sobrepõem aqueles que são definidos no schema de base.
Propriedades de campos mais comumente usadas:
- required
- Cria o campo requerido na validação. Padrão é 0 (não é requerido).
- widget
- Um dos Widgets a serem usados para mostrar e editar o conteúdo do campo determinado.
Propriedades de campos menos comumente usadas:
- default
- Conjunto de valores padrão dos campos na inicialização.
- vocabulary
-
Este parâmetro especifica um vocabulário. Ele pode ser obtido também como uma instância estática de DisplayList ou como um método name (ele tem que ter name como uma string). O método é chamado e o resultado é pego como o vocabulário. O método retornará uma DisplayList.
Os conteúdos do vocabulário são usados como os valores que podem ser selecionados para preencher este campo.
Um exemplo para uso de uma DisplayList pode ser encontrado no diretório ArchExample no config.py.
- enforceVocabulary
- Se usado, checa se o valor está contido na fila do vocabulary na validação
- multiValued
- Se usado, permite ao campo ter múltiplos valores (ex. uma lista) no lugar de um simples valor
- isMetadata
- Se usado, o campo é considerado um metadado
- accessor 1
- Nome do método que será usado para obter dados fora do campo. Se o método já existir, nada é feito. Se o método não existir, o Archetypes gerará um método básico para você.
- edit_accessor
- Nome do método que será usado para obter dados fora do campo somente após a edição. Diferente do método padrão accessor que pode aplicar alguma transformação para o dado acessado, este método retornará dados sem qualquer transformação. Se o método já existir, nada é feito. Se o método não existir, o Archetypes gerará um método básico para você.
- mutator
- Nome do método que será usado para mudar o valor do campo. Se o método já existir, nada é feito. se o método não existir, o Archetypes gerará um método básico para você.
- mode
- Um dos r, w ou rw. Se r, somente o accessor é gerado. Se w somente o mutator e o edit accessor são gerados. Se rw, accessor e mutator e o edit accessor são gerados.
- read_permission
- Permissão necessária para visualizar o campo. O padrão é CMFCorePermissions.View. É checado quando a visualização é autogerada.
- write_permission
- Permissão necessária para visualizar o campo. O padrão é CMFCorePermissions. ModifyPortalContent. É checado quando o formulário submetido é processado.
- storage
- Uma das opções de Armazenamento. O padrão é AttributeStorage, que atribui um simples atributo para a instância.
- generateMode
- Desaprovado?
- force
- Desaprovado?
- validators
- Um dos Validadores. Você também pode criar o seu próprio validador.
- index
-
Uma string especificando a espécie de índice para criar no portal_catalog para este campo. Para incluir no catálogo de metadados, adicione :schema, como em FieldIndex:schema. Você pode tentar especificar outro tipo de campo, se o primeiro não estiver disponível, usando o caractere |. Ambas as combinações podem ser usadas juntas, como em:
...
index="TextIndex|FieldIndex:schema",
... - schemata
-
Schemata é usado para agrupar campos dentre fieldsets. O padrão é default em campos normais e metadata em campos metadados.
Aqui está um exemplo de um schema (de 'examples/SimpleType.py'):
schema = BaseSchema + Schema((
TextField("body",
required=1,
searchable=1,
default_output_type="text/html",
allowable_content_types=("text/plain",
"text/restructured",
"text/html",
"application/msword"),
widget = RichWidget,
),
))
| [1] |
Dependendo do modo de cada Campo no Schema o tempo de execução do sistema verificará um accessor ou mutator. Se, por exemplo, o modo do campo é "rw" (como é o padrão), então o gerador assegurará que accessors e mutators existem para aquele campo. Isto pode acontecer de uma forma ou de outra: em uma das duas você define os métodos diretamente na sua classe, ou você deixa o gerador fornecer para você. Se você não requer lógica especializada, então deixar o gerador criar estes métodos no seu novo tipo é uma boa idéia. O formato para accessors e mutators é como a seguir: field -> title |
Validadores
O Archetypes fornece alguns validadores pré-definidos. Você usa-os passando uma seqüência de strings para a propriedade do campo validator, cada string contém um nome de um validador. Os validadores e as condições possuem os seguintes testes:
- inNumericRange
- O argumento deve ser numérico
- isDecimal
- O argumento deve ser decimal, talvez positivo ou negativo, talvez em notação científica
- isInt
- O argumento deve ser um inteiro, talvez positivo ou negativo
- isPrintable
- O argumento deve conter unicamente um ou mais alfanuméricos ou espaços
- isSSN
- O argumento deve conter somente nove dígitos (sem separador) (Número do Seguro Social?)
- isUSPhoneNumber
- O argumento deve conter somente 10 dígitos (sem separadores)
- isInternationalPhoneNumber
- O argumento deve conter somente um ou mais dígitos (sem separadores)
- isZipCode
- O argumento deve conter somente cinco ou nove dígitos (sem separadores)
- isURL
- O argumento deve conter uma URL válida (incluindo o protocolo, sem espaços ou novas linhas)
- isEmail
- O argumento deve conter um endereço de e-mail válido
A atual utilidade dos validadores do Archetypes é aliviar com delicadas mensagens de erro, a carência de suporte para separadores em SSNs, números de telefone, e códigos postais.
Lá estão também ganchos para pré e pós-validação que podem ser usados para declarar coisas sobre o objeto completo. Estes ganchos são:
pre_validate(self, REQUEST, errors)
post_validate(self, REQUEST, errors)
Você deve extrais valores do REQUEST e escrever os valores nos errors usando o nome do campo como chave. Se pre_validate lançar erros, então validadores customizados (incluindo envios) não serão chamados.
Escrevendo um validador customizado
Se você precisa customizar validação, você pode escrever um novo validador no seu produto:
from Products.validation.interfaces import ivalidator
class FooValidator:
__implements__ = (ivalidator,)
def __init__(self, name):
self.name = name
def __call__(self, value, *args, **kwargs):
if value == 'Foo':
return """Validation failed"""
return 1
Então você precisa registrá-lo no método de inicialização FooProduct/__init__.py:
from Products.validation import validation
from validator import FooValidator
validation.register(FooValidator('isFoo'))
O validador está registrado agora, e pode ser usado no schema do seu tipo.
Widgets
Quando o Archetypes gera um formulário em um schema, ele usa um dos Widgets disponíveis para cada campo. Você pode perceber no Archetypes qual widget será usado por seus campos usando a propriedade do campo widget. Perceba, apesar, que um campo não pode usar simplesmente qualquer widget, somente um dado apropriado em produção para este tipo. Abaixo está uma lista de possíveis propriedades widget, com seus valores padrão (veja 'generator/widget.py'). Widgets individuais podem ter propriedades adicionais.
- attributes
- Usado para??
- description
- A dica para este campo. Aparece em resposta para onFocus.
- description_msgid
- Id i18n para a descrição
- label
- É usado como o rótulo para o campo quando renderiza o formulário
- label_msgid
- Id i18n para o rótulo
- visible
- O padrão é 1. Use 0 para renderizar um campo oculto, e -1 para pular a renderização.
Views
Views são auto-geradas para você por padrão, baseado nas opções que você especificou no seu Schema (Widgets, Campos, rótulos widget, etc.) se você usa a ação FTI padrão (ex: não fornece um atributo actions na sua classe. Veja Notas adicionais sobre Factory Type Information).
Customizando Views
Se você quer somente impor algumas partes para a View gerada, como o cabeçalho e o rodapé, você pode:
- Criar um template nomeado ${your_portal_type_lowercase}_view 2
-
Neste template, você pode fornecer os seguintes macros:
header
body
footer -
Quando construir a view autogerada, o archetypes olha para estes macros e os inclui na view, se disponível. Note que o a macro body excede a lista de campos/valores autogerados.
| [2] | Atualmente, esta é a única implementação para autogerar o template view. |
Ou, para customizar somente uma widget:
- Ajuste os atributos macro_view ou macro_edit para a localização do seu macro customizada na instanciação da Widget.
- Seu template do macro customizado deverá conter um macro com tanto o mesmo nome como o modo que ele será usado. Ex: um template que está sendo usado em macro_view deve ter um macro denominado view. O mesmo se aplica a macro_edit e edit.
Atributos da Classe
além do schema, você pode definir todas as propriedades de conteúdo que você vê quando você clica em um tipo de conteúdo na ferramenta 'portal_types'. Aqui está a lista dos atributos da classe, com seus valores padrão (veja 'ArchetypeTool.py'):
Atributos/métodos de classe padrão
- modify_fti : method
- É encontrado no módulo e chamado antes do registro do produto. Trabalha como um gancho para permitir que você modifique a factory type information padrão fornecida pelo Archetypes.
- add${classname} : method
- É encontrado no módulo. Se ele não existe, uma básica é autogerada para você.
- content_icon
- Um nome de uma imagem (que deve estar disponível no contexto do seu objeto) para ser usada como um ícone para o seu tipo de conteúdo dentro do CMF.
- global_allow
- Ativa o global_allow padrão na factory type information padrão.
- allowed_content_types
- Ativa o allowed_content_types padrão ajustando a factory type information padrão. Se ajustado, sobrepõem o filter_content_types no caso de ele não estiver contido na classe.
- filter_content_types
- Ativa o filter_content_types padrão ajustando a factory type information padrão.
Notas adicionais sobre Factory Type Information
-
Se a sua classe é declarada para implementar IReferenceable, você obterá uma aba references no seu objeto, permitindo a você criar referências a outros objetos.
-
Se a sua classe é declarada para implementar IExtensibleMetadata, você obterá uma aba properties no seu objeto, permitindo a você modificar os metadados.
-
Ações customizadas: Define as ações do membro no seu tipo de conteúdo e o método externo aplicará isso à ferramenta de tipos para você. Isso significa que se você quer customizar views ou alguma coisa, você necessita somente dizer o que quer:
class Foo(BaseContent):
actions = ({'id': 'view',
'name': 'View',
'action': 'custom_view',
'permissions': (CMFCorePermissions.View,)
},)
Armazenadores
Existem alguns armazenadores básicos disponíveis por padrão no Archetypes, incluindo armazenadores que armazenam dados em SQL. Aqui está uma lista:
- AttributeStorage
- Simplesmente armazena os atributos diretamente na instância.
- MetadataStorage
- Armazena os atributos dentro de um PersistentDict denominado _md na instância.
- ReadOnlyStorage
- Usado para marcar uma chave como ReadOnly
- ObjectManagedStorage
- Usa o método ObjectManager para guardar o atributo dentro da instância. Permite a você criar um objeto de pasta de conteúdo que se comporta como um objeto de conteúdo simples.
- *SQLStorage
- Camada de armazenamento experimental, que põem dados dentro do SQL. As variações disponíveis são: MySQL e PostGRES. Está em implementação inicial em um armazenador Oracle, porém isso está sendo testado no momento.
Marshall
Do The Free On-line Dictionary of Computing (09 FEB 02) [foldoc]:
marshalling
<communications> (US -ll- or -l-) O processo de empacotar um ou mais itens de dados em uma mensagem {buffer}, previamente transmitindo tal buffer de mensagem por um canal de comunicação. O processo de empacotamento não só coleta valores juntos que provavelmente são armazenados em locais de memória não-consecutivos como também converte dados de tipos diferentes em uma representação padrão que de acordo com o recipiente da mensagem.
Marshalling é usado no Archetypes para converter dados em um arquivo simples, por exemplo, quando alguém traz um objeto de conteúdo via FTP ou WebDAV. O processo inverso é chamado Demarshalling.
Atualmente o Archetypes tem alguns marshallers simples, porém eles estão um tanto experimentais (não existem testes para confirmar que eles trabalham, e que permanecerão trabalhando). Um dos marshallers simples é o RFC822Marshaller, que faz um trabalho muito similar ao feito no CMF quando usando FTP e WebDAV com tipos de conteúdos. Aqui está o que acontece, basicamente:
- Procura o primeiro campo para o objeto de conteúdo, se houver.
- Obtém o tipo do conteúdo para o primeiro campo e seu conteúdo.
- Constrói um dicionário com todos os outros campos e seus valores.
- Usa a função formatRFC822Headers do CMFCore.utils para escrever o código do dicionário nos campos RFC822-like.
- Adiciona o primeiro campo de conteúdo como o corpo.
- Retorna o result, content_type e data.
Quando adiciona conteúdo de volta, o inverso é feito:
-
O corpo é separado dos cabeçalhos, usando parseHeadersBody de CMFCore.utils.
- O corpo, com o tipo do conteúdo, é passado para o mutator do primeiro campo.
- Para cada um dos cabeçalhos, nós chamamos o mutator que combina o campo com o valor do cabeçalho.
É isto.
Um exemplo usando um Marshaller
Para usar um Marshaller, você precisa somente passar uma instância de um Marshaller como um dos argumentos para o Schema. Por exemplo:
from Products.Archetypes.Marshall import RFC822Marshaller
class Story(BaseContent):
schema = BaseSchema + Schema ((
TextField('story_description',
primary = 1,
default_output_type = 'text/plain',
allowable_content_types = ('text/plain', 'text/restructured',),
widget = TextAreaWidget(label = 'Description',
description = 'A short story.'
)),
),
marshall = RFC822Marshaller())
Exemplos e mais informação
Exemplos podem ser encontrados no produto ArchExample, que está incluído neste download. Você também pode navegar no repositório cvs.
Agradecimento especial
Ao Vladimir Iliev, pela contribuição com i18n e várias outras boas idéias e Bill Schindler, por vários bons patches e revisão da documentação.