Current

This document is valid for the current version of Plone.

Query portal_catalog for Interfaces

by Kees Hink last modified May 04, 2012 01:49 PM
Query the portal catalog tool for objects implementing a given interface.

This manual has moved to http://collective-docs.readthedocs.org/en/latest/searching_and_indexing/query.html#querying-by-interface, and will no longer be maintained here.

Purpose

Suppose you have several types (for example, event types like 'Birthday','Wedding','Graduation') in your portal which implement the same interface (for example, IIsCauseForCelebration). Suppose you want to get items of these types from the catalog by their interface. This is more exact than naming the types explicitly (like portal_type=['Birthday','Wedding','Graduation' ]), because you don't really care what the types' names really are: all you really care for is the interface.

This has the additional advantage that if products added or modified later add types which implement the interface, these new types will also show up in your query.

Prerequisities

  • Plone 3 or higher

Step by step

  1. Import the interface:
    from Products.MyProduct.path.to import IIsCauseForCelebration
    You can't do this import from a script, due to restricted python.
  2. Do the catalog query:
    catalog(object_provides=IIsCauseForCelebration.__identifier__)
    In a script, you might do object_provides='Products.MyProduct.path.to.IIsCauseForCelebration'

Caveats

  • A word of warning: object_provides is a KeywordIndex which indexes absolute Python class names. A string matching is performed for the dotted name. Thus, you will have zero results for this:
    catalog(object_provides="Products.ATContentTypes.interface.IATDocument") # Products.ATContentTypes.interface imports * from document
    But this will work:
    catalog(object_provides="Products.ATContentTypes.interface.document.IATDocument") # Products.ATContentTypes.document.IATDocument declares the interface
  • As with all catalog queries, if you pass an empty value for search parameter, it will return all results. So if the interface you defined would yield a None type object, the search would return all values of object_provides.
  • One advantage of using Interface.__identifier__ instead instead of "Product.interfaces.Interface" is that you will get errors at startup time if the interface cannot be found.

Further information

Nothing yet, suggestions welcome


Contribute

Something wrong or out of date? Anybody can edit or create a new article in the knowledge base. Simply create an account on this site, log in, and click the Edit button to contribute.