building content types with dexterity

Post on 08-May-2015

4.331 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

David Glick's Plone Conference 2009 tutorial on building content types using Dexterity, an alternative to Archetypes.

TRANSCRIPT

Building Content Typeswith Dexterity

David GlickPlone Conference 2009

Groundwire uses the power of technology to connect people, organizations, and communities working to build a sustainable society.

What is a content type?

A way of categorizingthe items in your site

Page Something Else

Schema

Workflow

Custom view templates

Miscellaneous settings

• Placeful restrictions• Comments• Searchability• Per-type portlet assignments• etc.

History Lesson

http://commons.wikimedia.org/wiki/File:1893_Nina_Pinta_Santa_Maria_replicas.jpg

Content Management Framework (CMF)• Underlying framework for registering

types, assigning workflow• CMFDefault contains sample types which

used to be used by Plone• Not schema-based

Archetypes

• Schema-based form generation• Basis of Plone's current default content

types (ATContentTypes)• Not going away anytime soon

Dexterity

Martin Aspeli

Goals

http://www.fickr.com/photos/paul-w-locke/1662634481/sizes/m/

Make filesystem content type development sane

Make through-the-web content type development sane

Make it possible to switch back and forth between the 2

Philosophy

http://www.fickr.com/photos/ulrichsson/3519217737/

Reuse over reinvention

Produc ts .Arc he type s

Small over big

felds

widgets

base classes

storage

metadataschema

referenceengine

plone .de x te rity

plone.app.dexterity

plone.schemaeditor

z3c.form

plone.behavior

plone.app.relations

plone.directives.*

plone.autoform

plone.supermodel

Natural interaction over excessive generality

diffculty

time

Real code over generated code

Zope 3 over Zope 2

Automated testing over wishful thinking

Let's build a content type!

Installing Dexterity

[buildout]extends = http://dist.plone.org/release/3.3.1/versions.cfg http://good-py.appspot.com/release/dexterity/1.0a2

…[instance]…eggs = … plone.app.dexterity

Installing Dexterity

Dexterity Types Control Panel

Adding a Type

Adding a Type

Adding a 'Plonista' instance

Adding a 'Plonista' instance

The default 'Plonista' view

A few issues

• Bad short name for URL (“plonista”)• Showing lots of metadata fields we don't

care about• We want it to say “Name” instead of “Title”• Doesn't store anything interesting yet :)

...so let's fix it!

Behaviors

ATFile

schema

CustomATFile

s ubc la s s ing

ATFile

schema

behav iors

DexterityFile

model

thumbnailimage

name fromtitle

ratingsgeolocatable

versioned

s c hemae x te ns ion

ATFile

schema

schemaschema

schema Decolayout

Editing the 'Plonista' Behaviors

Disable this to hide the metadata

Enable this to generate short name from title

Adding a Field

Adding a Field

This will replace the title feld that used to come from the Dublin Core behavior.

Adding a Field

Editing a fieldWe are changing the title of this feld to 'Name'.

Edit a revised 'Plonista'

Rapid Prototyping

• The schema object in memory is directly modified, so changes take effect immediately.

• The changes are also serialized to XML and stored in the ZODB (in a property of the FTI), so they are persistent when Zope restarts.

Modifying a Type

• You can add, remove, and rename fields through the web.

• But, values stored in existing instances will not be automatically removed or converted. So be careful.

Some more desired refinements

• Custom add permission• Show the 'bio' field in a separate fieldset.

…we can't do these through the web (at least not yet)

Filesystem roundtripping

Web File s y s tem

Zope 3 Schema

XML schema in FTI

ContentEditing

SchemaEditing

xmlxml

XML schemaon flesystem

py

Schema asPython interface

GenericSetupimport/export

Externaltools

Exporting a type

• GenericSetup export for now;better UI coming :)

Minimal Dexterity package structure

• example.ploneconf09» /example• /ploneconf09

• /__init__.py• /configure.zcml• /profiles

• /default• /metadata.xml• /types.xml• /types

• plonista.xml

» /setup.py

setup.py

