#239: Adapterise the Extensible Indexable Object Wrapper

  1. Motivation
  2. Proposal
  3. Risks
  4. Progress log

Make it easier to register ExtensibleIndexableObjectWrapper attributes with adapters

Proposed by
Martin Aspeli
Proposal type
Assigned to release


Custom indexing strategies currently rely on a global registry of "fake" attributes to the indexable object wrapper. It would be more natural and flexible to be able to register adapters for any context that can provide values for indexable attributes.


  1. Create a new package, plone.indexer
  2. Here, define an interface, IIndexer, which looks like this:
    class IIndexer(Interface):
        def __call__(self):
            """Return the value to index.
    The idea is that you register an adapter that adapts your content type (self.context) and the catalog (self.catalog) and provides IIndexer, with the name of the indexable attribute.
  3. Create a convenience @indexer decorator to allow simpler indexers like the following:
    def my_indexer(object):
        return ...
  4. Create a standard IndexableObjectWrapper implementation that looks up such adapters when asked to provide indexable attributes.
  5. Update CMFPlone's CatalogTool to use this wrapper
  6. Deprecate registerIndexableAttribute() and make it register delegate adapters for now.



We may find that doing an adapter lookup for each attribute that gets indexed is slower than finding a function in a global dict, as it is now. Hopefully, the zope.component cache will solve this, but we should benchmark.

Progress log

  • plone.indexer written and tested
  • Plone branch created and relevant tests updated
  • BBB code in place
  • Deprecate plone.app.content.interfaces.IIndexableObjectWrapper as an alias for plone.indexer's version of the same (we can do this post-merge)