4 "Yes, they're stereotypes." - Blur
9 .0WkxKNWM0; .lc:cx' ,kl.
10 .:. 'NMNl..lKWK: .xWNx'
11 .:dONMK. :NWd :OX; 'OWXNNx'
12 .,lkKWMMMMMWk 'co.:NN: . .oNXl..ok, '.
13 .,cxKNMMMMMMNOo;..':dOXWWXc .. l:. 'dXNo. ,c :OWNk'
14 lWMMMMMWMMMMX' cOXMMWKxc' .x0l. l0o. dN' .cKMMXNWWx'
15 dWXxl,.OMMMMK.lWMM0, .'. .c. oolXx. :dl:dWc .cKMMXl..oNMNd.
16 ' .0MMMMd lWMWdlOXWd .o0olXk' .,:lxKK: ;KMMMMXc. 'KMMx
17 .0MMMWc cNMMMXko, .cx, ;x:;kWW0cc0WWXo,,0MMk
18 .0MMMNc :NMMx .cxKX: .dNK; ,kNMMMMNd.
19 .lk0XNNXNMMMMN; :NMWx:dKWMMNOc .. .dXx' .;cc,.
20 .oNMMMMMMMMMMMMMX, cNMMMMXkl,. .oNMMMWk,
21 .kMMMWKkxkOKWMMMMMX, ;Oxc' .:KMMMNNMMW0c.
22 ;WMMM0. .lXMMMNx. .lXMMMXl..dNMMMK;
23 'XMMMWk:. .oc,. cKMMMMMK: .oXMMW0:
24 :NMMMMMWKkc'. :0WMMWKNMMWKc. .lXMWO.
25 .o0WMMMMMMMNk:. .lKWMMNk, .dXMWk' .c,
26 .;lkKWMMMMM0. oNMMMMO. .:'
27 .,lc .c0MMMMk .dNMMMNd.
28 NMMMO. ;WMMMX. .oXMMMNo.
29 0WMMMNxl;,',;oKMMMWd .:OWMMXd'
30 c0WMMMMMMMMMMMMMNo 'xWMXc
36 git+ssh://<username>@repo.or.cz/srv/git/stereotypes.git
37 http://repo.or.cz/r/stereotypes.git
40 http://repo.or.cz/w/stereotypes.git
45 Stereotypes is a content framework for Zope 3. Its target application
46 is a content management system.
48 An abstracted storage layer makes it possible to use the framework
49 with an ORM as well as the ZODB.
51 The content model is based on schemas and containment, allowing
52 flexible and powerful modelling. A dynamic adaptation pattern is
53 introduced to simplify access to the storage layer.
58 stereotypes.annotation
59 Storage implementation that uses annotations
64 Content schemas are defined using ``zope.interface`` and
65 ``zope.schema``, allowing complete separation of model and storage.
67 Content types are comprised of schema mixins and may act as local
70 As an example, consider a document and an event type. The document
71 derives from a standard Dublin Core metadata schema and declares that
72 it's a container for media content and attachments.
74 >>> class IDocument(IContainer, IDCDescriptiveProperties):
75 ... text = zope.schema.Text(title=u"Document text")
76 ... contains(IMedia, IAttachment)
78 >>> class IEvent(IDocument):
79 ... location = zope.schema.TextLine(title=u"Venue location")
80 ... date = zope.schema.Date(title=u"Date")
82 Technically, we can query the containment contraints via the
85 >>> IDocument['__setitem__'].getTaggedValue('precondition').types
86 (<InterfaceClass ...IMedia>,
87 <InterfaceClass ...IAttachment>)
89 To contrast containment, consider another example.
91 >>> class IPhotograph(IDCDescriptiveProperties, IImage):
92 ... location = zope.schema.TextLine(title=u"Shoot location")
94 Here we inherit directly from ``IImage``, instead of declaring
95 containment. This content type requires that an image is provided.
97 Adapting a context to content
98 -----------------------------
100 Let's consider a web application where we have a homogenous object
101 hierarchy based on a general object class ``Page``.
103 We use dynamic adaptation to adapt our page to the schema (this is
104 implemented by the storage layer).
106 >>> document = IDocument(page)
108 This will let us read and write the attributes of a document.
110 >>> document.title = u"How to be a gardener"
111 >>> document.description = u"A complete online guide gardening for beginners."
113 Inversely, we can examine the content on a page:
115 >>> content = IContent(page)
117 [<Content providing IDocument at ...>]
119 If we adapt to a content schema that is a subset of an already defined
120 schema, we retrieve an object that is per-attribute equivalent.
122 >>> descriptive = IDCDescriptiveProperties(page)
123 >>> descriptive.title = document.title
126 This holds even if we modify an attribute on the first object.
128 >>> document.title = u"How to be a farmer"
129 >>> descriptive.title == document.title
132 Similarly, if we first ask for ``IDCDescriptiveProperties``, then
133 ``IDocument``, the same equivalency pertains.
135 >>> document = IDocument(page)
136 >>> descriptive.title = u"How to be an astronaut"
137 >>> descriptive.title == document.title
140 Depending on the storage layer, content may be kept as annotations, or
141 in some other implementation-specific way.
143 Adding contained content
144 ------------------------
146 Content classes may act as containers, and we can use the standard
147 dictionary syntax to add items.
149 >>> document['my-image'] = Image("sunset.jpg")
150 >>> document.values()
151 [<Image("sunset.jpg") at ...>]
153 If we try to add an item that does not meet the constraints, an
156 >>> document['my-string'] = "Sunset"
157 Traceback (most recent call first)
159 TypeError: Disallowed type 'str'