Author: | Sidnei da Silva |
---|---|
Contact: | sidnei@plone.org |
Date: | $Date$ |
Version: | $Revision$ |
Web site: | http://sourceforge.net/projects/archetypes |
Archetypes is a framework for developing new content types in Plone. The power of Archetypes is, first, in automatically generating forms; second, in providing a library of stock field types, form widgets, and field validators; third, in easily integrating custom fields, widgets, and validators; and fourth, in automating transformations of rich content.
The project is hosted on the Archetypes Project at SourceForge. The latest version of this document can be always found under the under the docs directory of Archetypes.
Archetypes is currently being tested and run in various environments using the following combination:
It is also known to work smoothly with Zope 2.5.
You should install the validation and generator packages available on the archetypes'sourceforge page before installing Archetypes itself. WARNING: those packages was used to be installed as Zope products, this not the case anymore. They should be installed as regular python package (look at the packages'README file for more info).
Download the latest stable version from the Archetypes Project on Sourceforge.
Decompress it into the Products dir of your Zope installation. It should contain the following directories:
Archetypes ArchExample
You should install the validation and generator packages available on the Archetypes Project page before installing Archetypes itself.
WARNING: those packages used to be installed as Zope products, this not the case anymore. They should be installed as regular python package (look at the packages README file for more info).
Restart your Zope.
Check in the Control Panel of your Zope if everything imported just fine.
Good luck!
If you want to get the latest version of Archetypes from CVS, here is how to do it.
XXX Need more info here.
Quick and dirty:
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
The heart of an archetype is its Schema, which is a sequence of fields. Archetypes includes three stock schemas: BaseSchema, BaseFolderSchema, and BaseBTreeFolderSchema. All three include two fields, 'id' and 'title', as well as the standard metadata fields.
The Schema works like a definition of what your object will contain and how to present the information contained. When Zope starts up, during product initialization, Archetypes reads the schema of the registered classes and automagically generates methods to access and mutate each of the fields defined on a Schema.
You add additional fields to a schema by using one of available field types. These fields share a set of properties (below, with their default values), which you may modify on instantiation. Your fields override those that are defined in the base schema.
More commonly used field properties:
Less commonly used field properties:
This parameter specifies a vocabulary. It can be given either as a static instance of DisplayList or as a method name (it has to be the name as a string). The method is called and the result is taken as the vocabulary. The method should return a DisplayList.
The contents of the vocabulary are used as the values which can be choosen from to fill this field.
An example for a DisplayList usage can be found in the ArchExample directory in config.py.
A string specifying the kind of index to create on portal_catalog for this field. To include in catalog metadata, append :schema, as in FieldIndex:schema. You can specify another field type to try if the first isn't available by using the | character. Both combinations can be used together, as in:
... index="TextIndex|FieldIndex:schema", ...
Here is an example of a schema (from '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] | Depending on the mode of each Field in the Schema the runtime system will look for an accessor or mutator. If, for example, the mode of a field is "rw" (as is the default), then the generator will ensure that accessors and mutators exist for that field. This can happen one of two ways: either you define the methods directly on your class, or you let the generator provide them for you. If you don't require specialized logic, then letting the generator create these methods on your new type is a good idea. The format for accessors and mutators is as follows: field -> title accessor -> getTitle() here/getTitle mutator -> setTitle(value) |
Archetypes provides some pre-defined validators. You use them by passing a sequence of strings in the validator field property, each string being a name of a validator. The validators and the conditions they test are:
The current usefulness of Archetypes' validators is mitigated by weak error messaging, and the lack of support for separators in SSNs, phone numbers, and ZIP codes.
There are also hooks for pre and post validation that can be used to assert things about the entire object. These hooks are:
pre_validate(self, REQUEST, errors) post_validate(self, REQUEST, errrors)
You must extract values from REQUEST and write values into errors using the field name as the key. If pre_validate throws errors, then other custom validators (including post) will not be called.
If you need custom validation, you can write a new validator in your product.:
from 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
Then you need to register it in FooProduct/__init__.py method initialize:
from validation import validation from validator import FooValidator validation.register(FooValidator('isFoo'))
The validator is now registered, and can be used in the schema of your type.
When Archetypes generates a form from a schema, it uses one of the available Widgets for each field. You can tell Archetypes which widget to use for your field using the widget field property. Note, though, that a field cannot use just any widget, only one that yields data appropriate to its type. Below is a list of possible widget properties, with their default values (see 'generator/widget.py'). Individual widgets may have additional properties.
Views are auto-generated for you by default, based on the options you specified on your Schema (Widgets, Fields, widget labels, etc.) if you use the default FTI actions (eg: don't provide an actions attribute in your class. See Additional notes about Factory Type Information).
If you want only to override a few parts of the generated View, like the header or footer, you can:
Create a template named ${your_portal_type_lowercase}_view 2
On this template, you may provide the following macros:
header body footer
When building the auto-generated view, archetypes looks for these macros and includes them in the view, if available. Note that the body macro overrides the auto-generated list of fields/values.
[2] | Currently, this is only implemented for the auto-generated view template. |
Or, for customizing only a widget:
Besides the schema, you can define all of the content properties you see when you click on a content type in the 'portal_types' tool. Here is a list of class attributes, with their default values (see 'ArchetypeTool.py'):
If your class declares to implement IReferenceable, you will get a references tab on your object, allowing you to make references to other objects.
If your class declares to implement IExtensibleMetadata, you will get a properties tab on your object, allowing you to modify the metadata.
Custom actions: Define an actions member on your content type and the external method will apply this to the types tool for you. This means the if you want custom views or something you only need to say something like:
class Foo(BaseContent): actions = ({'id': 'view', 'name': 'View', 'action': 'custom_view', 'permissions': (CMFCorePermissions.View,) },)
There are a few basic storages available by default on Archetypes, including storages that store data on SQL. Here's a listing:
From The Free On-line Dictionary of Computing (09 FEB 02) [foldoc]:
marshalling
<communications> (US -ll- or -l-) The process of packing one or more items of data into a message {buffer}, prior to transmitting that message buffer over a communication channel. The packing process not only collects together values which may be stored in non-consecutive memory locations but also converts data of different types into a standard representation agreed with the recipient of the message.
Marshalling is used in Archetypes to convert data into a single file for example, when someone fetches the content object via FTP or WebDAV. The inverse process is called Demarshalling.
Archetypes currently has a few sample marshallers, but they are somewhat experimental (there are no tests to confirm that they work, and that they will keep working). One of the sample marshallers is the RFC822Marshaller, which does a job very similar to what CMF does when using FTP and WebDAV with content types. Here's what happens, basically:
When putting content back, the inverse is done:
1. The body is separated from the headers, using parseHeadersBody from CMFCore.utils.
2. The body, with the content type, is passed to the mutator of the primary field.
3. For each of the headers, we call the mutator of the given matching field with the header value.
That's it.
To use a Marshaller, you just need to pass a Marshaller instance as one of the arguments for the Schema. For example:
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())
Examples can be found on the ArchExample product, that is included in the download. You can also browse the cvs repository.
To Vladimir Iliev, for contributing with i18n and lots of other nice ideas and Bill Schindler, for lots of nice patches and reviewing documentation.