A Dexterity Intro for Recovering Archetypes Addicts


Published on

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

Published in: Technology
1 Comment
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

A Dexterity Intro for Recovering Archetypes Addicts

  1. 1. A Dexterity Intro for Recovering Archetypes Addicts David Glick Plone Symposium East, 2010
  2. 2. What is a content type?
  3. 3. ZODB stores objects
  4. 4. Content type (or portal_type) categorizes objects Page Something Else
  5. 5. Schema (what sort of data can be stored)
  6. 6. Workflow (who can do things when)
  7. 7. Custom view templates (what it looks like)
  8. 8. Miscellaneous settings • Placeful restrictions • Comments • Searchability • Per-type portlet assignments • etc.
  9. 9. History Lesson http://commons.wikimedia.org/wiki/File:1893_Nina_Pinta_Santa_Maria_replicas.jpg
  10. 10. 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
  11. 11. Archetypes • Schema-based form generation • Basis of Plone's current default content types (ATContentTypes) • Not going away anytime soon
  12. 12. Dexterity Martin Aspeli
  13. 13. Goals http://www.fickr.com/photos/paul-w-locke/1662634481/sizes/m/
  14. 14. Make filesystem content type development sane
  15. 15. Make through-the-web content type development possible
  16. 16. Make it possible to switch back and forth between the 2
  17. 17. Philosophy http://www.fickr.com/photos/ulrichsson/3519217737/
  18. 18. Reuse over reinvention
  19. 19. Small over big Pro duc ts .Arc he ty pe s plone.app.dexterity base classes metadata plone.behavior felds schema plone.directives.* plone.autoform widgets plo ne .de x te rity storage plone.supermodel z3c.form reference engine plone.schemaeditor plone.app.relations
  20. 20. Natural interaction over excessive generality understanding time
  21. 21. Real code over generated code
  22. 22. Zope 3 over Zope 2
  23. 23. Automated testing over wishful thinking
  24. 24. Example: Photo Gallery (example.dexgallery in the collective) • Photo Gallery content type • Photo content type • Tagging • Geolocation
  25. 25. Rapid Development Archetypes Dexterity • ArchGenXML • collective.dexteritypaste • ZopeSkel $ bin/zopeskel dexterity • Though-the-web content type creation
  26. 26. TTW type development
  27. 27. Exporting a type • GenericSetup export for now; better UI coming :)
  28. 28. Base class Archetypes Dexterity • BaseObject, usually via • plone.dexterity.content.Item or plone.dexterity.content.Container ATContentTypes • fewer mixins • many mixins • custom subclasses • typically need a custom typically unneeded subclass
  29. 29. Schemas Archetypes Dexterity • unique schema format • Zope 3 schemas • define a schema, assign it • Can also be represented in to the content class's a unique XML schema 'schema' attribute format • Associated with a content type via the FTI in portal_types
  30. 30. Filesystem roundtripping We b File s y s te m Zope 3 Schema Schema as Python interface Content Editing py Schema Editing xml xml External GenericSetup tools import/export XML schema in XML schema FTI on flesystem
  31. 31. Schemas Archetypes Dexterity From content/photo.py: From content/photo.py: PhotoSchema = atapi.Schema(( class IPhoto(form.Schema): # (fields here) # (fields here) )) From profles/default/types/photo.xml: schemata.finalizeATCTSchema(PhotoSchema, moveDiscussion=False) <property name="schema"> example.dexgallery.dexterity.content.photo. class Photo(base.ATCTContent): IPhoto implements(IPhoto) </property> meta_type = "Photo" schema = PhotoSchema
  32. 32. Accessing fields Archetypes Dexterity • obj.getField('fieldname') • obj.fieldname .get(obj) (values are simply stored • obj.getFieldname() as attributes) (magically generated • Use property descriptors if accessor on the content you need custom accessor/ class) mutator logic • __getattr__ makes sure to get default value from schema if there's no attribute stored yet
  33. 33. Field security • Controlled access (from RestrictedPython) • Implemented using __allow_access_to_unprotected_subobjects__ Archetypes Dexterity • Read/write permissions • Read/write permissions can be specified per field can be specified per field in the schema in the schema
  34. 34. Caption field (rich text) Archetypes Dexterity From content/photo.py: From content/photo.py: atapi.TextField('caption', from plone.app.textfield import RichText required = False, searchable = True, caption = RichText( storage = title = _(u'Caption'), atapi.AnnotationStorage(migrate=True), required = False, validators = ) ('isTidyHtmlWithCleanup',), default_content_type = 'text/html', default_output_type = 'text/x-html- safe', widget = atapi.RichWidget( label = _(u'Caption'), ), ),
  35. 35. Photo field (image) Archetypes 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 ), ), Dexterity from plone.namedfile.field import NamedBlobImage image = NamedBlobImage( title = _(u'Photo'), )
  36. 36. Image scaling • Now supports arbitrary sizes, e.g. <img tal:defne="scale photo_obj/@ @ images" tal:replace="structure python:scale.scale('image', width=1200, height=300, direction='keep').tag()"/> • (supported for both Archetypes and Dexterity in Plone 4)
  37. 37. Tags field (relations) Archetypes Dexterity From content/photo.py: From content/photo.py: atapi.ReferenceField( from z3c.relationfield.schema import 'tags', RelationList, RelationChoice storage=atapi.AnnotationStorage(), tags = RelationList( widget=atapi.ReferenceWidget( title = _(u'Tags'), label=_(u"Tags"), default = [], ), value_type=RelationChoice( required=False, title = _(u'Tag'), relationship='photo_tag', source = ObjPathSourceBinder( allowed_types=('Document',), navigation_tree_query = {'path': multiValued=True, {'query':'/'}}, ), portal_type = 'Document', ), ), required = False, )
  38. 38. Content tree widget
  39. 39. 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])
  40. 40. Custom views Archetypes Dexterity • default: base_view.cpt • default: view class in • add a skin layer template plone.dexterity.browser.view or browser view, register • add a skin layer template or in the FTI browser view, register in the FTI
  41. 41. Grok-style configuration • Configuration via directives inline with code, instead of via ZCML declarations. e.g. from five import grok class View(grok.View): grok.context(IPhoto) grok.require('zope2.View') • Supported but not required
  42. 42. Custom forms Archetypes Dexterity • difficult • 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.)
  43. 43. Adding items Archetypes Dexterity • Autogenerated factory • z3c.form add form method • Default works in many • In Plone, portal_factory cases, but can be replaced prevents premature by setting add_view_expr creation and indexing in the FTI • No content is constructed until the form is submitted
  44. 44. Extending content types Archetypes Dexterity • archetypes.schemaextender • “behaviors” • “schema extender” adapters • can provide additional can provide additional fields fields • “schema modifier” adapters • can mark the content item can make arbitrary changes with a particular interface to a schema • can be turned on/off through the web for each content type
  45. 45. Behaviors s ubc la s s ing s c he m a be ha v io rs schema e x te ns io n ATFile schema model schema schema schema Deco thumbnail schema layout image ATFile Dexterity versioned File name from CustomATFile ATFile title geolocatable ratings
  46. 46. Geolocation behavior
  47. 47. 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
  48. 48. Registering a type Archetypes Dexterity • registerType() after class • Just GenericSetup definition magically (profiles/default/types/ generates Zope 2-style [Type_Id].xml) factory methods • boilerplate in __init__.py finds types and completes registration • type configuration in GenericSetup profile references the factory method
  49. 49. """Main product initializer from zope.i18nmessageid import MessageFactory """ _ = MessageFactory('example.dexgallery') from zope.i18nmessageid import MessageFactory from example.dexgallery.archetypes import config from Products.Archetypes import atapi from 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)
  50. 50. Status report / roadmap http://www.fickr.com/photos/brianatwebbmoto/2392041992/sizes/m/
  51. 51. Core functionality
  52. 52. Schema serialization
  53. 53. Automatic form generation
  54. 54. Portlet assignments
  55. 55. Content rules
  56. 56. Relations • Support for referencing Dexterity content from AT content is in progress
  57. 57. Widgets • Not as rich as Archetypes yet, but better than formlib. We have autocomplete, browse-for-content, file/image upload.
  58. 58. TTW schema editing
  59. 59. Image & file support (via plone.namedfile)
  60. 60. Text transform support (via plone.app.textfield)
  61. 61. WebDAV support
  62. 62. Versioning & staging • In progress
  63. 63. TTW behavior creation
  64. 64. Automatic migration from Archetypes content
  65. 65. Multi-lingual content • Some discussion, but no code yet.
  66. 66. Link integrity checks
  67. 67. Upcoming releases • First beta release was on Apr. 20 • But, being used in production • Future releases will support upgrades
  68. 68. Compatibility • Plone 3 • Plone 4
  69. 69. Performance
  70. 70. Further information • Installation howto: http://plone.org/products/dexterity/documentation/how -to/install • Dexterity manual: http://plone.org/products/dexterity/documentation/man ual/developer-manual • Behaviors manual: http://plone.org/products/dexterity/documentation/man ual/behaviors
  71. 71. Example Code • example.dexterity • example.conference • example.dexgallery (in the collective)
  72. 72. Thanks to everyone who has contributed to making Dexterity a reality! http://www.fickr.com/photos/torley/2862255105/
  73. 73. Getting involved • Google Code project: http://code.google.com/p/dexterity/ • Google Group: http://groups.google.com/group/dexterity- development