Enable Collection Indices (fields for searching) for custom types

by Hans-Peter Locher last modified Feb 04, 2009 03:03 AM
How-to enable usage of Collections for AT-based content types with custom schema fields

Motivation

I'm developing Archetypes-based types for Plone 3, they are based on the standard Plone types, like ATFolder, which bases on ATCTOrderedFolder. I have custom schemas, and wanted to use Collections to be able to search for my custom fields.

General

Portal_catalog

Portal_catalog is the backend tool responsible for making your site searchable. When a user performs a search, portal_catalog checks from it's indexes which objects match the search criteria.

Portal_catalog is accessible from Zope management interface.

Indexes

To inspect the indexes, go to Indexes tab (portal_catalog/manage_catalogIndexes). The available indexes in Plone 3 are:

  • DateIndex
  • DateRangeIndex
  • ExtendePathIndex
  • FieldIndex
  • KeywordIndex
  • PathIndex
  • TextIndex
  • TopicIndex
  • ZCTextIndex

For most purposes FieldIndex might be sufficient. Field Indexes treat the value of an objects attributes atomically, and can be used, for example, to track only a certain subset of object values, such as 'meta_type'.

Metadata

To inspect the metadata, go to Metadata tab (portal_catalog/manage_catalogSchema) To use the value of an object's attribute in the result of a search, that attribute must be in the metadata list.

ATContentTypes Tool

Some basic functions of atct tool can be accessed via ZMI (like image scaling). Atct tool is also queried when using collections. It uses portal_atct.getIndexes() to get the list of indexes. The list differs from portal_catalog.indexes(). The list of atct indexes (and metadata) can't be modified using ZMI, to do so you need to modify it programatically.

Workaround

To enable custom fields for use in a Collection you need to follow these steps (for each field):

  1. add index to portal_catalog
  2. add metadata to portal_catalog
  3. add index to portal_atct
  4. add metadata to portal_atct

To add these indexes by hand to your site, you can use ZMI (for portal_catalog). Regarding atct tool, you can do it with Python via:

portal_atct.addIndex
portal_atct.addMetadata

Using generic setup

Using ZMI and ipython to enable fields to be used in a Collection is good for testing. More convenient is to use generic setup. To apply a generic setup profile during installation of your product, you need to register it in your product's configure.zcml. A default profile should be placed at:

<Product directory>/profiles/default

Plone 3's quickinstaller is aware of generic setup so the default profile will be applied (earlier this had to be done in an install routine).

If you need more information on generic setup you may look at:

http://plone.org/documentation/tutorial/genericsetup/

A very good example can be found here.

Example (MYPRODUCT)

In this example, a product called MYPRODUCT registers a default profile which makes myfield usable in collections. The necessary xml files are:

  • catalog.xml:

    • adding index and metadata to portal_catalog
  • portal_atct.xml:

    • adding index and metadata to portal_atct

    • You can specify all settings manageable by Collection Settings (e.g. to restrict the criteria to be just ATSimpleStringCriterion):

      portal_atct/atct_manageTopicIndex
      portal_atct/atct_manageTopicMetadata
      

configure.zcml:

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:gs="http://namespaces.zope.org/genericsetup"
    i18n_domain="MYPRODUCT">

    <gs:registerProfile
        name="MYPRODUCT"
        title="MYPRODUCT"
        directory="profiles/default"
        description="MYPRODUCT default profile"
        provides="Products.GenericSetup.interfaces.EXTENSION"
        for="Products.CMFPlone.interfaces.IPloneSiteRoot"
    />
</configure>

catalog.xml:

<?xml version="1.0"?>
<object name="portal_catalog" meta_type="Plone Catalog Tool">
 <index name="myfield" meta_type="FieldIndex">
  <indexed_attr value="myfield"/>
 </index>
 <column value="myfield"/>
</object>

portal_atct.xml:

<?xml version="1.0"?>
<atcttool>
 <topic_indexes>
  <index
    name="myfield"
    description="myfield's description"
    enabled="True"
    friendlyName="mytype's myfield">
   <criteria>ATBooleanCriterion</criteria>
   <criteria>ATCurrentAuthorCriterion</criteria>
   <criteria>ATDateRangeCriterion</criteria>
   <criteria>ATFriendlyDateCriteria</criteria>
   <criteria>ATListCriterion</criteria>
   <criteria>ATPortalTypeCriterion</criteria>
   <criteria>ATReferenceCriterion</criteria>
   <criteria>ATSelectionCriterion</criteria>
   <criteria>ATSimpleIntCriterion</criteria>
   <criteria>ATSimpleStringCriterion</criteria>
  </index>
 </topic_indexes>
 <topic_metadata>
  <metadata
    name="myfield"
        description="myfield's description"
        enabled="True"
        friendlyName="mytype's myfield"/>
 </topic_metadata>
</atcttool>

Thanks for reading and I hope this was helpful to you.

~mr_savage