z3ext.content 0.17.1
z3ext content - Alternative implementation of content types system.
Latest Version: 0.19.0
z3ext:content directive
Alternative implementation of content types system.
>>> import z3ext.content >>> from z3ext.content import interfaces, constraints, item, tests>>> from zope.configuration import xmlconfig >>> context = xmlconfig.file('meta.zcml', z3ext.content)
We can register new content type with z3ext:content directive. Let's create schema and implementation for our type.
>>> from zope import interface, component, schema>>> class IMyContent(interface.Interface): ... ... title = schema.TextLine( ... title = u'Title')>>> class MyContent(item.Item): ... interface.implements(IMyContent) ... ... def __init__(self, title): ... self.title = title>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext" i18n_domain="z3ext"> ... <z3ext:content ... name="myContent" ... title="My content" ... class="z3ext.content.TESTS.MyContent" ... schema="z3ext.content.TESTS.IMyContent" ... description="Simple content type." /> ... </configure>""", context)
We can get content type as named utility.
>>> ctContent = component.getUtility(interfaces.IContentType, 'myContent')>>> ctContent.name, ctContent.klass, ctContent.title (u'myContent', <class 'z3ext.content.TESTS.MyContent'>, u'My content')
We can create content instance
>>> content = ctContent.create(u'Title') >>> isinstance(content, MyContent) True
Content type for content object
>>> print interfaces.IContentType(content) <BoundContentType:z3ext.content.contenttype.ContentType myContent 'My content'>
Content Type binding
We can use content types for various tasks like adding new content, check availability of content type, etc. Content type should be bound to some context
>>> interfaces.IBoundContentType.providedBy(ctContent) False>>> print ctContent <ContentType:z3ext.content.contenttype.ContentType myContent 'My content'>
Now we need content
>>> from zope.app.container.sample import SampleContainer >>> container = SampleContainer()
Now let's bind content type to container
>>> bctContent = ctContent.__bind__(container)>>> interfaces.IBoundContentType.providedBy(bctContent) True>>> print bctContent <BoundContentType:z3ext.content.contenttype.ContentType myContent 'My content'>
Content Type availability
Unbound content type is always unavailable. By default z3ext.content register only one checker for permission checks.
>>> ctContent.isAvailable() False>>> bctContent.isAvailable() True
We can define new avilability checks. We need new adapter to IContentTypeChecker interface. We define checker that fail is content type name is 'failed.container'
>>> class NameChecker(object): ... interface.implements(interfaces.IContentTypeChecker) ... component.adapts(interfaces.IContentType, interface.Interface) ... ... def __init__(self, contenttype, context): ... self.contenttype = contenttype ... self.context = context ... ... def check(self): ... return not (self.contenttype.name == 'failed.container')>>> component.provideAdapter(NameChecker, name='mychecker')>>> bctContent.name = 'failed.container' >>> bctContent.isAvailable() False>>> bctContent.name = 'any' >>> bctContent.isAvailable() True>>> sm = component.getSiteManager() >>> t = sm.unregisterAdapter(NameChecker, name='mychecker')
Adding Content
We can add content only if container content type can contain content types. Let's register container content type
>>> from z3ext.content.container import ContentContainer>>> class IMyContainer(interfaces.IItem): ... pass>>> class MyContainer(ContentContainer): ... interface.implements(IMyContainer)>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext" i18n_domain="z3ext"> ... <z3ext:content ... name="myContainer" ... title="My container" ... class="z3ext.content.TESTS.MyContainer" ... schema="z3ext.content.TESTS.IMyContainer" ... description="Simple container type." /> ... </configure>""", context)>>> ctContainer = component.getUtility(interfaces.IContentType, 'myContainer')
Unbound container can't contain any content
>>> list(ctContainer.listContainedTypes()) []>>> container = MyContainer('Container')>>> bctContainer = ctContainer.__bind__(container) >>> [ct.name for ct in bctContainer.listContainedTypes()] [u'myContent', u'myContainer']>>> content = ctContent.create('Title')
We can't add content with unbound content type
>>> ctContent.add(content, 'test-content') Traceback (most recent call last): ... Unauthorized: Can't create '' instance>>> bctContent = ctContent.__bind__(container) >>> addedContent = bctContent.add(content, 'test-content') >>> addedContent.__name__ u'test-content'>>> container[u'test-content'] is content True
But if conten type not in container content type types listing we won't able to add content.
>>> interface.directlyProvides(ctContent, interfaces.IInactiveType) >>> t = sm.unregisterUtility(ctContent, interfaces.IActiveType, ctContent.name)>>> [ct.name for ct in bctContainer.listContainedTypes()] [u'myContainer']>>> content = ctContent.create(u'Title')>>> addedContent = bctContent.add(content, 'test-content2') Traceback (most recent call last): ... InvalidItemType: ...
ContentType Type
We can use any number of types in type attribute of directive. By default package defines some types.
IInactiveType - for inactive types, this type can't be added to any container also if we won't use 'factory' then content type marked as inactive automaticly
>>> ct = component.getUtility(interfaces.IContentType, 'myContent') >>> interfaces.IInactiveType.providedBy(ct) True>>> [ct.name for ct in bctContainer.listContainedTypes()] [u'myContainer']
IActiveType - for content that can be added to any content container
>>> class IContent1(interfaces.IItem): ... pass>>> class Content1(item.Item): ... interface.implements(IContent1)>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext" i18n_domain="z3ext"> ... <z3ext:content ... name="content1" ... title="content1" ... schema="z3ext.content.TESTS.IContent1" ... class="z3ext.content.TESTS.Content1" ... type="z3ext.content.interfaces.IActiveType" ... description="Simple content type." /> ... </configure>""", context)>>> [ct.name for ct in bctContainer.listContainedTypes()] [u'myContainer', u'content1']
IExplicitlyAddable - if content type is explicitly addable then it can be added only to container that explicitly contains content type
>>> class IContent2(interfaces.IItem): ... pass>>> class Content2(item.Item): ... interface.implements(IContent2)>>> context = xmlconfig.string(""" ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext" i18n_domain="z3ext"> ... <z3ext:content ... name="content2" ... title="content2" ... schema="z3ext.content.TESTS.IContent2" ... class="z3ext.content.TESTS.Content2" ... type="z3ext.content.tests.ITestContentType ... z3ext.content.interfaces.IExplicitlyAddable" ... description="Simple content type." /> ... </configure>""", context)>>> [ct.name for ct in bctContainer.listContainedTypes()] [u'myContainer', u'content1']
Now let's add content type to precondition, it is the same if we use contains="mypackage.interface.IMyType"
>>> precondition = component.queryUtility( ... constraints.IItemTypePrecondition, bctContainer.name) >>> precondition.ifaces = precondition.ifaces + (tests.ITestContentType, )>>> [ct.name for ct in bctContainer.listContainedTypes()] [u'myContainer', u'content1', u'content2']
CHANGES
0.17.1 (2008-10-15)
- Fix available list content types
0.17.0 (2008-10-15)
- Prepare for removing auto generating content type maker interfaces.
- contenttype attribute is makrer interface for content type.
- ctclass custom content type implementation
0.16.0 (2008-10-08)
- Use 'contents.html' link for content in contents view
- If container contains index.html content show it instead of listing
- Added IRenameNotAllowed marker interface
- Added container contents ordering
- Use z3ext.content i18n domain for transaltions
- Use zc.copy for content copy
0.15.0 (2008-08-28)
- Added IPortalType,IActivePortalType types
- Using content schema for content creation
- Added short name validation for add/edit forms
0.14.3 (2008-08-13)
- Use new pageelement api
- Added rename field to content edit form
0.14.2 (2008-08-07)
- Fixed content creation, if content class doesn't have__init__
- Added addform attribute for z3ext:content directive, it allow use custom add form
0.14.1 (2008-08-05)
- Fixed container __delitem__
- Fixed ContentType.create method
- Tests updated
0.14.0 (2008-08-04)
- IItem is optional now
- Custom breadcrumb for content objects
- Added support for ordered containers
0.13.2 (2008-07-28)
- Fixed edit form
0.13.1 (2008-07-24)
- Added 'cancel' button to edit form
0.13.0 (2008-05-26)
- Moved content actions to z3ext.ui.contentactions
- Moved content byline to to z3ext.ui.contentbyline
- Use viewlet for rendering content layout
0.12.0 (2008-04-08)
- Added content actions
0.11.4 (2008-04-01)
- Code cleanup
0.11.3 (2008-03-17)
- Use z3ext.contextlayout for context
0.11.2 (2008-02-28)
- Use z3c.autoinclude
0.11.1 (2008-02-25)
- Code cleanup
0.11 (2008-02-20)
- Replace zope.formlib with z3c.form
0.10.2 (2008-02-18)
- Removed rwproperty.py from package
- Fixed bug with View context link in context information
- Added default adapter to IContentAdding
- Added getContentType to IContentAdding interface returns bound IContentType object
- Added viewlet structure for content view
- Added viewlet structure for content byline
0.10.1 (2008-02-12)
- Move some code to z3ext.contentextensions package
0.10 (2008-02-04)
- Rename 'for' to 'schema' for z3ext:content directive
0.9.1 (2008-02-02)
- Fixed missing import
0.9.0 (2008-02-01)
- Initial release.
| File | Type | Py Version | Uploaded on | Size | # downloads |
|---|---|---|---|---|---|
| z3ext.content-0.17.1.tar.gz (md5) | Source | 2008-10-15 18:11:34 | 41KB | 56 | |
- Author: Nikolay Kim <fafhrd91 at gmail com>
- Home Page: http://z3ext.net/
- License: ZPL 2.1
- Categories
- Package Index Owner: fafhrd
- DOAP record: z3ext.content-0.17.1.xml