setup(name='example.ploneconf09', ... install_requires=[ 'setuptools', 'plone.app.dexterity', # -*- Extra requirements: -*- ], entry_points=""" [z3c.autoinclude.plugin] target = plone """, )

Make sure we automatically get Dexterity

Make sure we don't need a ZCML slug(in Plone 3.3 and greater)

__init__.py

# Nothing to see here; move along. :)

configure.zcml

<configure xmlns="http://namespaces.zope.org/zope" xmlns:grok="http://namespaces.zope.org/grok" xmlns:genericsetup="http://namespaces.zope.org/genericsetup" i18n_domain="example.ploneconf09">

<includeDependencies package="."/> <genericsetup:registerProfile name="default" title="Plone conference Dexterity example" directory="profiles/default" description="Installs the Dexterity example for the Plone conference." provides="Products.GenericSetup.interfaces.EXTENSION" />

</configure>

Loads ZCML for all dependency packages listed in setup.py

types.xml

metadata.xml

<?xml version="1.0"?><object name="portal_types" meta_type="Plone Types Tool"> <object name="plonista" meta_type="Dexterity FTI"/></object>

<metadata> <version>1</version> <dependencies> <dependency>profile-plone.app.dexterity:default</dependency> </dependencies></metadata>

plonista.xml<?xml version="1.0"?><object name="plonista" meta_type="Dexterity FTI" xmlns:i18n="http://xml.zope.org/namespaces/i18n"> <property name="title">Plonista</property> <property name="description">A member of the Plone community.</property> <property name="content_icon">document_icon.png</property> <property name="icon_expr">string:${portal_url}/document_icon.png</property> <property name="factory">plonista</property> <property name="link_target"></property> <property name="immediate_view">view</property> <property name="global_allow">True</property> <property name="filter_content_types">True</property> <property name="allowed_content_types"/> <property name="allow_discussion">False</property> <property name="default_view">view</property> <property name="view_methods"> <element value="view"/> </property> <property name="default_view_fallback">False</property>

plonista.xml (continued) <property name="add_permission">cmf.AddPortalContent</property> <property name="klass">plone.dexterity.content.Item</property> <property name="behaviors"> <element value="plone.app.content.interfaces.INameFromTitle"/> </property> <property name="schema"></property> <property name="model_source">&lt;model xmlns="http://namespaces.plone.org/supermodel/schema"&gt; &lt;schema&gt; &lt;field name="title" type="zope.schema.TextLine"&gt; &lt;description /&gt; &lt;title&gt;Name&lt;/title&gt; &lt;/field&gt; &lt;field name="portrait" type="plone.namedfile.field.NamedBlobImage"&gt; &lt;title&gt;Portrait&lt;/title&gt; &lt;/field&gt; &lt;field name="bio" type="plone.app.textfield.RichText"&gt; &lt;title&gt;Bio&lt;/title&gt; &lt;/field&gt; &lt;/schema&gt; &lt;/model&gt;</property> <property name="model_file"></property>

(These are the Dexterity-specifc bits.)

Can put model in a separate fle.

Can put model in a Zope 3 schema.

plonista.xml (continued)

<alias from="(Default)" to="(selected layout)"/> <alias from="edit" to="@@edit"/> <alias from="sharing" to="@@sharing"/> <alias from="view" to="@@view"/> <action title="View" action_id="view" category="object" condition_expr="" icon_expr="" link_target="" url_expr="string:${object_url}" visible="True"> <permission value="View"/> </action> <action title="Edit" action_id="edit" category="object" condition_expr="" icon_expr="" link_target="" url_expr="string:${object_url}/edit" visible="True"> <permission value="Modify portal content"/> </action></object>

Custom add permission

• In configure.zcml:

• In plonista.xml:

• Add collective.autopermission dependency in setup.py, rerun buildout

<permission id="example.ploneconf09.AddPlonista" title="example.ploneconf09: Add plonista" />

<property name="add_permission">example.ploneconf09.AddPlonista</property>

Using a Zope 3 schema

from zope import schemafrom plone.directives import formfrom plone.namedfile.field import NamedBlobImagefrom plone.app.textfield import RichText

class IPlonista(form.Schema): title = schema.TextLine( title = u'Name', ) portrait = NamedBlobImage( title = u'Portrait', required = False, ) bio = RichText( title=u'Bio', required = False, )

• In plonista.py:

Using a Zope 3 Schema• In configure.zcml:

• Add five.grok to dependencies in setup.py• In plonista.xml:

<configure ... xmlns:grok="http://namespaces.zope.org/grok"> <grok:grok package="."/> ...</configure>

<property name="schema">example.ploneconf09.plonista.IPlonista</property> <property name="model_source"></property>

Specifying a fieldset

class IPlonista(form.Schema): … bio = RichText( title=u'Bio', required = False, ) form.fieldset( 'bio', label=u'Bio', fields=['bio'], )

More form directives

• widget – specify alternate widget• omitted – omits fields• mode – input, display, or hidden• order_before, order_after – adjust position

plone.directives.dexterity

• read_permission• write_permission

Custom view template

• In plonista.py:

from five import grokclass View(grok.View): grok.context(IPlonista) grok.require('zope2.View')

• In plonista_templates/view.pt<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" lang="en" metal:use-macro="context/main_template/macros/master" i18n:domain="example.conference"><body><metal:main fill-slot="main"> <tal:main-macro metal:define-macro="main"> <div tal:replace="structure provider:plone.abovecontenttitle" /> <h1 class="documentFirstHeading" tal:content="context/title" /> <div tal:replace="structure provider:plone.belowcontenttitle" /> <div tal:replace="structure provider:plone.abovecontentbody" /> <div tal:define="portrait nocall:context/portrait" tal:condition="nocall:portrait"><imgtal:attributes="src string:${context/absolute_url}/@@download/portrait/${portrait/filename}; height portrait/_height | nothing; width portrait/_width | nothing;" /> </div> <div tal:content="structure context/bio/output" /> <div tal:replace="structure provider:plone.belowcontentbody" /> </tal:main-macro></metal:main></body></html>

Add the package to buildout[buildout]develop = src/example.ploneconf09

[instance]… eggs = … example.ploneconf09

Install the new package

Existing content automatically provides the new schema

The custom view

The pieces

http://www.fickr.com/photos/intvgene/370973576/

five.grok

• Allows for writing configuration directives in Python and in place, instead of using ZCML.

• “Grok” a package using the following ZCML, and it will register anything its grokkers find and recognize.

<grok:grok package="." />

plone.dexterity

• Base content classes.• FTI (Factory Type Information)

provides for dynamic lookupof model and schema.

• Default edit form and view.

plone.autoform

• Dexterity renders widgets using z3c.form.• Plone.autoform makes it possible for a form

to be composed by schemas and form hints from different sources.(Main schema + behavior schemas, in the case of Dexterity.)

plone.schemaeditor

• Provides the UI for editing Zope 3 interfaces through the web.

• Dexterity integrates it with the Dexterity types control panel, but it could be used separately.

• IFieldFactory lookup determines what fields can be edited.

plone.supermodel

• Serializer translates a Zope 3 schema into XML.

• Parser translates an XML schema into a Zope 3 schema.

• Easily extensible» Field handlers found via adapter lookup» Additional metadata handlers may handle

custom XML namespaces

plone.directives.form

• Defines the form rendering hint directives that may be included in schemas for use by plone.autoform when rendering forms and views.

plone.directives.dexterity

• Grok directives for custom content classes and forms.

plone.folder

• Orderable Btree-based folder implementation.

• Will also be the basis for AT-based folders in Plone 4.

plone.behavior

• A behavior is a conditional adapter.• In Dexterity, the condition is whether the

behavior is listed in the FTI for an item.• ZCML directive for registering new

behaviors.

plone.rfc822

• Supports the marshalling of Dexterity content into RFC 822 format.

• Used to support access via WebDAV.

plone.app.dexterity

• Pulls in everything you need.• Standard behaviors.» Dublin Core» Related Items

• Dexterity types control panel.

Status report / roadmap

http://www.fickr.com/photos/brianatwebbmoto/2392041992/sizes/m/

Core functionality

Schema serialization

Automatic formgeneration

Portlet assignments

Content rules

Relations

• Not working between Archetypes and Dexterity content in the same site

Widgets

• Not as rich as Archetypes yet, but better than formlib. We have autocomplete, browse-for-content, file/image upload.

TTW schema editing

• Works fine, but needs more real-life use.

Image & file support

(via plone.namedfile & plone.formwidget.namedfile)

• No support for image scaling yet.

Text transform support

(via plone.app.textfield)

Select field support

• No way to define vocabularies through the web yet.

WebDAV support

Versioning & staging

• In progress

TTW behavior creation

Automatic migrationfrom Archetypescontent

Multi-lingual content

• Some discussion, but no code yet.

Link integrity checks

Upcoming releases

• Second alpha release was on Oct. 12• First beta release coming soon

Compatibility

• Plone 3• Plone 4 compatibility coming soon

Performance

Further information

• Dexterity manual:http://plone.org/products/dexterity/documentation/manual/developer-manual

• Behaviors manual:http://plone.org/products/dexterity/documentation/manual/behaviors

• Over 30,000 words!

Example Code

• example.dexterity• example.conference

(both in the collective)

• Example code from this talk:http://svn.plone.org/svn/plone/plone.dexterity/example.ploneconf09

Thanks to everyone who has contributed to making Dexterity a reality!

http://www.fickr.com/photos/torley/2862255105/

Getting involved

• Google Code project:http://code.google.com/p/dexterity/

• Google Group:http://groups.google.com/group/dexterity-development

top related