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