Re: Our story for re-using content types

"Martin Aspeli" <[email protected]>
Newsgroups gmane.comp.web.zope.plone.archetypes.devel
Message-ID <[email protected]>
On Fri, 07 Apr 2006 04:39:45 +0100, George Lee  
<[email protected]> wrote:


>> My advice is - don't do this unless you have a really good reason
>> to.
>
>
> Don't the same questions apply to when you re-use a content type, though?

Yes and no. Re-using a content type (i.e. making your own type based on  
it) has nothing to do with Alan's original advice, but it *does* face some  
of the problems you're mentioning (which are the same problems I identify  
in the original post)

> In
> which case it isn't a mere Python wrapper / module alias that's going  
> on. It
> seems like to create a good Archetype that you can reuse, subclass, etc.  
> you
> have to worry about the above things and code it very well to start with  
> so that
> subclassing, etc. later on is simple.

Yes. Which sucks. :)

> For instance, it seems like this would involve making generic  
> installation code
> with a method that could be called by a newly defined content type that
> subclasses the original content-type. (I half-shudder thinking about  
> subclassing
> RichDocument, for instance, given the installation code it requires.  
> Although
> actually that is fairly clean so that's not a full shudder.)

Well, I tried to put the parts of the RD installation that were  
*necessary* for it to work in Extensions/utils.py. You can import  
Products.RichDocument.Extensions.utils and call those methods on your own  
type. But indeed, I had to think about this. To be honest, you're never  
going to get around that I think, but using util methods and not  
hard-coding the type names gets you a long way. Put it differently - the  
thing you want change may very well be set up in the installer. :)

> And as for coding the relationship between a class and other portal  
> objects, I
> suppose that these should all happen inside methods that can be  
> overriden, for
> instance
>
>   def _lookupDataFromPropertySheet(self):
>       return getToolByName(self,  
> 'portal_properties').new_props.getProperty('data')
>
>   def processData(self):
>       return 'Data: %s' % self._lookupDataFromPropertySheet()
>
> rather than
>
>   def processData(self):
>       return 'Data: %s' % getToolByName(self,
> 'portal_properties').new_props.getProperty('data')

Well yes, that's the kind of thing you'd have to do. However, if you start  
using Zope 3 concepts and factor your code out into smaller modules and  
use adapters it may look like:

     def processData(self):
         context = self
         dataProvider = IDataProvider(context)
         return 'Data: %s' % dataProvider.data

IDataProvider would be an interface:

 from zope.interface import Interface
class IDataProvider(Interface):
     data = Attribute('The data being provided')

and you'd wire up an adapter using ZCML that said that if 'context' in the  
example above was an IMyContentType (the default thing you're writing),  
then the following adapter would be instantiated:

class MyDataProvider(object):
     implements(IDataProvider)

     def _getData(self):
         return 'foo'

     data = property(_getData)

Slightly simplified, but it lets you separate concerns much more cleanly  
than using hooks and mixin classes.

Martin

-- 
(muted)



-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.