[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/apidoc/ifacemodule/
Changed the interface module menu to provide a search field
instead of the
Stephan Richter
srichter at cosmos.phy.tufts.edu
Wed Feb 16 17:50:39 EST 2005
Log message for revision 29172:
Changed the interface module menu to provide a search field instead of the
not so effective tree; you have the choice between name and full-text
search.
Changed:
U Zope3/trunk/src/zope/app/apidoc/ifacemodule/configure.zcml
U Zope3/trunk/src/zope/app/apidoc/ifacemodule/ftests.py
U Zope3/trunk/src/zope/app/apidoc/ifacemodule/menu.pt
U Zope3/trunk/src/zope/app/apidoc/ifacemodule/menu.py
-=-
Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/configure.zcml 2005-02-16 21:20:50 UTC (rev 29171)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/configure.zcml 2005-02-16 22:50:38 UTC (rev 29172)
@@ -27,12 +27,6 @@
<!-- Interface Documentation Module Menu -->
- <adapter
- provides="zope.app.tree.interfaces.IChildObjects"
- for=".IInterfaceModule"
- factory=".menu.InterfaceModuleChildObjects"
- />
-
<browser:page
for=".InterfaceModule"
permission="zope.app.apidoc.UseAPIDoc"
Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/ftests.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/ftests.py 2005-02-16 21:20:50 UTC (rev 29171)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/ftests.py 2005-02-16 22:50:38 UTC (rev 29172)
@@ -24,11 +24,12 @@
def testMenu(self):
response = self.publish(
'/++apidoc++/Interface/menu.html',
- basic='mgr:mgrpw')
+ basic='mgr:mgrpw',
+ env = {'name_only': True, 'search_str': 'IComponent'})
self.assertEqual(response.getStatus(), 200)
body = response.getBody()
self.assert_(body.find(
- 'zope.app.apidoc.ifacemodule.IInterfaceModule') > 0)
+ 'zope.app.component.interfaces.registration.IComponent') > 0)
self.checkForBrokenLinks(body, '/++apidoc++/Interface/menu.html',
basic='mgr:mgrpw')
Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/menu.pt
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/menu.pt 2005-02-16 21:20:50 UTC (rev 29171)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/menu.pt 2005-02-16 22:50:38 UTC (rev 29172)
@@ -1,6 +1,35 @@
<html metal:use-macro="views/apidoc_macros/menu">
<body>
+ <div metal:fill-slot="menu" class="small">
+
+ <div>
+ <span i18n:translate="">Interface Finder:</span>
+ </div>
+ <form action="menu.html" method="post">
+ <input type="checkbox" name="name_only" value="on" checked="checked" />
+ name only search
+ <br />
+ <input type="text" name="search_str"
+ style="font-size: 80%; width=95%"
+ tal:attributes="value request/search_str|nothing" />
+ <input type="submit" name="SUBMIT" value="Find"
+ i18n:attributes="value find-button" style="font-size: 80%"/>
+ </form>
+
+ <div tal:define="ifaces view/findInterfaces"
+ tal:condition="ifaces">
+
+ <a href="" target="main"
+ tal:repeat="info ifaces"
+ tal:attributes="href info/url"
+ tal:content="info/name">
+ zope.app.component.interfaces.ILocalSiteManager
+ </a>
+ </div>
+
+ </div>
+
<p metal:fill-slot="post_menu" class="small" i18n:translate="">
Note: These are only interfaces that are registered with the site manager.
</p>
Modified: Zope3/trunk/src/zope/app/apidoc/ifacemodule/menu.py
===================================================================
--- Zope3/trunk/src/zope/app/apidoc/ifacemodule/menu.py 2005-02-16 21:20:50 UTC (rev 29171)
+++ Zope3/trunk/src/zope/app/apidoc/ifacemodule/menu.py 2005-02-16 22:50:38 UTC (rev 29172)
@@ -20,160 +20,108 @@
$Id$
"""
__docformat__ = 'restructuredtext'
-
-from zope.interface import implements
from zope.security.proxy import removeSecurityProxy
-from zope.app import zapi
-from zope.app.location.interfaces import ILocation
-from zope.app.location import LocationProxy
-from zope.app.tree.interfaces import IChildObjects
+def getAllTextOfInterface(iface):
+ """Get all searchable text from an interface
-from zope.app.apidoc.ifacemodule import IInterfaceModule
-from zope.app.apidoc.utilities import ReadContainerBase
+ Example:
-class IModule(ILocation):
- """Represents some module
-
- Marker interface, so that we can register an adapter for it."""
+ >>> import zope.interface
+ >>> import zope.schema
+ >>> class IFoo(zope.interface.Interface):
+ ... '''foo'''
+ ...
+ ... def bar(self):
+ ... '''bar'''
+ ...
+ ... blah = zope.interface.Attribute('blah', 'blah')
+ ...
+ ... field = zope.schema.Field(
+ ... title = u'title', description = u'description')
-
-class Module(ReadContainerBase):
- r"""Represents a Python module
-
- Examples: zope, zope.app, zope.app.interfaces
-
- However, we usually use it only for the last case.
-
- Usage::
-
- >>> from zope.app.apidoc.ifacemodule import InterfaceModule
-
- >>> module = Module(InterfaceModule(), 'zope.app')
- >>> module.get('apidoc.interfaces.IDocumentationModule').getName()
- 'IDocumentationModule'
-
- >>> module.get(
- ... 'zope.app.apidoc.interfaces.IDocumentationModule') is None
- True
-
- >>> print '\n'.join([id for id, iface in module.items()])
- zope.app.apidoc.interfaces.IDocumentationModule
- """
+ Now get the text. Note that there is no particular order during the text
+ collection.
- implements(IModule)
+ >>> text = getAllTextOfInterface(IFoo)
+ >>> u'foo' in text
+ True
+ >>> u'bar' in text
+ True
+ >>> u'blah' in text
+ True
+ >>> u'field' in text
+ True
+ >>> u'title' in text
+ True
+ >>> u'description' in text
+ True
+ """
+ iface = removeSecurityProxy(iface)
+ text = iface.__doc__ or ''
+ for name in iface:
+ attr = iface[name]
+ text += attr.getName()
+ text += attr.getDoc()
+ return text
- def __init__(self, parent, name):
- self.__parent__ = parent
- self.__name__ = name
- def get(self, key, default=None):
- name = self.__name__ + '.' + key
- return self.__parent__.get(name, default)
+class Menu(object):
+ """Menu for the Interface Documentation Module.
- def items(self):
- parent = self.__parent__
- items = []
- for key in parent.keys():
- if key.startswith(self.__name__):
- items.append((key, LocationProxy(parent[key], self, key)))
- return items
-
-
-class InterfaceModuleChildObjects(object):
- r"""Module Adapter for Static Tree
-
- This adapter is used when building a static tree for the browser.
-
- Functionality::
-
- >>> from zope.app.apidoc.ifacemodule import InterfaceModule
- >>> from zope.app.apidoc.ifacemodule import tests
-
- >>> module = InterfaceModule()
- >>> module = tests.rootLocation(module, 'Interface')
- >>> adapter = InterfaceModuleChildObjects(module)
- >>> adapter.hasChildren()
- True
-
- >>> print '\n'.join([c.__name__ for c in adapter.getChildObjects()])
- IInterfaceModule
- zope.app.apidoc.interfaces
+ The menu allows for looking for interfaces by full-text search or partial
+ names. See `findInterfaces()` for the simple search implementation.
"""
- implements(IChildObjects)
- __used_for__ = IInterfaceModule
+ def findInterfaces(self):
+ """Find the interface that match any text in the documentation strings
+ or a partial path.
- def __init__(self, context):
- self.context = context
+ Before we can test the method, let's create a Menu instance:
- def hasChildren(self):
- """See zope.app.tree.interfaces.IChildObject"""
- return bool(len(self.context))
+ >>> from zope.interface.interfaces import IElement, IAttribute
- def getChildObjects(self):
- """See zope.app.tree.interfaces.IChildObject"""
- objects = {}
- names = removeSecurityProxy(self.context.keys())
- names.sort()
- for name in names:
- # Split these long names and make part of the module path separate
- # entries. Currently we only split by the term '.interfaces', but
- # a more sophisticated algorithm could be developed.
- iface_loc = name.find('.interfaces')
- if iface_loc == -1:
- objects[name] = LocationProxy(self.context[name],
- self.context, name)
- else:
- module_name = name[:iface_loc+11]
- objects[module_name] = Module(self.context, module_name)
- items = objects.items()
- items.sort()
- return [x[1] for x in items]
+ >>> menu = Menu()
+ >>> menu.context = {'IElement': IElement, 'IAttribute': IAttribute}
+ >>> menu.request = {'name_only': 'on', 'search_str': ''}
+ Now let's see how successful our searches are:
-class Menu(object):
- """Menu View Helper Class
+ >>> from zope.app.apidoc.tests import pprint
+ >>> menu.request['search_str'] = 'Elem'
+ >>> pprint(menu.findInterfaces())
+ [[('name', 'IElement'), ('url', './IElement/apiindex.html')]]
- A class that helps building the menu. The menu_macros expects the menu view
- class to have the `getMenuTitle(node)` and `getMenuLink(node)` methods
- implemented. `node` is a `zope.app.tree.node.Node` instance.
+ >>> menu.request['search_str'] = 'I'
+ >>> pprint(menu.findInterfaces())
+ [[('name', 'IAttribute'), ('url', './IAttribute/apiindex.html')],
+ [('name', 'IElement'), ('url', './IElement/apiindex.html')]]
- Examples::
+ Now using the full text search:
- >>> from zope.app.apidoc.ifacemodule import InterfaceModule
- >>> from zope.app.apidoc.ifacemodule.tests import Root
- >>> from zope.app.tree.node import Node
+ >>> del menu.request['name_only']
- >>> ifacemod = InterfaceModule()
- >>> ifacemod.__parent__ = Root()
- >>> ifacemod.__name__ = 'Interfaces'
- >>> mod = Module(ifacemod, 'zope.app.apidoc.interfaces')
- >>> menu = Menu()
+ >>> menu.request['search_str'] = 'object'
+ >>> pprint(menu.findInterfaces())
+ [[('name', 'IAttribute'), ('url', './IAttribute/apiindex.html')],
+ [('name', 'IElement'), ('url', './IElement/apiindex.html')]]
- >>> node = Node(mod.get('IDocumentationModule'))
- >>> menu.getMenuTitle(node)
- 'zope.app.apidoc.interfaces.IDocumentationModule'
-
- >>> values = mod.values()
- >>> values.sort()
- >>> node = Node(values[0])
- >>> menu.getMenuTitle(node)
- u'IDocumentationModule'
-
- >>> menu.getMenuLink(node)
- u'./zope.app.apidoc.interfaces.IDocumentationModule/apiindex.html'
- """
-
- def getMenuTitle(self, node):
- """Return the title of the node that is displayed in the menu."""
- if zapi.isinstance(node.context.__parent__, Module):
- parent = node.context.__parent__
- return zapi.name(node.context).replace(zapi.name(parent)+'.', '')
- return zapi.name(node.context)
-
- def getMenuLink(self, node):
- """Return the HTML link of the node that is displayed in the menu."""
- if zapi.isinstance(node.context, Module):
- return None
- return './' + zapi.name(node.context) + '/apiindex.html'
+ >>> menu.request['search_str'] = 'Stores'
+ >>> pprint(menu.findInterfaces())
+ [[('name', 'IAttribute'), ('url', './IAttribute/apiindex.html')]]
+ """
+ name_only = ('name_only' in self.request) and True or False
+ search_str = self.request.get('search_str', None)
+ results = []
+
+ if search_str is None:
+ return results
+ for name, iface in self.context.items():
+ if (search_str in name or
+ (not name_only and search_str in getAllTextOfInterface(iface))):
+ results.append(
+ {'name': name,
+ 'url': './%s/apiindex.html' %name
+ })
+ results.sort(lambda x, y: cmp(x['name'], y['name']))
+ return results
More information about the Zope3-Checkins
mailing list