Re: RFC: Proposal Dexterity API - two variants
Steve McMahon <[email protected]>
| Newsgroups | gmane.comp.web.zope.plone.devel |
|---|---|
| Message-ID | <CAOqzbgiEy7UjHj6m-wAhAts4Zodxov17QwWfSvwu0wN-i+yHMA@mail.gmail.com> |
I've a challenge for those who have looked at the dexterity interface with plone.app.contenttypes installed: Try to see if you can describe -- or document -- the difference between fields and behaviors to Dexterity's principle audience. That's people starting content-type development TTW. I fear we are currently in a situation where this is close to impossible. The problem with attribute access is a symptom of this. We are bringing in a lot of fields via behavior. We have the potential for namespace collision if those fields are simple attributes, and the problem of API complexity if they aren't. I think I understand why the current plone.app.contenttypes is doing so much via behaviors. It's a way to solve the problem of having the standard content types be relatively customizable. If the fields were frozen in schema or Python-package-base model files, you wouldn't be able to turn fields on and off. I'm fearing, though, that it's not the right solution. Consider one of the most common varieties of customization a TTW user might wish to make: changing the title or description of a field like the title or description. I can think of some possible solutions; I'll be others can come up with some, too. But, first step, do we agree we've got a problem here? Steve On Wed, Nov 5, 2014 at 8:57 AM, Martin Aspeli <[email protected]> wrote: > Hi, > > When Dexterity was first designed this was the thinking: > > - Anything that belongs to "your" content type is in "your" schema and is > available as attributes on "your" type. > - If you personally want to reuse among your types, just use subclassing. > Simple, effective. > - Behaviours are a way for programmers to build things that > non-programmers can use TTW. That is, behaviours lets you declaratively opt > into certain things (the canonical example was "versioning") without having > to understand how they're implemented. > - Behaviours can work either adapter-like (data stored elsewhere, e.g. in > annotations or centrally somewhere) or marker-interface-like (data stored > on the object). > > I think where maybe we've gone a bit wrong is that we seem to have made > the decision to ship with very fine-grained behaviours that form part of > the primary API to objects when we think about the Dublin Core metadata. > > That is a special case and arguably one that should be handled with only > one or a small number of behaviours, which should by and large be of the > market interface variety. So, if you are writing very generic code, then > you may want to check or do an explicit adaptation (remember that you can > adapt to an interface that is directly provided by an object without an > explicit adapter registration). > > Most people don't write very generic code, though, they write specific > code to their specific usecase. That's probably one of three things: > > - Some custom fields that are reusable. Use a shared baseclass and direct > attribute access, behaviours give you little benefit. > - Some reusable thing that you want to publish for generic use by third > parties. Write behaviours and use the adaptation pattern for safety. I > don't really see this as "yet another field", I see this as something with > more functionality like rendering additional stuff or something > event-driven (there's a reason we called it "behaviours" not "fields"). > - Some reusable thing you want non-technical users in your project to > reuse TTW. Special case of the one above. > > I don't like the idea of having a dict-like API and an attribute-like API. > That's neither very Pythonic nor very clear. Reminds me of the myriad ways > we can acquire values in Zope 3 land. It seems to add a lot of complexity > for very marginal benefit. > > Martin > > On 5 November 2014 15:44, Jens W. Klein <jens-/[email protected]> wrote: > >> ====================== >> Proposal Dexterity API >> ====================== >> >> We, Robert Niederreiter and Jens Klein, wrote this proposal as an entry >> to a discussion for an future Dexterity API (read: Dexterity 3). We >> followed two different pathes and we are curios which one gets more +1 ;) >> >> Both of them are implementable and also both are in the perspective of >> speed almost the same. >> >> >> Explicit behaviors proposal: expose behaviors explicitly >> ======================================================== >> >> Basic principles >> ---------------- >> >> * Duplicate attribute names are allowed by different behaviors >> * Programmer always addresses effected behavior explicit >> >> >> Pros >> ---- >> >> * More reliable and readable code >> * Explicitness >> * Easy migration >> >> >> Cons >> ---- >> >> * Steeper learning curve (developer needs to learn which behaviors exists) >> * More code >> >> Implementation implications >> --------------------------- >> >> * think of behavior inheritance and how default behaviors can be >> overwritten >> >> >> API usage example >> ----------------- >> >> Read Attribute:: >> >>> context.behavior('basic').title >> >> Write Attribute:: >> >>> context.behavior('basic').title = u'My Title' >> >> Behavior information:: >> >>> context.behaviors >> { >> 'basic': { >> 'title': 'Basic', >> 'description': 'Foo', >> 'attributes': { >> 'title': { >> 'label': 'Title', >> 'description': 'Title of the object', >> '...' >> }, >> ... >> } >> } >> ... >> } >> >> >>> repr(context.behaviors) >> - basic >> -title >> -description >> ... >> >> Unrestricted access:: >> >>> context.behavior('basic').unrestricted('title') >> >> >> Shadowed Behaviors Proposal: Simplified value access >> ==================================================== >> >> Basic principles >> ---------------- >> >> * implemented as one property directly on >> plone.dexterity.content.DexterityContent which acts as a >> zope.interface.mapping.IFullMapping (read: dict-like) to work with all >> values and methods coming from the main schema, behavior schemas and >> behavior factories. >> * Programmer does not need to know about behavior names when accessing >> data >> * Set/get of main schema values is same as schemas form behaviors. >> * Duplicate attribute names are NOT allowed any more and enforced >> (checked on FTI creation time, i.e. XML import, TTW setting) This is >> important! >> * factory methods/properties from behaviors are exposed when a factory >> is given instaed of direct attribute access. >> >> >> Pros >> ---- >> >> * Simple entry for new developers >> * pythonic >> * natural dict-like API is first principle >> * no accicdential override of attributes stored >> * behavior inheritance (i.e.IDublicCoreMetadata is not a problem at all) >> >> >> Cons >> ---- >> >> * duplicate fieldnames in existing code needs migration (not in core) >> * behaviors are kind of hidden to developers, so misunderstandings may >> occur (needs good documentation) >> >> >> Open for discussion >> ------------------- >> >> * should validation be enforced? >> >> >> Important >> --------- >> >> * lots of caching of schemas and intermeidate results >> >> >> API usage example >> ----------------- >> >> >>> context.values['title'] >> 'My Document' >> >> >>> context.values['title'] = 'Jensens Document' >> >>> context.values['some_factory_property'] = 'Foo' >> >>> context.values['some_factory_property'] >> 'Foo' >> >> >>> context.values['some_factory_method'](param1, param2='foo') >> ... >> >> >>> context.values.keys() >> ['title', 'description', ....] >> >> >>> context.update({'title': 'Jensens Updated Document', 'description': >> 'A new easy to understand API for dx'} >> >>> context.values.items() >> [('title': 'Jensens Updated Document', 'description': 'A new easy ...', >> ....)] >> >> other dict-api methods are implemented too (need to finish this, but you >> can imagine how it looks like, ) >> active access to restricted values which checks the read/write permission! >> >> >>> context.restricted_values['title'] >> Traceback ... >> .... >> Unauthorized(...) >> >> >> Legacy Proposal >> ------------------------ >> >> * rename dexterity to devilstick >> * use wording molecule instead of behavior >> * the values are atoms >> * ignore this legacy proposal ;D >> >> ------------------------------------------------------------------------- >> >> happy commenting >> >> Jens and Robert >> -- >> BlueDynamics Alliance >> >> >> >> ------------------------------------------------------------------------------ >> _______________________________________________ >> Plone-developers mailing list >> Plone-developers-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org >> https://lists.sourceforge.net/lists/listinfo/plone-developers >> > > > > ------------------------------------------------------------------------------ > > _______________________________________________ > Plone-developers mailing list > Plone-developers-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org > https://lists.sourceforge.net/lists/listinfo/plone-developers > > ------------------------------------------------------------------------------ _______________________________________________ Plone-developers mailing list Plone-developers-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org https://lists.sourceforge.net/lists/listinfo/plone-developers