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

A Dexterity Intro for Recovering Archetypes Addicts

Jan 17, 2015

Download

Technology

David Glick

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
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
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