74
A Dexterity Intro for Recovering Archetypes Addicts David Glick Plone Symposium East, 2010

A Dexterity Intro for Recovering Archetypes Addicts

Embed Size (px)

DESCRIPTION

This talk covers the basics of building content types with Dexterity, and how it compares to doing so with Archetypes; what sorts of tasks Dexterity is best suited for, and which ones it isn't ready for yet * an update on the most recent improvements to Dexterity

Citation preview

Page 1: A Dexterity Intro for Recovering Archetypes Addicts

A Dexterity Intro for Recovering Archetypes Addicts

David GlickPlone Symposium East, 2010

Page 2: A Dexterity Intro for Recovering Archetypes Addicts

What is a content type?

Page 3: A Dexterity Intro for Recovering Archetypes Addicts

ZODB stores objects

Page 4: A Dexterity Intro for Recovering Archetypes Addicts

Content type (or portal_type)categorizes objects

Page Something Else

Page 5: A Dexterity Intro for Recovering Archetypes Addicts

Schema

(what sort of data can be stored)

Page 6: A Dexterity Intro for Recovering Archetypes Addicts

Workflow

(who can do things when)

Page 7: A Dexterity Intro for Recovering Archetypes Addicts

Custom view templates

(what it looks like)

Page 8: A Dexterity Intro for Recovering Archetypes Addicts

Miscellaneous settings

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

Page 9: A Dexterity Intro for Recovering Archetypes Addicts

History Lesson

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

Page 10: A Dexterity Intro for Recovering Archetypes Addicts

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: A Dexterity Intro for Recovering Archetypes Addicts

Archetypes

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

types (ATContentTypes)• Not going away anytime soon

Page 12: A Dexterity Intro for Recovering Archetypes Addicts

Dexterity

Martin Aspeli

Page 13: A Dexterity Intro for Recovering Archetypes Addicts

Goals

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

Page 14: A Dexterity Intro for Recovering Archetypes Addicts

Make filesystem content type development sane

Page 15: A Dexterity Intro for Recovering Archetypes Addicts

Make through-the-web content type development possible

Page 16: A Dexterity Intro for Recovering Archetypes Addicts

Make it possible to switch back and forth between the 2

Page 17: A Dexterity Intro for Recovering Archetypes Addicts

Philosophy

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

Page 18: A Dexterity Intro for Recovering Archetypes Addicts

Reuse over reinvention

Page 19: A Dexterity Intro for Recovering Archetypes Addicts

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: A Dexterity Intro for Recovering Archetypes Addicts

Natural interaction over excessive generality

understanding

time

Page 21: A Dexterity Intro for Recovering Archetypes Addicts

Real code over generated code

Page 22: A Dexterity Intro for Recovering Archetypes Addicts

Zope 3 over Zope 2

Page 23: A Dexterity Intro for Recovering Archetypes Addicts

Automated testing over wishful thinking

Page 24: A Dexterity Intro for Recovering Archetypes Addicts

Example: Photo Gallery(example.dexgallery in the collective)

• Photo Gallery content type• Photo content type

• Tagging• Geolocation

Page 25: A Dexterity Intro for Recovering Archetypes Addicts
Page 26: A Dexterity Intro for Recovering Archetypes Addicts

Rapid Development

Archetypes• ArchGenXML

• ZopeSkel

Dexterity• collective.dexteritypaste

• Though-the-webcontent type creation

$ bin/zopeskel dexterity

Page 27: A Dexterity Intro for Recovering Archetypes Addicts

TTW type development

Page 28: A Dexterity Intro for Recovering Archetypes Addicts

Exporting a type

• GenericSetup export for now;better UI coming :)

Page 29: A Dexterity Intro for Recovering Archetypes Addicts

Base class

Archetypes• BaseObject, usually via

ATContentTypes

• many mixins

• typically need a custom subclass

Dexterity• plone.dexterity.content.Item or

plone.dexterity.content.Container

• fewer mixins

• custom subclasses typically unneeded

Page 30: A Dexterity Intro for Recovering Archetypes Addicts

Schemas

Archetypes• unique schema format

• define a schema, assign it to the content class's 'schema' attribute

Dexterity• Zope 3 schemas

• Can also be represented in a unique XML schema format

• Associated with a content type via the FTI in portal_types

Page 31: A Dexterity Intro for Recovering Archetypes Addicts

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 32: A Dexterity Intro for Recovering Archetypes Addicts

