103
Building Content Types with Dexterity David Glick Plone Conference 2009

Building Content Types with Dexterity

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Building Content Types with Dexterity

Building Content Typeswith Dexterity

David GlickPlone Conference 2009

Page 2: Building Content Types with Dexterity

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

Page 3: Building Content Types with Dexterity

What is a content type?

Page 4: Building Content Types with Dexterity

A way of categorizingthe items in your site

Page Something Else

Page 5: Building Content Types with Dexterity

Schema

Page 6: Building Content Types with Dexterity

Workflow

Page 7: Building Content Types with Dexterity

Custom view templates

Page 8: Building Content Types with Dexterity

Miscellaneous settings

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

Page 9: Building Content Types with Dexterity

History Lesson

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

Page 10: Building Content Types with Dexterity

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

Page 11: Building Content Types with Dexterity

Archetypes

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

types (ATContentTypes)• Not going away anytime soon

Page 12: Building Content Types with Dexterity

Dexterity

Martin Aspeli

Page 13: Building Content Types with Dexterity

Goals

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

Page 14: Building Content Types with Dexterity

Make filesystem content type development sane

Page 15: Building Content Types with Dexterity

Make through-the-web content type development sane

Page 16: Building Content Types with Dexterity

Make it possible to switch back and forth between the 2

Page 17: Building Content Types with Dexterity

Philosophy

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

Page 18: Building Content Types with Dexterity

Reuse over reinvention

Page 19: Building Content Types with Dexterity

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

Page 20: Building Content Types with Dexterity

Natural interaction over excessive generality

diffculty

time

Page 21: Building Content Types with Dexterity

Real code over generated code

Page 22: Building Content Types with Dexterity

Zope 3 over Zope 2

Page 23: Building Content Types with Dexterity

Automated testing over wishful thinking

Page 24: Building Content Types with Dexterity

Let's build a content type!

Page 25: Building Content Types with Dexterity

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

Page 26: Building Content Types with Dexterity

Installing Dexterity

Page 27: Building Content Types with Dexterity

Dexterity Types Control Panel

Page 28: Building Content Types with Dexterity

Adding a Type

Page 29: Building Content Types with Dexterity

Adding a Type

Page 30: Building Content Types with Dexterity

Adding a 'Plonista' instance

Page 31: Building Content Types with Dexterity

Adding a 'Plonista' instance

Page 32: Building Content Types with Dexterity

The default 'Plonista' view

Page 33: Building Content Types with Dexterity

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!

Page 34: Building Content Types with Dexterity

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

Page 35: Building Content Types with Dexterity

Editing the 'Plonista' Behaviors

Disable this to hide the metadata

Enable this to generate short name from title

Page 36: Building Content Types with Dexterity

Adding a Field

Page 37: Building Content Types with Dexterity

Adding a Field

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

Page 38: Building Content Types with Dexterity

Adding a Field

Page 39: Building Content Types with Dexterity

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

Page 40: Building Content Types with Dexterity

Edit a revised 'Plonista'

Page 41: Building Content Types with Dexterity
Page 42: Building Content Types with Dexterity

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.

Page 43: Building Content Types with Dexterity

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.

Page 44: Building Content Types with Dexterity

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)

Page 45: Building Content Types with Dexterity

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

Page 46: Building Content Types with Dexterity

Exporting a type

• GenericSetup export for now;better UI coming :)

Page 47: Building Content Types with Dexterity

Minimal Dexterity package structure

• example.ploneconf09» /example• /ploneconf09

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

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

• plonista.xml

» /setup.py

Page 48: Building Content Types with Dexterity

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)

Page 49: Building Content Types with Dexterity

__init__.py

# Nothing to see here; move along. :)

Page 50: Building Content Types with Dexterity

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

Page 51: Building Content Types with Dexterity

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>

Page 52: Building Content Types with Dexterity

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>

Page 53: Building Content Types with Dexterity

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.

Page 54: Building Content Types with Dexterity

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>

Page 55: Building Content Types with Dexterity

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>

Page 56: Building Content Types with Dexterity

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:

Page 57: Building Content Types with Dexterity

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>

Page 58: Building Content Types with Dexterity

Specifying a fieldset

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

Page 59: Building Content Types with Dexterity

More form directives

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

Page 60: Building Content Types with Dexterity

plone.directives.dexterity

• read_permission• write_permission

Page 61: Building Content Types with Dexterity

Custom view template

• In plonista.py:

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

Page 62: Building Content Types with Dexterity

• 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>

Page 63: Building Content Types with Dexterity

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

[instance]… eggs = … example.ploneconf09

Page 64: Building Content Types with Dexterity

Install the new package

Page 65: Building Content Types with Dexterity

Existing content automatically provides the new schema

Page 66: Building Content Types with Dexterity

The custom view

Page 67: Building Content Types with Dexterity

The pieces

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

Page 68: Building Content Types with Dexterity

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="." />

Page 69: Building Content Types with Dexterity

plone.dexterity

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

provides for dynamic lookupof model and schema.

• Default edit form and view.

Page 70: Building Content Types with Dexterity

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.)

Page 71: Building Content Types with 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.

Page 72: Building Content Types with Dexterity

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

Page 73: Building Content Types with Dexterity

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.

Page 74: Building Content Types with Dexterity

plone.directives.dexterity

• Grok directives for custom content classes and forms.

Page 75: Building Content Types with Dexterity

plone.folder

• Orderable Btree-based folder implementation.

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

Page 76: Building Content Types with Dexterity

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.

Page 77: Building Content Types with Dexterity

plone.rfc822

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

• Used to support access via WebDAV.

Page 78: Building Content Types with Dexterity

plone.app.dexterity

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

• Dexterity types control panel.

Page 79: Building Content Types with Dexterity

Status report / roadmap

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

Page 80: Building Content Types with Dexterity

Core functionality

Page 81: Building Content Types with Dexterity

Schema serialization

Page 82: Building Content Types with Dexterity

Automatic formgeneration

Page 83: Building Content Types with Dexterity

Portlet assignments

Page 84: Building Content Types with Dexterity

Content rules

Page 85: Building Content Types with Dexterity

Relations

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

Page 86: Building Content Types with Dexterity

Widgets

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

Page 87: Building Content Types with Dexterity

TTW schema editing

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

Page 88: Building Content Types with Dexterity

Image & file support

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

• No support for image scaling yet.

Page 89: Building Content Types with Dexterity

Text transform support

(via plone.app.textfield)

Page 90: Building Content Types with Dexterity

Select field support

• No way to define vocabularies through the web yet.

Page 91: Building Content Types with Dexterity

WebDAV support

Page 92: Building Content Types with Dexterity

Versioning & staging

• In progress

Page 93: Building Content Types with Dexterity

TTW behavior creation

Page 94: Building Content Types with Dexterity

Automatic migrationfrom Archetypescontent

Page 95: Building Content Types with Dexterity

Multi-lingual content

• Some discussion, but no code yet.

Page 96: Building Content Types with Dexterity

Link integrity checks

Page 97: Building Content Types with Dexterity

Upcoming releases

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

Page 98: Building Content Types with Dexterity

Compatibility

• Plone 3• Plone 4 compatibility coming soon

Page 99: Building Content Types with Dexterity

Performance

Page 100: Building Content Types with Dexterity

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!

Page 101: Building Content Types with Dexterity

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

Page 102: Building Content Types with Dexterity

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

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

Page 103: Building Content Types with Dexterity

Getting involved

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

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