From 5932513bc94c34b0e67676b2718357e6921933c5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 3 Jan 2010 08:49:25 +0000 Subject: Add a (minimal) repoze.catalog tutorial. --- docs/tutorials/catalog/index.rst | 133 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 docs/tutorials/catalog/index.rst (limited to 'docs/tutorials') diff --git a/docs/tutorials/catalog/index.rst b/docs/tutorials/catalog/index.rst new file mode 100644 index 000000000..af31ef6b0 --- /dev/null +++ b/docs/tutorials/catalog/index.rst @@ -0,0 +1,133 @@ +.. _catalog_tutorial: + +Using :mod:`repoze.catalog` Within :mod:`repoze.bfg` +==================================================== + +:mod:`repoze.catalog` is a ZODB-based system that can be used to index +Python objects. It also offers a query interface for retrieving +previously indexed data. Those whom are used to Zope's "ZCatalog" +implementation will feel at home using :mod:`repoze.catalog`. + +This tutorial assumes that you want a Zope-like setup. For example, +it assumes you want to use a persistent ZODB object as your +:term:`root` object, and that the :mod:`repoze.catalog` catalog will +be an attribute of this root object. It is further assumed that you +want the application to be based on :term:`traversal`. + +#. Follow the :ref:`zodb_with_zeo` tutorial to get a system set up with + ZODB and ZEO. When you are finished, come back here. + +#. Install the :mod:`repoze.catalog` software within your application's + environment: + + .. code-block:: text + + $ easy_install repoze.catalog + +#. Change your ZODB application's ``models.py`` file to look like the + below: + + .. code-block:: python + + from repoze.folder import Folder + from repoze.catalog.catalog import Catalog + from repoze.catalog.document import DocumentMap + from repoze.catalog.indexes.field import CatalogFieldIndex + + def get_title(object, default): + title = getattr(object, 'title', '') + if isinstance(title, basestring): + # lowercase for alphabetic sorting + title = title.lower() + return title + + class Document(Folder): + def __init__(self, title): + self.title = title + Folder.__init__(self) + + class Site(Folder): + def __init__(self): + self.catalog = Catalog() + self.catalog.document_map = DocumentMap() + self.update_indexes() + Folder.__init__(self) + + def update_indexes(self): + indexes = { + 'title': CatalogFieldIndex(get_title), + } + + catalog = self.catalog + + # add indexes + for name, index in indexes.iteritems(): + if name not in catalog: + catalog[name] = index + + # remove indexes + for name in catalog.keys(): + if name not in indexes: + del catalog[name] + +#. Change the ``appmaker`` in your application's ``run.py`` to look + something like the below: + + .. code-block:: python + + from myapp.models import Site + + def appmaker(root): + if not 'site' in root: + root['site'] = Site() + transaction.commit() + return root['site'] + +#. We'll demonstrate how you might interact with a catalog from code + by manipulating the database directly using the ``bfgshell`` + command in a terminal window: + + .. code-block:: text + :linenos: + + [chrism@snowpro sess]$ ../bin/paster --plugin=repoze.bfg bfgshell \ + myapp.ini myapp + Python 2.5.4 (r254:67916, Sep 4 2009, 02:12:16) + [GCC 4.2.1 (Apple Inc. build 5646)] on darwin + Type "help" for more information. "root" is the BFG app root object. + >>> from repoze.bfg.traversal import model_path + >>> from myapp.models import Document + >>> root['name'] = Document('title') + >>> doc = root['name'] + >>> docid = root.catalog.document_map.add(model_path(doc)) + >>> root.catalog.index_doc(docid, doc) + >>> import transaction + >>> transaction.commit() + >>> root.catalog.search(title='title') + (1, IFSet([-787959756])) + +#. Add other indexes required by your application to the catalog + within the ``update_indexes`` method of the ``Site`` object. + Whenever an index is added or removed, invoke the + ``update_indexes`` method of the site (the root object) from a + script or from within a ``bfgshell`` session to update the set of + indexes used by your application. + +Read the :mod:`repoze.catalog` `documentation +`_ for further information about other +types of indexes to add, using the document map, and how to issue +queries using the catalog query API. + +Note that in :term:`view` code, you should be able to get a hold of +the root object via the :func:`repoze.bfg.traversal.find_root` API. +The ``catalog`` attribute of that root object will represent the +catalog previously added. + +.. note:: + + The :mod:`repoze.folder` implementation sends events that can be + intercepted with a :term:`subscriber` when documents are added and + removed from a folder. It is often useful to hook these events for + the purpose of mutating the catalog when a new document is added or + removed. See the `repoze.folder documentation + `_ for more information. -- cgit v1.2.3