PhotoSchema = atapi.Schema(( # (fields here)))

schemata.finalizeATCTSchema(PhotoSchema, moveDiscussion=False)

class Photo(base.ATCTContent): implements(IPhoto) meta_type = "Photo" schema = PhotoSchema

class IPhoto(form.Schema): # (fields here)

<property name="schema">example.dexgallery.dexterity.content.photo.IPhoto</property>

From profles/default/types/photo.xml:

From content/photo.py:From content/photo.py:

Schemas

Archetypes Dexterity

Page 33: A Dexterity Intro for Recovering Archetypes Addicts

Accessing fields

Archetypes• obj.getField('fieldname')\

.get(obj)

• obj.getFieldname()

(magically generated accessor on the content class)

Dexterity• obj.fieldname

(values are simply stored as attributes)

• Use property descriptors if you need custom accessor/mutator logic

• __getattr__ makes sure to get default value from schema if there's no attribute stored yet

Page 34: A Dexterity Intro for Recovering Archetypes Addicts

Field security

Archetypes• Read/write permissions

can be specified per field in the schema

Dexterity• Read/write permissions

can be specified per field in the schema

• Controlled access (from RestrictedPython)

• Implemented using __allow_access_to_unprotected_subobjects__

Page 35: A Dexterity Intro for Recovering Archetypes Addicts

atapi.TextField('caption', required = False, searchable = True, storage = atapi.AnnotationStorage(migrate=True), validators = ('isTidyHtmlWithCleanup',), default_content_type = 'text/html', default_output_type = 'text/x-html-safe', widget = atapi.RichWidget( label = _(u'Caption'), ), ),

from plone.app.textfield import RichText caption = RichText( title = _(u'Caption'), required = False, )

From content/photo.py:From content/photo.py:

Caption field (rich text)

Archetypes Dexterity

Page 36: A Dexterity Intro for Recovering Archetypes Addicts

from plone.app.blob.field import ImageField

ImageField('image', required = True, storage = atapi.AnnotationStorage(migrate=True), languageIndependent = True, swallowResizeExceptions = zconf.swallowImageResizeExceptions.enable, pil_quality = zconf.pil_config.quality, pil_resize_algo = zconf.pil_config.resize_algo, max_size = zconf.ATNewsItem.max_image_dimension, validators = (('isNonEmptyFile', V_REQUIRED), ('checkNewsImageMaxSize', V_REQUIRED)), widget = atapi.ImageWidget( label = _(u'Photo'), show_content_type = False ), ),

from plone.namedfile.field import NamedBlobImage

image = NamedBlobImage( title = _(u'Photo'), )

Photo field (image)Archetypes

Dexterity

Page 37: A Dexterity Intro for Recovering Archetypes Addicts

Image scaling

• Now supports arbitrary sizes, e.g.

• (supported for both Archetypes and Dexterity in Plone 4)

<img tal:defne="scale photo_obj/@ @ images" tal:replace="structure python:scale.scale('image', width=1200, height=300, direction='keep').tag()"/>

Page 38: A Dexterity Intro for Recovering Archetypes Addicts

atapi.ReferenceField( 'tags', storage=atapi.AnnotationStorage(), widget=atapi.ReferenceWidget( label=_(u"Tags"), ), required=False, relationship='photo_tag', allowed_types=('Document',), multiValued=True, ),

from z3c.relationfield.schema import \ RelationList, RelationChoicetags = RelationList( title = _(u'Tags'), default = [], value_type=RelationChoice( title = _(u'Tag'), source = ObjPathSourceBinder( navigation_tree_query = {'path': {'query':'/'}}, portal_type = 'Document', ), ), required = False, )

From content/photo.py:From content/photo.py:

Tags field (relations)

Archetypes Dexterity

Page 39: A Dexterity Intro for Recovering Archetypes Addicts

Content tree widget

Page 40: A Dexterity Intro for Recovering Archetypes Addicts

Indexing fields

• similar for both• for Dexterity you may need to implement

your own SearchableText indexer, e.g.

from plone.indexer import indexer

@indexer(IPhoto)def SearchableText(obj): return ' '.join([obj.Title(), obj.Description(), obj.caption.output])

Page 41: A Dexterity Intro for Recovering Archetypes Addicts

Custom views

Archetypes

• default: base_view.cpt

• add a skin layer template or browser view, register in the FTI

Dexterity

• default: view class in plone.dexterity.browser.view

• add a skin layer template or browser view, register in the FTI

Page 42: A Dexterity Intro for Recovering Archetypes Addicts

Grok-style configuration

• Configuration via directives inline with code, instead of via ZCML declarations. e.g.

• Supported but not required

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

Page 43: A Dexterity Intro for Recovering Archetypes Addicts

Custom forms

Archetypes

• difficult

Dexterity

• full power of z3c.form

(write custom forms that reference fields from the type's schema)

• or, use grok directives on the schema to influence how fields appear in all forms (e.g., custom widget, etc.)

Page 44: A Dexterity Intro for Recovering Archetypes Addicts

Adding items

Archetypes• Autogenerated factory

method

• In Plone, portal_factory prevents premature creation and indexing

Dexterity• z3c.form add form

• Default works in many cases, but can be replaced by setting add_view_expr in the FTI

• No content is constructed until the form is submitted

Page 45: A Dexterity Intro for Recovering Archetypes Addicts

Extending content types

Archetypes• archetypes.schemaextender

• “schema extender” adapters can provide additional fields

• “schema modifier” adapters can make arbitrary changes to a schema

Dexterity• “behaviors”

• can provide additional fields

• can mark the content item with a particular interface

• can be turned on/off through the web for each content type

Page 46: A Dexterity Intro for Recovering Archetypes Addicts

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 47: A Dexterity Intro for Recovering Archetypes Addicts

Geolocation behavior

Page 48: A Dexterity Intro for Recovering Archetypes Addicts

Geolocation behavior

• Adds a geolocation field• Provides an adapter to store the value of

that field in an annotation• Marks the item with IGeolocatableMarker• Some adapters so that Products.Maps

knows how to get a geolocation from an item with IGeolocatableMarker

Page 49: A Dexterity Intro for Recovering Archetypes Addicts

Registering a type

Archetypes• registerType() after class

definition magically generates Zope 2-style factory methods

• boilerplate in __init__.py finds types and completes registration

• type configuration in GenericSetup profile references the factory method

Dexterity• Just GenericSetup

(profiles/default/types/[Type_Id].xml)

Page 50: A Dexterity Intro for Recovering Archetypes Addicts

"""Main product initializer"""

from zope.i18nmessageid import MessageFactoryfrom example.dexgallery.archetypes import config

from Products.Archetypes import atapifrom Products.CMFCore import utils

# Define a message factory for when this product is internationalised.# This will be imported with the special name "_" in most modules. Strings# like _(u"message") will then be extracted by i18n tools for translation.

archetypesMessageFactory = MessageFactory('example.dexgallery.archetypes')

def initialize(context): """Initializer called when used as a Zope 2 product.

This is referenced from configure.zcml. Regstrations as a "Zope 2 product" is necessary for GenericSetup profiles to work, for example.

Here, we call the Archetypes machinery to register our content types with Zope and the CMF. """

# Retrieve the content types that have been registered with Archetypes # This happens when the content type is imported and the registerType() # call in the content type's module is invoked. Actually, this happens # during ZCML processing, but we do it here again to be explicit. Of # course, even if we import the module several times, it is only run # once.

content_types, constructors, ftis = atapi.process_types( atapi.listTypes(config.PROJECTNAME), config.PROJECTNAME)

# Now initialize all these content types. The initialization process takes # care of registering low-level Zope 2 factories, including the relevant # add-permission. These are listed in config.py. We use different # permissions for each content type to allow maximum flexibility of who # can add which content types, where. The roles are set up in rolemap.xml # in the GenericSetup profile.

for atype, constructor in zip(content_types, constructors): utils.ContentInit('%s: %s' % (config.PROJECTNAME, atype.portal_type), content_types=(atype, ), permission=config.ADD_PERMISSIONS[atype.portal_type], extra_constructors=(constructor,), ).initialize(context)

from zope.i18nmessageid import MessageFactory

_ = MessageFactory('example.dexgallery')

Page 51: A Dexterity Intro for Recovering Archetypes Addicts

Status report / roadmap

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

Page 52: A Dexterity Intro for Recovering Archetypes Addicts

Core functionality

Page 53: A Dexterity Intro for Recovering Archetypes Addicts

Schema serialization

Page 54: A Dexterity Intro for Recovering Archetypes Addicts

Automatic formgeneration

Page 55: A Dexterity Intro for Recovering Archetypes Addicts

Portlet assignments

Page 56: A Dexterity Intro for Recovering Archetypes Addicts

Content rules

Page 57: A Dexterity Intro for Recovering Archetypes Addicts

Relations

• Support for referencing Dexterity content from AT content is in progress

Page 58: A Dexterity Intro for Recovering Archetypes Addicts

Widgets

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

Page 59: A Dexterity Intro for Recovering Archetypes Addicts

TTW schema editing

Page 60: A Dexterity Intro for Recovering Archetypes Addicts

Image & file support

(via plone.namedfile)

Page 61: A Dexterity Intro for Recovering Archetypes Addicts

Text transform support

(via plone.app.textfield)

Page 62: A Dexterity Intro for Recovering Archetypes Addicts

WebDAV support

Page 63: A Dexterity Intro for Recovering Archetypes Addicts

Versioning & staging

• In progress

Page 64: A Dexterity Intro for Recovering Archetypes Addicts

TTW behavior creation

Page 65: A Dexterity Intro for Recovering Archetypes Addicts

Automatic migrationfrom Archetypescontent

Page 66: A Dexterity Intro for Recovering Archetypes Addicts

Multi-lingual content

• Some discussion, but no code yet.

Page 67: A Dexterity Intro for Recovering Archetypes Addicts

Link integrity checks

Page 68: A Dexterity Intro for Recovering Archetypes Addicts

Upcoming releases

• First beta release was on Apr. 20• But, being used in production• Future releases will support upgrades

Page 69: A Dexterity Intro for Recovering Archetypes Addicts

Compatibility

• Plone 3• Plone 4

Page 70: A Dexterity Intro for Recovering Archetypes Addicts

Performance

Page 71: A Dexterity Intro for Recovering Archetypes Addicts

Further information

• Installation howto: http://plone.org/products/dexterity/documentation/how-to/install

• Dexterity manual:

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

• Behaviors manual:

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

Page 72: A Dexterity Intro for Recovering Archetypes Addicts

Example Code

• example.dexterity• example.conference• example.dexgallery

(in the collective)

Page 73: A Dexterity Intro for Recovering Archetypes Addicts

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

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

Page 74: A Dexterity Intro for Recovering Archetypes Addicts

Getting involved

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

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