Metadata-Version: 1.0
Name: dolmen.app.search
Version: 0.4
Summary: Catalog search utilities for Grok applications
Home-page: http://gitweb.dolmen-project.org
Author: Souheil Chelfouh
Author-email: trollfot@gmail.com
License: GPL
Description: =================
        dolmen.app.search
        =================
        
        `dolmen.app.search` provides components to search objects inside a
        Grok application.
        
        Searchers
        =========
        
        `dolmen.app.search` introduces a new component : the ISearcher. This
        component is dedicated in searching and returning a set of objects,
        using a search term.
        
        The provided API is::
        
          >>> from dolmen.app.search.interfaces import ISearchAPI
          >>> interfaceDescription(ISearchAPI)
          ISearcher: A component dedicated to search
          ICatalogSearcher: A specialized ISearcher querying a catalog
        
        
        Test environment
        ----------------
        
        In order to test our searchers, we need an operationnal application
        with at least one index.
        
        We prepare out imports::
        
          >>> import grok
          >>> from grok import index
          >>> from zope.index.text.interfaces import ISearchableText
          >>> from zope.interface import Interface
          >>> from zope.schema import TextLine
        
        We create a model that will be cataloged::
        
          >>> class IRipper(Interface):
          ...   """A serial killer.
          ...   """
          ...   searchabletext = TextLine(title=u"Name of the ripper")
        
          >>> class Ripper(grok.Model):
          ...   grok.implements(IRipper)
          ...
          ...   def __init__(self, searchabletext):
          ...     self.searchabletext = searchabletext
        
        We create a Grok application, that will be out site manager::
        
          >>> class Backstreet(grok.Container, grok.Application):
          ...   """A dark alley.
          ...   """
        
          >>> grok.testing.grok_component('application', Backstreet)
          True
        
        We define an index that will be the base for our search::
        
          >>> class RipperIndexes(grok.Indexes):
          ...  grok.site(Backstreet)
          ...  grok.context(IRipper)
          ...  searchabletext = index.Text()
        
          >>> grok.testing.grok_component('indexes', RipperIndexes)
          True
        
        Now we persist our application and set it as the default site::
        
          >>> from zope.site.hooks import setSite
          >>> app = Backstreet()
          >>> root = getRootFolder()
          >>> root['berner_street'] = app
         
          >>> setSite(app)
        
        The Grok application has created the catalog::
        
          >>> from zope.component import getUtility
          >>> from zope.catalog.interfaces import ICatalog
          >>> catalog = getUtility(ICatalog)
          >>> catalog
          <zope.catalog.catalog.Catalog object at ...>
        
        Our index is there::
        
          >>> catalog['searchabletext']
          <zope.catalog.text.TextIndex object at ...>
          >>> catalog['searchabletext'].documentCount()
          0
        
        Indexing
        --------
        
        The catalog is ready. Now, if we create a content and persist it, the
        cataloging mechanism will do the work for us::
        
          >>> jack = Ripper(u"Jack the knife")
          >>> grok.notify(grok.ObjectCreatedEvent(jack))
          >>> app['jack'] = jack
        
          >>> catalog['searchabletext'].documentCount()
          1
        
        The searchabletext is set. That is what is cataloged in our site catalog::
        
          >>> jack.searchabletext
          u'Jack the knife'
        
        
        Searching
        ---------
        
        An ISearcher can be used as an utility. `dolmen.app.search` provides a
        default implementation of an ICatalogSearcher. This component is used
        to query the site catalog:: 
        
          >>> from dolmen.app.search import ICatalogSearcher
          >>> searcher = getUtility(ICatalogSearcher, "searcher.sitecatalog")	
          >>> searcher
          <dolmen.app.search.searchers.SiteCatalogSearcher object at ...>
          >>> searcher.catalog == catalog
          True
        
        The search method of the ICatalogSearcher takes a search term and the
        name of the index. By default, it uses the `searchabletext` index::
        
          >>> result = searcher.search(term="Jack")
          >>> result
          <dolmen.app.search.sets.PermissionAwareResultSet instance at ...>
          >>> list(result)
          [<dolmen.app.search.tests.Ripper object at ...>]
        
        If we provide a non existing index name, an error is raised::
        
          >>> result = searcher.search(term="Jack", index="non-existing")
          Traceback (most recent call last):
          ...
          ValueError: Index 'non-existing' does not exist
        
        
        Wildcard
        ~~~~~~~~
        
        A wildcard can be given, when searching a text index::
        
          >>> result = searcher.search("Ja")
          >>> list(result)
          []
        
          >>> result = searcher.search("Ja*")
          >>> list(result)
          [<dolmen.app.search.tests.Ripper object at ...>]
        
        
        Permission
        ~~~~~~~~~~
        
        By default, our searcher checks the `zope.View` permission on the
        objects of the result set. We can provide another permission
        explicitly::
        
          >>> result = searcher.search("knife", permission="i-do-not-exist")
          >>> list(result)
          []
        
        A `grok.Permision` class can be used instead of a string::
        
          >>> from dolmen.app.security import CanViewContent
          >>> result = searcher.search("knife", permission=CanViewContent)
          >>> list(result)
          [<dolmen.app.search.tests.Ripper object at ...>]
        
        If permission is set to None, nothing is checked::
           
          >>> result = searcher.search("knife", permission=None)
          >>> list(result)
          [<dolmen.app.search.tests.Ripper object at ...>]
        
        
        View and viewlet
        ================
        
        `dolmen.app.search` comes with two browser components. A search form
        viewlet and a result page.
        
        Search viewlet
        --------------
        
        A search viewlet is registered to display a search form input. In
        order to test the output of the viewlet, we need a view::
        
          >>> class GasLamp(grok.View):
          ...   """A view where the air's cold and damp
          ...   """
          ...   grok.context(IRipper)
        
          >>> grok.testing.grok_component('view', GasLamp)
          True
        
        We get the view to render the viewlet:: 
         
          >>> from zope.publisher.browser import TestRequest
          >>> from zope.component import getMultiAdapter
        
          >>> request = TestRequest()
          >>> view = getMultiAdapter((jack, request), name="gaslamp")
        
        The `Search` viewlet is registered for the `dolmen.app.layout.Top`
        manager. We construct this manager::
        
          >>> from dolmen.app.layout import Top
          >>> manager = Top(jack, request, view)
        
        We can now call, update and render the Search viewlet::
        
          >>> from dolmen.app.search.browser import Search
          >>> search = Search(jack, request, view, manager)
          >>> search.update()
          >>> print search.render()
          <form id="searchbox" method="post"
                action="http://127.0.0.1/berner_street/search.result">
            <input type="text" autocomplete="off" name="search_term"
                   id="search-widget" value="" />
            <input type="submit" name="search_button"
                   id="search-button" title="Search" alt="Search"
                   value="Search" />
          </form>
        
        
        Result page
        -----------
        
        The viewlet posts the data to the `search.result` view. This view
        fetches the `search_term` from the request, queries the
        ICatalogSearcher and displays the results::
        
          >>> request = TestRequest(form = {'search_term': 'jack'})
          >>> results = getMultiAdapter((jack, request), name="search.result")
          >>> results
          <dolmen.app.search.browser.Results object at ...>
        
          >>> results.update()
          >>> print results.content()
          <div class="search-result">
            <div class="search-header">
              <h1>Search</h1>
              <h3>Found 1 results for jack</h3>
            </div>
            <dl class="search-results content-listing">
              <dt>
                <a href="http://127.0.0.1/berner_street/jack"
                   title="jack">
                  <span>jack</span>
                </a>
              </dt>
            </dl>
          </div>
        
        
        Changelog
        =========
        
        0.4 (2010-11-05)
        ----------------
        
        - The package now works for Grok 1.2.
        
        - The icon is now using the "icon" and no longer "contenttype_icon" view.
        
        - The dependencies have been reviewed and slimmed down.
        
        
        0.3.1 (2010-07-24)
        ------------------
        
        - 0.3 release was broken because of missing locales directory.
        
        
        0.3 (2010-07-24)
        ----------------
        
        - Added French translation.
        
        
        0.2.2 (2009-01-08)
        ------------------
        
        - Declare all dependencies and some cleanup.
        
        - Require dolmen.content.View permission for Search viewlet.
        
        
        0.2.1 (2009-12-01)
        ------------------
        
        - Removed all imports from zope.app.* for intid and catalog. Using now
          the new packages. This makes dolmen.app.search compatible with
          grok1.1a2.
        
        
        0.2 (2009-12-01)
        ----------------
        
        - Modified the imports to make it compatible with grok 1.1 (ztk 1.0)
        
        
        0.1 (2009-11-08)
        ----------------
        
        - Initial release
        
Keywords: Grok Zope3 CMS Dolmen
Platform: Any
Classifier: Environment :: Web Environment
Classifier: Framework :: Zope3
Classifier: License :: OSI Approved :: GNU General Public License (GPL)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
