Utility

by Maurits van Rees last modified Feb 04, 2009 03:05 AM
zcml and code for the utilities

zcml registration
^^^^^^^^^^^^^^^^^

In keywordannotator it looks like this::

<utility
provides=".interfaces.IAnnotationDecider"
factory=".events.DefaultAnnotationDecider" />

This means that when some code wants to have a utility that provides
the IAnnotationDecider interface (the event handler code wants this,
see above), such a utility can be created by calling the
DefaultAnnotationDecider class in the events.py file in the
keywordannotator product.

The quadapter overrides this utility in overrides.zcml::

<utility
provides="Products.keywordannotator.interfaces.IAnnotationDecider"
factory="Products.quadapter.events.AudioDecider" />

Since this is an override, this means that the only known way to
create a utility that provides the IAnnotationDecider interface, is
now calling the AudioDecider class in the events.py file in the
quadapter product.


Utility code
^^^^^^^^^^^^

So what does that code look like? In keywordannotator it is this::

class DefaultAnnotationDecider(object):
implements(IAnnotationDecider)
keywords = KEYWORDS
ifaces = (IKeywordMatch,)
def matchesKeywords(self, object):
...
def provideInterfaces(self, object):
for iface in self.ifaces:
if not iface.providedBy(object):
alsoProvides(object, iface)

The implementation of the function 'matchesKeywords' is not
interesting here. It simply checks whether the keywords of the object
match one of the special keywords. By default, only the literal word
'special' is considered special.

The function provideInterfaces is more interesting. It makes sure
that a certain object provides all wanted interfaces. By default this
is the IKeywordMatch marker interface. In the next section we will
register an adapter for objects implementing that interface.

In quadapter the utility code is just four lines::

class AudioDecider(DefaultAnnotationDecider):
implements(IAnnotationDecider)
keywords = KEYWORDS
ifaces = PROVIDE_INTERFACES

It uses a different list of keywords that are special, and different
interfaces that need to be provided to objects that match one of the
keywords. These values are specified in the config.py file::

KEYWORDS = ['audio', 'preken']
PROVIDE_INTERFACES = (IMaudio, IAttributeAnnotatable,)

Note: 'preken' is the Dutch word for 'sermons'.

So, with just a few lines, the quadapter product changes the default
adapter so it reacts to different keywords and provides different
interfaces.

Note that a Quills WeblogEntry does not by default provide the
IAttributeAnnotatable interface, so we must instruct the utility to
make sure that WeblogEntries with one of the special keywords now
implement that interface as well. If wanted, we could add code to
quadapter that makes sure that *all* WeblogEntries also provide the
IAttributeAnnotatable interface. If you want that, look at the
utils.py file of keywordannotator.

At this point you may want to look back at Event handler code to
see how this utility is used by the event handler.