[Checkins] SVN: Sandbox/ulif/grok-testsetup/ Merged trunk-updates into branch.

Uli Fouquet uli at gnufix.de
Tue Jan 29 16:52:24 EST 2008


Log message for revision 83307:
  Merged trunk-updates into branch.

Changed:
  _U  Sandbox/ulif/grok-testsetup/
  U   Sandbox/ulif/grok-testsetup/CHANGES.txt
  U   Sandbox/ulif/grok-testsetup/doc/index.txt
  A   Sandbox/ulif/grok-testsetup/doc/minitutorials/automatic_form_generation.txt
  U   Sandbox/ulif/grok-testsetup/doc/minitutorials/macros.txt
  U   Sandbox/ulif/grok-testsetup/doc/reference/components.rst
  U   Sandbox/ulif/grok-testsetup/doc/reference/decorators.rst
  U   Sandbox/ulif/grok-testsetup/doc/reference/directives.rst
  U   Sandbox/ulif/grok-testsetup/doc/reference/events.rst
  U   Sandbox/ulif/grok-testsetup/doc/reference/exceptions.rst
  U   Sandbox/ulif/grok-testsetup/doc/reference/functions.rst
  U   Sandbox/ulif/grok-testsetup/setup.py
  U   Sandbox/ulif/grok-testsetup/src/grok/__init__.py
  U   Sandbox/ulif/grok-testsetup/src/grok/components.py
  U   Sandbox/ulif/grok-testsetup/src/grok/directive.py
  U   Sandbox/ulif/grok-testsetup/src/grok/ftests/admin/docgrok.py
  U   Sandbox/ulif/grok-testsetup/src/grok/ftests/catalog/indexes_multiple_conflict.py
  U   Sandbox/ulif/grok-testsetup/src/grok/interfaces.py
  U   Sandbox/ulif/grok-testsetup/src/grok/meta.py
  U   Sandbox/ulif/grok-testsetup/src/grok/tests/form/fields.py
  U   Sandbox/ulif/grok-testsetup/src/grok/tests/json/view_lookup.py
  A   Sandbox/ulif/grok-testsetup/src/grok/tests/order/
  U   Sandbox/ulif/grok-testsetup/src/grok/tests/test_grok.py
  A   Sandbox/ulif/grok-testsetup/src/grok/tests/util/public_methods_from_class.py
  U   Sandbox/ulif/grok-testsetup/src/grok/util.py
  U   Sandbox/ulif/grok-testsetup/versions.cfg

-=-

Property changes on: Sandbox/ulif/grok-testsetup
___________________________________________________________________
Name: svn:externals
   - bootstrap svn://svn.zope.org/repos/main/zc.buildout/trunk/bootstrap/

   + bootstrap svn://svn.zope.org/repos/main/zc.buildout/trunk/bootstrap/



Modified: Sandbox/ulif/grok-testsetup/CHANGES.txt
===================================================================
--- Sandbox/ulif/grok-testsetup/CHANGES.txt	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/CHANGES.txt	2008-01-29 21:52:24 UTC (rev 83307)
@@ -10,9 +10,21 @@
 * Added testsetup classes in grok.testing to improve easy setup of
   unit- and functional tests.
 
+* Add a new directive, ``grok.order()``, which can be used to help
+  sort components. At the time it is not used yet, but we intend to
+  use it for the viewlets support. Note that this means Grok now
+  requires Martian 0.9.3 or higher. See ``grok.interfaces`` for more
+  documentation on this directive.
+ 
 Bug fixes
 ---------
 
+* Do not register the publishTraverse and browserDefault methods of the
+  JSON component as views.
+
+* Methods with names that start with an '_' are not registered as views
+  for XMLRPC, REST and JSON components.
+
 * Use a configuration action for the registration of the static directory.
 
 * Fix imports from zope.app.securitypolicy.
@@ -35,6 +47,14 @@
 * Fix https://bugs.launchpad.net/grok/+bug/162437: grok.Form and its
   subclasses did not implement IBrowserView.
 
+* Fix https://bugs.launchpad.net/grok/+bug/185414: grok introsepector
+  was broken for zipped eggs.
+
+Restructuring
+-------------
+
+* Refactor commonalities out of meta.py.
+
 0.11 (2007-11-08)
 =================
 

Modified: Sandbox/ulif/grok-testsetup/doc/index.txt
===================================================================
--- Sandbox/ulif/grok-testsetup/doc/index.txt	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/doc/index.txt	2008-01-29 21:52:24 UTC (rev 83307)
@@ -27,6 +27,11 @@
 
 Grok News
 ---------
+2008-01-20:
+  Grok 0.11.1 has been released! See the `announcement`__ for more details!
+
+  .. __: http://permalink.gmane.org/gmane.comp.web.zope.grok.devel/3565
+
 2007-11-08:
   Grok 0.11 has been released! See the release `announcement`__
   for more details! For projects that want to upgrade, please read the

Copied: Sandbox/ulif/grok-testsetup/doc/minitutorials/automatic_form_generation.txt (from rev 83306, grok/trunk/doc/minitutorials/automatic_form_generation.txt)
===================================================================
--- Sandbox/ulif/grok-testsetup/doc/minitutorials/automatic_form_generation.txt	                        (rev 0)
+++ Sandbox/ulif/grok-testsetup/doc/minitutorials/automatic_form_generation.txt	2008-01-29 21:52:24 UTC (rev 83307)
@@ -0,0 +1,309 @@
+=========================
+Automatic Form Generation
+=========================
+
+:Author: Dirceu Pereira Tiegs
+
+Introduction
+------------
+
+Grok supports automatic form generation by working with zope.interface, zope.schema and zope.formlib. This how-to will show you how to create an application that uses this feature and also how to use some more advanced widgets than the formlib defaults.
+
+Schema and Fields
+-----------------
+
+Fields are components that define a model's attributes, and schemas are collections of fields. For example:
+
++-------------------+
+| Person            |
++-------------------+
+| name: String      |
++-------------------+
+| birth: Date       |
++-------------------+
+| description: Text |
++-------------------+
+
+The model above can be translated into Grok code like this:
+
+.. code-block:: python
+
+    from zope import interface, schema
+    class IPerson(interface.Interface):
+        name = schema.TextLine(title="Name")
+        birth = schema.Date(title="Birth")
+        description = schema.Text(title="Description")
+
+Defining an interface with schema fields allows automatic form generation and validation. To do this, grok.AddForm, grok.EditForm and grok.DisplayForm are used. These components are called forms; forms are web components that use widgets to display and input data. Typically a template renders the widgets by calling attributes or methods of the displayed object.
+
+Widgets are components that display field values and, in the case of writable fields, allow the user to edit those values. Widgets:
+
+- Display current field values, either in a read-only format, or in a format that lets the user change 
+  the field value.
+
+- Update their corresponding field values based on values provided by users.
+
+- Manage the relationships between their representation of a field value and the object's field value.
+  For example, a widget responsible for editing a number will likely represent that number internally as
+  a string. For this reason, widgets must be able to convert between the two value formats. In the case
+  of the number-editing widget, string values typed by the user need to be converted to numbers such as
+  int or float.
+
+- Support the ability to assign a missing value to a field. For example, a widget may present a ``None`` 
+  option for selection that, when selected, indicates that the object should be updated with the field's 
+  ``missing`` value.
+
+
+The forms have default templates that are used if no other template is provided. 
+
+grok.AddForm and grok.EditForm use the default template [grok_egg]/templates/default_edit_form.pt. 
+
+grok.DisplayForm uses [grok_egg]/templates/default_display_form.pt.
+
+Input Validation - Constraints and Invariants
+---------------------------------------------
+
+A constraint is constraint (:-)) that is bound to a specific field:
+
+.. code-block:: python
+
+    import grok
+    from zope import interface, schema
+    import re
+
+    expr = re.compile(r"^(\w&.%#$&'\*+-/=?^_`{}|~]+!)*[\w&.%#$&'\*+-/=?^_`{}|~]+"
+                      r"@(([0-9a-z]([0-9a-z-]*[0-9a-z])?\.)+[a-z]{2,6}|([0-9]{1,3}"
+                      r"\.){3}[0-9]{1,3})$", re.IGNORECASE)
+    check_email = expr.match
+
+    class IMyUser(interface.Interface):
+        email = schema.TextLine(title="Email", constraint=check_email)
+
+    class MyUser(grok.Model)
+        interface.implements(IMyUser)
+
+        def __init__(self, email):
+            super(MyUser, self).__init__()
+            self.email = email
+
+An invariant is a constraint that involves more than one field:
+
+.. code-block:: python
+
+    import grok
+    from zope import interface, schema
+    from datetime import date
+
+    class IMyEvent(interface.Interface):
+        title = schema.TextLine(title="Title")
+        begin = schema.Date(title="Begin date")
+        end = schema.Date(title="End date")
+
+    class MyEvent(grok.Model)
+        interface.implements(IMyEvent)
+
+        def __init__(self, title, begin, end):
+            super(MyEvent, self).__init__()
+            self.title = title
+            self.begin = begin
+            self.end = end
+
+        @interface.invariant
+        def beginBeforeEnd(event):
+            if event.begin > event.end:
+                raise interface.Invalid("Begin date must be before end date")
+
+Example 1 - Birthday Reminder
+-----------------------------
+
+Grok want to remember his friends's birthday, so he created a simple application to do that.
+
+ME GROK SMASH CALENDAR!
+
+We want to use a custom widget to select dates, so you need to add 'z3c.widget' to setup.py of your package:
+
+.. code-block:: python
+
+    install_requires=['setuptools',
+                      'grok',
+                      'z3c.widget',
+                      # Add extra requirements here
+                      ],
+
+And run ./bin/buildout. This will install z3c.widget and make it available to your project.
+
+app.py is pretty simple:
+
+.. code-block:: python
+
+    import grok
+
+    class Friends(grok.Application, grok.Container):
+        pass
+
+    class Index(grok.View):
+        pass
+
+friend.py contains our content component and it's forms:
+
+.. code-block:: python
+
+    import grok
+    from zope import interface, schema
+    from app import Friends
+
+    from z3c.widget.dropdowndatewidget.widget import DropDownDateWidget
+
+    class IFriend(interface.Interface):
+        name = schema.TextLine(title=u"Name")
+        birth_date = schema.Date(title=u"Birth Date")
+        description = schema.Text(title=u"Description")
+
+    class Friend(grok.Model):
+        interface.implements(IFriend)
+    
+        def __init__(self, name, birth_date, description):
+            super(Friend, self).__init__()
+            self.name = name
+            self.birth_date = birth_date
+            self.description = description
+
+    class AddFriend(grok.AddForm):
+        grok.context(Friends)
+        form_fields = grok.AutoFields(Friend)
+
+        # Here is the trick. You set the 'custom_widget' attribute with the custom Widget's class
+        form_fields['birth_date'].custom_widget = DropDownDateWidget
+
+        @grok.action('Add event')
+        def add(self, **data):
+            obj = Friend(**data)
+            name = data['name'].lower().replace(' ', '_')
+            self.context[name] = obj
+
+    class Edit(grok.EditForm):
+        form_fields = grok.AutoFields(Friend)
+        form_fields['birth_date'].custom_widget = DropDownDateWidget
+
+    class Index(grok.DisplayForm):
+        pass
+
+
+Example 2 - Wiki
+----------------
+
+Grok wants to impress beautiful cavewomen with a cool Web 2.0 application, so he built a Wiki with a JavaScript enabled text editor. 
+
+ME GROK WANTS COLLABORATE AND RICH TEXT EDITOR!
+
+You need to add 'zc.resourcelibrary' and 'z3c.widget' to setup.py of your package and run ./bin/buildout to install the new components:
+
+setup.py
+
+.. code-block:: python
+
+    install_requires=['setuptools',
+                      'grok',
+                      'zc.resourcelibrary',
+                      'z3c.widget',
+                      # Add extra requirements here
+                      ],
+
+app.py won't contain any application logic, only the application and the default view called "index".
+
+.. code-block:: python
+
+    import grok
+
+    class Wiki(grok.Application, grok.Container):
+        pass
+
+    class Index(grok.View):
+        pass
+
+wikipage.py is almost identical to friend.py in our first example:
+
+.. code-block:: python
+
+    import grok
+    from zope import interface, schema
+    from app import Wiki
+
+    from z3c.widget.tiny.widget import TinyWidget
+
+    class IWikiPage(interface.Interface):
+        title = schema.TextLine(title=u"Title")
+        contents = schema.Text(title=u"Contents")
+
+    class WikiPage(grok.Model):
+        interface.implements(IWikiPage)
+    
+        def __init__(self, title, contents):
+            super(WikiPage, self).__init__()
+            self.title = title
+            self.contents = contents
+
+    class AddWikiPage(grok.AddForm):
+        grok.context(Wiki)
+        form_fields = grok.AutoFields(WikiPage)
+        form_fields['contents'].custom_widget = TinyWidget
+
+        @grok.action('Add event')
+        def add(self, **data):
+            obj = WikiPage(**data)
+            name = data['title'].lower().replace(' ', '_')
+            self.context[name] = obj
+
+    class Edit(grok.EditForm):
+        form_fields = grok.AutoFields(WikiPage)
+        form_fields['contents'].custom_widget = TinyWidget
+
+    class Index(grok.DisplayForm):
+        pass
+
+Here is the trick: to use TinyWidget you must load it's configuration. TinyWidget uses zc.resourcelibrary to load the JavaScript editor, and zc.resourcelibrary have some dependencies (on zope.app.component and zope.app.pagetemplate). Your package's configure.zcml must be like this:
+
+.. code-block:: html
+
+    <configure xmlns="http://namespaces.zope.org/zope"
+               xmlns:grok="http://namespaces.zope.org/grok">
+      <include package="zope.app.component" file="meta.zcml" />
+      <include package="zope.app.pagetemplate" file="meta.zcml" />
+      <include package="zc.resourcelibrary" file="meta.zcml" />
+      <include package="zc.resourcelibrary" />
+      <include package="z3c.widget.tiny" />
+      <include package="grok" />
+      <grok:grok package="." />
+    </configure>
+
+And we must add a directive to the AddForm template to load the TinyMCE editor. First, copy the default template:
+
+.. code-block:: sh
+
+    $ mkdir wikipage_templates 
+    $ cp [grok_egg]/grok/templates/default_edit_form.pt wikipage_templates/addwikipage.pt
+
+Then add this directive to the <head> tag of wikipage_templates/addwikipage.pt
+
+.. code-block:: html
+
+  <head>
+    <tal:block replace="resource_library:tiny_mce" />
+  </head>
+
+And that's it! Now AddWikiPage uses TinyMCE to edit the "contents" field.
+
+Learning More
+-------------
+
+Many topics not were covered here. You can learn more reading the source code of Zope 3 components such as zope.schema and zope.formlib. Zope is a great platform and have a pretty good automated testing culture, so you can evend read / run doctests like these:
+
+- http://svn.zope.org/zope.schema/trunk/src/zope/schema/README.txt?rev=80304&view=auto
+- http://svn.zope.org/zope.schema/trunk/src/zope/schema/fields.txt?rev=75170&view=auto
+- http://svn.zope.org/zope.schema/trunk/src/zope/schema/validation.txt?rev=79215&view=auto
+- http://svn.zope.org/zope.formlib/trunk/src/zope/formlib/form.txt?rev=81649&view=markup
+- http://svn.zope.org/zope.formlib/trunk/src/zope/formlib/errors.txt?rev=75131&view=markup
+
+Web Component Development with Zope 3 is a great book written by Philipp von Weitershausen (wich is a Grok core developer). While the book doesn't cover Grok directly, it covers all the underlying technology that Grok uses:
+
+- http://worldcookery.com/

Modified: Sandbox/ulif/grok-testsetup/doc/minitutorials/macros.txt
===================================================================
--- Sandbox/ulif/grok-testsetup/doc/minitutorials/macros.txt	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/doc/minitutorials/macros.txt	2008-01-29 21:52:24 UTC (rev 83307)
@@ -117,7 +117,7 @@
 
 .. code-block:: html
 
-    <html metal:use-macro="context/@@mymacros/mypage">
+    <html metal:use-macro="context/@@mymacros/macros/mypage">
     </html>
 
 Watching::
@@ -138,7 +138,7 @@
 
 .. code-block:: html
 
-    <html metal:use-macro="context/@@mymacros/mypage">
+    <html metal:use-macro="context/@@mymacros/macros/mypage">
       <body>
         <!-- slot 'mycontent' was defined in the macro above -->
         <div metal:fill-slot="mycontent">
@@ -155,7 +155,7 @@
 The pattern of the macro reference (the <macro-location>) used here
 is::
 
-    context/<view-name>/<macro-name>
+    context/<view-name>/macros/<macro-name>
 
 whereas ``context`` references the object being viewed, which in our
 case is the ``Sample`` application. In plain English we want Zope to
@@ -170,9 +170,8 @@
 
 It is not a bad idea to register views for interfaces (instead of
 implementing classes), because it means, that a view will remain
-usable, while an implementation of an interface can change. [FIXME: Is
-this a lie?] This is done in the section `Defining 'all-purpose'
-macros`_ below.
+usable, while an implementation of an interface can change. This is
+done in the section `Defining 'all-purpose' macros`_ below.
 
 
 Background: how ``grok.View`` and macros interact
@@ -198,12 +197,26 @@
 
 Such, you can write in short for the above pattern::
 
-      context/<view-name>/<macro-name>
+      context/<view-name>/macros/<macro-name>
 
 View names always start with the 'eyes' (``@@``) which is a shortcut
 for ``++view++<view-name>``.
 
+.. versionchanged:: 0.11
 
+  In older grok releases (before 0.11) even omitting the `macros` part
+  of a URI was possible. So you could write::
+
+    context/<view-name>/<macro-name>
+
+  instead of::
+
+    context/<view-name>/macros/<macro-name>
+
+  This is now deprecated. Use always `macros/` to indicate, that you
+  want to reference a macro of a view.
+
+
 Defining 'all-purpose' macros
 ------------------------------
 
@@ -222,7 +235,7 @@
 
 and reference the macros of the associated pagetemplate like this::
 
-    context/@@master/<macro-name>
+    context/@@master/macros/<macro-name>
 
 Because the macros in ``Master`` now are 'bound' (in fact their view
 is bound) to ``Interface`` and every Grok application, model or
@@ -244,7 +257,7 @@
 
 .. code-block:: html
 
-        <html metal:use-macro="context/@@standard_macros/page">
+        <html metal:use-macro="context/@@standard_macros/macros/page">
           <head>
             <title metal:fill-slot="title">
               Document Title

Modified: Sandbox/ulif/grok-testsetup/doc/reference/components.rst
===================================================================
--- Sandbox/ulif/grok-testsetup/doc/reference/components.rst	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/doc/reference/components.rst	2008-01-29 21:52:24 UTC (rev 83307)
@@ -40,8 +40,8 @@
 
 .. class:: grok.Adapter
 
-   Base class to define an adapter. Adapters are automatically registered when a
-   module is "grokked".
+   Base class to define an adapter. Adapters are automatically
+   registered when a module is "grokked".
 
    .. attribute:: grok.Adapter.context
 
@@ -50,39 +50,42 @@
    **Directives:**
 
    :func:`grok.context(context_obj_or_interface)`
-      Maybe required. Identifies the type of objects or interface for the adaptation.
+      Maybe required. Identifies the type of objects or interface for
+      the adaptation.
 
    .. seealso::
 
-      :function:`grok.context`
+      :func:`grok.context`
 
    :func:`grok.implements(\*interfaces)`
       Required. Identifies the interface(s) the adapter implements.
 
    .. seealso::
 
-      :function:`grok.implements`
+      :func:`grok.implements`
 
    :func:`grok.name(name)`
-      Optional. Identifies the name used for the adapter registration. If ommitted, no
-      name will be used.
+      Optional. Identifies the name used for the adapter
+      registration. If ommitted, no name will be used.
 
-      When a name is used for the adapter registration, the adapter can only be
-      retrieved by explicitely using its name.
+      When a name is used for the adapter registration, the adapter
+      can only be retrieved by explicitely using its name.
 
    .. seealso::
 
-      :function:`grok.name`
+      :func:`grok.name`
 
    :func:`grok.provides(name)`
       Maybe required.
 
    .. seealso::
 
-      :function:`grok.provides`
+      :func:`grok.provides`
 
-**Example 1:** ::
+**Example 1:**
 
+.. code-block:: python
+
    import grok
    from zope import interface
 
@@ -97,15 +100,17 @@
 
    home = IHome(cave)
 
-**Example 2: Register and retrieve the adapter under a specific name** ::
 
+**Example 2: Register and retrieve the adapter under a specific name**
+
+.. code-block:: python
+
    import grok
    from zope import interface
 
    class Cave(grok.Model):
        pass
-
-   class IHome(interface.Interface):
+    class IHome(interface.Interface):
        pass
 
    class Home(grok.Adapter):
@@ -115,6 +120,7 @@
    from zope.component import getAdapter
    home = getAdapter(cave, IHome, name='home')
 
+
 :class:`grok.MultiAdapter`
 ==========================
 
@@ -144,8 +150,10 @@
       :func:`grok.provides` is required to disambiguate for what interface the
       adapter will be registered.
 
-**Example:** ::
+**Example:**
 
+.. code-block:: python
+
    import grok
    from zope import interface
 
@@ -171,6 +179,7 @@
 :class:`grok.Annotation`
 ========================
 
+
 Utilities
 ~~~~~~~~~
 
@@ -199,6 +208,7 @@
       :func:`grok.provides` is required to disambiguate for what interface the
       global utility will be registered.
 
+
 :class:`grok.LocalUtility`
 ==========================
 
@@ -240,7 +250,7 @@
 :class:`grok.View`
 ==================
 
-:class:`grok.JSON
+:class:`grok.JSON`
 ==================
 
 :class:`grok.XMLRPC`
@@ -291,8 +301,10 @@
    it is important to define permissions, which restrict access to
    certain principals or roles.
 
-   **Example:** ::
+   **Example:**
 
+   .. code-block:: python
+
       import grok
       grok.define_permission('cave.enter')
 
@@ -302,6 +314,7 @@
       :func:`grok.require`, :class:`grok.Permission`, :class:`grok.Role`
 
    .. versionchanged:: 0.11
+
       replaced by :class:`grok.Permission`.
 
 :class:`Role`

Modified: Sandbox/ulif/grok-testsetup/doc/reference/decorators.rst
===================================================================
--- Sandbox/ulif/grok-testsetup/doc/reference/decorators.rst	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/doc/reference/decorators.rst	2008-01-29 21:52:24 UTC (rev 83307)
@@ -13,14 +13,14 @@
 
 .. function:: subscribe(*classes_or_interfaces)
 
-Declare that the decorated function subscribes to an event or a combination of
-objects and events and register it.
+  Declare that the decorated function subscribes to an event or a
+  combination of objects and events and register it.
 
-Applicable on module-level for functions. Requires at least one class or
-interface as argument.
+  Applicable on module-level for functions. Requires at least one
+  class or interface as argument.
 
-(Similar to Zope 3's :func:`subscriber` decorator, but automatically performs
-the registration of the component.)
+  (Similar to Zope 3's :func:`subscriber` decorator, but automatically
+  performs the registration of the component.)
 
 
 :func:`grok.action` -- Declare a form submit handler
@@ -33,43 +33,48 @@
 :func:`grok.adapter/grok.implementer` -- Declare an adapter factory
 ====================================================================
 
-.. XXX these two decorators are always used together, but are named separately because they are separate in the Zope 3 API. Should grok implement this as one decorator with two arguments?
+.. XXX these two decorators are always used together, but are named
+   separately because they are separate in the Zope 3 API. Should
+   grok implement this as one decorator with two arguments?
 
 These decorators are always used in tandem to declare an adapter factory.
 
 .. function:: grok.adapter(*interfaces) 
 
-`*interfaces` -- the interfaces *adapted* by the object created by this factory.
+  `*interfaces` -- the interfaces *adapted* by the object created by
+                   this factory.
 
+
 .. function:: grok.implementer(interface) 
 
-`interface` -- the interface *provided* by the object created by this factory.
+  `interface` -- the interface *provided* by the object created by
+                 this factory.
 
 
-**Example 1:** ::
+**Example 1:**
 
+.. code-block:: python
+
 	@grok.adapter(ICave)
 	@grok.implementer(IHome)
 	def home_for_cave(cave):
 	    return Home()
 
-**Example 2: adapt a regular class instead of an interface ** ::
+**Example 2: adapt a regular class instead of an interface**
 
+.. code-block:: python
+
 	@grok.adapter(Cave)
 	@grok.implementer(IHome)
 	def home_for_cave(cave):
 	    return Home()
 
-**Example 3: declare a multi-adapter factory ** ::
+**Example 3: declare a multi-adapter factory**
 
+.. code-block:: python
+
 	@grok.adapter(ICave,IFire)
 	@grok.implementer(ICozy)
 	def cozy_dwelling(cave, fire):
 	    return Dwelling()
 
-
-
-
-
-
-

Modified: Sandbox/ulif/grok-testsetup/doc/reference/directives.rst
===================================================================
--- Sandbox/ulif/grok-testsetup/doc/reference/directives.rst	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/doc/reference/directives.rst	2008-01-29 21:52:24 UTC (rev 83307)
@@ -23,74 +23,83 @@
 :func:`grok.context` -- Declare the context for views, adapters, etc.
 =====================================================================
 
+A class or module level directive to indicate the context for
+something (class or module) in the same scope.
 
 .. function:: grok.context(*class_or_interface)
 
-A class or module level directive to indicate the context for something
-(class or module) in the same scope. When used on module level, it will set
-the context for all views, adapters, etc. in that module. When used on class
-level, it will set the context for that particular class.
+  When used on module level, it will set the context for all views,
+  adapters, etc. in that module. When used on class level, it will set
+  the context for that particular class.
 
-With Grok contexts are set automatically for some objects, if they are
-unambigous. For example a :class:`grok.View` will get the only
-:class:`grok.Application` or :class:`grok.Model` class as context, iff there
-exists exactly one in the same module. If there are more possible contexts
-or you want to set a type (class/interface) from another module as context,
-than the one choosen by default, then you have to call :func:`grok.context`
-explicitly.
+  With Grok contexts are set automatically for some objects, if they are
+  unambigous. For example a :class:`grok.View` will get the only
+  :class:`grok.Application` or :class:`grok.Model` class as context,
+  iff there exists exactly one in the same module. If there are more
+  possible contexts or you want to set a type (class/interface) from
+  another module as context, than the one choosen by default, then you
+  have to call :func:`grok.context` explicitly.
 
-**Example:**
+  **Example:**
 
-Here the :func:`grok.context` directive indicates, that
-:class:`Mammoth` instances will be the context of :class:`Index`
-views (and not instances of :class:`Cave`) ::
+  Here the :func:`grok.context` directive indicates, that
+  :class:`Mammoth` instances will be the context of :class:`Index`
+  views (and not instances of :class:`Cave`):
 
-   import grok
+  .. code-block:: python
 
-   class Mammoth(grok.Model):
-       pass
+    import grok
 
-   class Cave(grok.Model):
-       pass
+    class Mammoth(grok.Model):
+        pass
 
-   class Index(grok.View):
-       grok.context(Mammoth)
+    class Cave(grok.Model):
+        pass
 
-.. seealso::
+    class Index(grok.View):
+        grok.context(Mammoth)
 
-   :class:`grok.View`, :class:`grok.Adapter`, :class:`grok.MultiAdapter`
+  .. seealso::
 
+    :class:`grok.View`, :class:`grok.Adapter`, :class:`grok.MultiAdapter`
+
+
 :func:`grok.name` -- associate a component with a name
 ======================================================
 
+A class level directive used to associate a component with a single
+name `name`.
+
 .. function:: grok.name(name)
 
-A class level directive used to associate a component with a single name
-`name`. Typically this directive is optional. The default behaviour when no
-name is given depends on the component. The same applies to the semantics of
-this directive: for what exactly a name is set when using this directive,
-depends on the component.
+  Typically this directive is optional. The default behaviour when no
+  name is given depends on the component. The same applies to the
+  semantics of this directive: for what exactly a name is set when
+  using this directive, depends on the component.
 
-**Example:** ::
+  **Example:**
 
-   import grok
+  .. code-block:: python
 
-   class Mammoth(grok.Model):
+    import grok
+
+    class Mammoth(grok.Model):
       pass
 
-   # a common use case is to have a URL for a view named differently than
-   # the name of the view class itself.
-   class SomeView(grok.View):
-      grok.name('index')
+    # a common use case is to have a URL for a view named differently than
+    # the name of the view class itself.
+    class SomeView(grok.View):
+       grok.name('index')
 
 
-.. seealso::
+  .. seealso::
 
-   :class:`grok.Adapter`, :class:`grok.Annotation`,
-   :class:`grok.GlobalUtility`, :class:`grok.Indexes`,
-   :class:`grok.MultiAdapter`, :class:`grok.Role`,
-   :class:`grok.View`
+    :class:`grok.Adapter`, :class:`grok.Annotation`,
+    :class:`grok.GlobalUtility`, :class:`grok.Indexes`,
+    :class:`grok.MultiAdapter`, :class:`grok.Role`,
+    :class:`grok.View`
 
+
 :func:`grok.title`
 ========================
 
@@ -101,139 +110,154 @@
 :func:`grok.implements` -- indicate, that a class implements an interface
 =========================================================================
 
+A class level directive to declare one or more `interfaces`, as
+implementers of the surrounding class.
+
 .. function:: grok.implements(*interfaces)
 
-A class level directive to declare one or more `interfaces`, as implementers
-of the surrounding class. This directive allows several parameters.
+  This directive allows several parameters.
 
-:func:`grok.implements` is currently an alias for
-:func:`zope.interface.implements`.
+  :func:`grok.implements` is currently an alias for
+  :func:`zope.interface.implements`.
 
-**Example:** ::
+  **Example:**
 
-   >>> import grok
-   >>> from zope import interface
-   >>> class IPaintable(interface.Interface):
-   ...   pass
-   ...
-   >>> class Cave(object):
-   ...   pass
-   ...
-   >>> cave = Cave()
-   >>> IPaintable.providedBy(cave)
-   False
-   >>> class PaintableCave(object):
-   ...   grok.implements(IPaintable)
-   ...
-   >>> cave = PaintableCave()
-   >>> IPaintable.providedBy(cave)
-   True
+  .. code-block:: python
 
-:func:`grok.provides`
-=====================
+    >>> import grok
+    >>> from zope import interface
+    >>> class IPaintable(interface.Interface):
+    ...   pass
+    ...
+    >>> class Cave(object):
+    ...   pass
+    ...
+    >>> cave = Cave()
+    >>> IPaintable.providedBy(cave)
+    False
+    >>> class PaintableCave(object):
+    ...   grok.implements(IPaintable)
+    ...
+    >>> cave = PaintableCave()
+    >>> IPaintable.providedBy(cave)
+    True
 
+
+:func:`grok.provides` -- Declare, that a component provides a certain interface
+===============================================================================
+
 .. function:: grok.provides(interface)
 
-If the component implements more than one interface, :func:`grok.provides`
-is required to disambiguate for what interface the component will be
-registered.
+  If the component implements more than one interface,
+  :func:`grok.provides` is required to disambiguate for what interface
+  the component will be registered.
 
-.. seealso::
+  .. seealso::
 
-   :func:`grok.implements`
+    :func:`grok.implements`
 
+
 :func:`grok.adapts` -- Declare that a class adapts certain objects
 ==================================================================
 
 .. function:: grok.adapts(*classes_or_interfaces)
 
-A class-level directive to declare that a class adapts objects of the
-classes or interfaces given in `\*classes_or_interfaces`.
+  A class-level directive to declare that a class adapts objects of
+  the classes or interfaces given in `\*classes_or_interfaces`.
 
-This directive accepts several arguments.
+  This directive accepts several arguments.
 
-It works much like the :mod:`zope.component`\ s :func:`adapts()`, but you do
-not have to make a ZCML entry to register the adapter.
+  It works much like the :mod:`zope.component`\ s :func:`adapts()`,
+  but you do not have to make a ZCML entry to register the adapter.
 
-**Example:** ::
+  **Example:**
 
-   import grok
-   from zope import interface, schema
-   from zope.size.interfaces import ISized
+  .. code-block:: python
 
-   class IMammoth(interface.Interface):
-       name = schema.TextLine(title=u"Name")
-       size = schema.TextLine(title=u"Size", default=u"Quite normal")
+    import grok
+    from zope import interface, schema
+    from zope.size.interfaces import ISized
 
-   class Mammoth(grok.Model):
-       interface.implements(IMammoth)
+    class IMammoth(interface.Interface):
+        name = schema.TextLine(title=u"Name")
+        size = schema.TextLine(title=u"Size", default=u"Quite normal")
 
-   class MammothSize(object):
-       grok.implements(ISized)
-       grok.adapts(IMammoth)
+    class Mammoth(grok.Model):
+        interface.implements(IMammoth)
 
-       def __init__(self, context):
-           self.context = context
+    class MammothSize(object):
+        grok.implements(ISized)
+        grok.adapts(IMammoth)
 
-       def sizeForSorting(self):
-           return ('byte', 1000)
+        def __init__(self, context):
+            self.context = context
 
-       def sizeForDisplay(self):
-           return ('1000 bytes')
+        def sizeForSorting(self):
+            return ('byte', 1000)
 
-Having :class:`MammothSize` available, you can register it as an adapter,
-without a single line of ZCML::
+        def sizeForDisplay(self):
+            return ('1000 bytes')
 
-   >>> manfred = Mammoth()
-   >>> from zope.component import provideAdapter
-   >>> provideAdapter(MammothSize)
-   >>> from zope.size.interfaces import ISized
-   >>> size = ISized(manfred)
-   >>> size.sizeForDisplay()
-   '1000 bytes'
+  Having :class:`MammothSize` available, you can register it as an adapter,
+  without a single line of ZCML:
 
-.. seealso::
+  .. code-block:: python
 
-   :func:`grok.implements`
+    >>> manfred = Mammoth()
+    >>> from zope.component import provideAdapter
+    >>> provideAdapter(MammothSize)
+    >>> from zope.size.interfaces import ISized
+    >>> size = ISized(manfred)
+    >>> size.sizeForDisplay()
+    '1000 bytes'
 
+  .. seealso::
+
+    :func:`grok.implements`
+
+
 :func:`grok.baseclass` -- declare a class as base
 =================================================
 
 .. function:: grok.baseclass()
 
-A class-level directive without argument to mark something as a base class.
-Base classes are are not grokked.
+  A class-level directive without argument to mark something as a base
+  class. Base classes are are not grokked.
 
-Another way to indicate that something is a base class, is by postfixing the
-classname with ``'Base'``.
+  Another way to indicate that something is a base class, is by
+  postfixing the classname with ``'Base'``.
 
-The baseclass mark is not inherited by subclasses, so those subclasses will
-be grokked (except they are explicitly declared as baseclasses as well).
+  The baseclass mark is not inherited by subclasses, so those
+  subclasses will be grokked (except they are explicitly declared as
+  baseclasses as well).
 
-**Example:** ::
+  **Example:**
 
-   import grok
+  .. code-block:: python
 
-   class ModelBase(grok.Model):
-       pass
+    import grok
 
-   class ViewBase(grok.View):
-       def render(self):
-           return "hello world"
+    class ModelBase(grok.Model):
+        pass
+ 
+    class ViewBase(grok.View):
+        def render(self):
+            return "hello world"
 
-   class AnotherView(grok.View):
-       grok.baseclass()
+    class AnotherView(grok.View):
+        grok.baseclass()
 
-       def render(self):
-           return "hello world"
+        def render(self):
+            return "hello world"
 
-   class WorkingView(grok.View):
-       pass
+    class WorkingView(grok.View):
+        pass
 
-Using this example, only the :class:`WorkingView` will serve as a view,
-while calling the :class:`ViewBase` or :class:`AnotherView` will lead to a
-:exc:`ComponentLookupError`.
+  Using this example, only the :class:`WorkingView` will serve as a
+  view, while calling the :class:`ViewBase` or :class:`AnotherView`
+  will lead to a :exc:`ComponentLookupError`.
 
+
 Utility directives
 ~~~~~~~~~~~~~~~~~~
 
@@ -242,31 +266,34 @@
 
 .. function:: grok.global_utility(factory[, provides=None[, name=u'']])
 
-A module level directive to register a global utility.
+  A module level directive to register a global utility.
 
-`factory` - the factory that creates the utility.
+  `factory` - the factory that creates the utility.
 
-`provides` - the interface the utility should be looked up with.
+  `provides` - the interface the utility should be looked up with.
 
-`name` - the name of the utility.
+  `name` - the name of the utility.
 
-The latter two parameters are optional.
+  The latter two parameters are optional.
 
-To register the utility correctly, Grok must be able to identify an
-interface provided by the utility. If none is given, Grok checks whether
-(exactly) one interface is implemented by the factory to be registered (see
-example below). If more than one interface is implemented by a class, use
-:func:`grok.provides` to specify which one to use. If no interface is
-implemented by the instances delivered by the factory, use
-:func:`grok.implements` to specify one.
+  To register the utility correctly, Grok must be able to identify an
+  interface provided by the utility. If none is given, Grok checks
+  whether (exactly) one interface is implemented by the factory to be
+  registered (see example below). If more than one interface is
+  implemented by a class, use :func:`grok.provides` to specify which
+  one to use. If no interface is implemented by the instances
+  delivered by the factory, use :func:`grok.implements` to specify
+  one.
 
-Another way to register global utilities with Grok is to subclass from
-:class:`grok.GlobalUtility`.
+  Another way to register global utilities with Grok is to subclass from
+  :class:`grok.GlobalUtility`.
 
-**Example:**
+  **Example:**
 
-   Given the following module code: ::
+    Given the following module code:
 
+    .. code-block:: python
+
       import grok
       from zope import interface
 
@@ -279,8 +306,10 @@
       grok.global_utility(Fireplace)
       grok.global_utility(Fireplace, name='hot')
 
-   Then the following works: ::
+    Then the following works:
 
+    .. code-block:: python
+
       >>> from zope import component
       >>> fireplace = component.getUtility(IFireplace)
       >>> IFireplace.providedBy(fireplace)
@@ -294,57 +323,62 @@
       >>> isinstance(fireplace, Fireplace)
       True
 
-.. seealso::
+  .. seealso::
 
-   :class:`grok.GlobalUtility`, :func:`grok.provides`,
-   :func:`grok.implements`
+    :class:`grok.GlobalUtility`, :func:`grok.provides`,
+    :func:`grok.implements`
 
+
 :func:`grok.local_utility` -- register a local utility
 ======================================================
 
 .. function:: grok.local_utility(factory[, provides=None[, name=u''[, setup=None[, public=False[, name_in_container=None]]]]])
 
-A class level directive to register a local utility.
+  A class level directive to register a local utility.
 
-`factory` -- the factory that creates the utility.
+  `factory` -- the factory that creates the utility.
 
-`provides` -- the interface the utility should be looked up with.
+  `provides` -- the interface the utility should be looked up with.
 
-`name` -- the name of the utility.
+  `name` -- the name of the utility.
 
-`setup` -- a callable that receives the utility as its single
-   argument, it is called after the utility has been created and
-   stored.
+  `setup` -- a callable that receives the utility as its single
+             argument, it is called after the utility has been created
+             and stored.
 
-`public` -- if `False`, the utility will be stored below
-   `++etc++site`.  If `True`, the utility will be stored directly
-   in the site.  The site should in this case be a container.
+  `public` -- if `False`, the utility will be stored below
+              `++etc++site`.  If `True`, the utility will be stored
+              directly in the site.  The site should in this case be a
+              container.
 
-`name_in_container` -- the name to use for storing the utility.
+  `name_in_container` -- the name to use for storing the utility.
 
-All but the first parameter are optional.
+  All but the first parameter are optional.
 
-To register a local utility correctly, Grok must know about the interface,
-the utility should be looked up with. If none is given, Grok looks up any
-interfaces implemented by instances delivered by `factory` and if exactly
-one can be found, it is taken. See :func:`grok.global_utility`.
+  To register a local utility correctly, Grok must know about the
+  interface, the utility should be looked up with. If none is given,
+  Grok looks up any interfaces implemented by instances delivered by
+  `factory` and if exactly one can be found, it is taken. See
+  :func:`grok.global_utility`.
 
-Every single combination of interfaces and names can only be registered once
-per module.
+  Every single combination of interfaces and names can only be
+  registered once per module.
 
-It is not possible to declare a local utility as public, if the site is not
-a container. Grok will remind you of this. To store a utility in a
-container, a `name_in_container` is needed. If none is given, Grok will make
-up one automatically.
+  It is not possible to declare a local utility as public, if the site
+  is not a container. Grok will remind you of this. To store a utility
+  in a container, a `name_in_container` is needed. If none is given,
+  Grok will make up one automatically.
 
-An alternative way to define a local utility is to subclass from
-:class:`grok.LocalUtility`.
+  An alternative way to define a local utility is to subclass from
+  :class:`grok.LocalUtility`.
 
-**Example:**
+  **Example:**
 
-   The following code registers a local unnamed utility `fireplace` in
-   instances of :class:`Cave` ::
+    The following code registers a local unnamed utility `fireplace` in
+    instances of :class:`Cave`
 
+    .. code-block:: python
+
       import grok
       from zope import interface
 
@@ -358,51 +392,58 @@
           grok.local_utility(Fireplace, public=True,
                              name_in_container='fireplace')
 
-.. seealso::
+  .. seealso::
 
    :func:`grok.global_utility`, :class:`grok.LocalUtility`
 
+
 :func:`grok.resourcedir --- XXX Not implemented yet`
 ====================================================
 
 .. function:: grok.resourcedir(*arg)
 
-   foobar
+  Resource directories are used to embed static resources like HTML-,
+  JavaScript-, CSS- and other files in your application.
 
-Resource directories are used to embed static resources like HTML-,
-JavaScript-, CSS- and other files in your application.
+  .. XXX insert directive description here (first: define the name,
+     second: describe the default behaviour if the directive isn't
+     given)
 
-XXX insert directive description here (first: define the name, second:
-describe the default behaviour if the directive isn't given)
+  A resource directory is created when a package contains a directory
+  with the name :file:`static`. All files from this directory become
+  accessible from a browser under the URL
+  :file:`http://<servername>/++resource++<packagename>/<filename>`.
 
-A resource directory is created when a package contains a directory with the
-name :file:`static`. All files from this directory become accessible from a
-browser under the URL
-:file:`http://<servername>/++resource++<packagename>/<filename>`.
+  **Example:**
 
-**Example:**
+    The package :mod:`a.b.c` is grokked and contains a directory
+    :file:`static` which contains the file :file:`example.css`. The
+    stylesheet will be available via
+    :file:`http://<servername>/++resource++a.b.c/example.css`.
 
-The package :mod:`a.b.c` is grokked and contains a directory :file:`static`
-which contains the file :file:`example.css`. The stylesheet will be
-available via :file:`http://<servername>/++resource++a.b.c/example.css`.
+  .. note::
 
-.. note::
+    A package can never have both a :file:`static` directory and a
+    Python module with the name :file:`static.py` at the same
+    time. grok will remind you of this conflict when grokking a
+    package by displaying an error message.
 
-A package can never have both a :file:`static` directory and a Python module
-with the name :file:`static.py` at the same time. grok will remind you of
-this conflict when grokking a package by displaying an error message.
 
-Linking to resources from templates
------------------------------------
+  **Linking to resources from templates**
 
-grok provides a convenient way to calculate the URLs to static resource using
-the keyword :keyword:`static` in page templates::
+  grok provides a convenient way to calculate the URLs to static
+  resource using the keyword :keyword:`static` in page templates:
 
-<link rel="stylesheet" tal:attributes="href static/example.css" type="text/css">
+  .. code-block:: html
 
-The keyword :keyword:`static` will be replaced by the reference to the resource
-directory for the package in which the template was registered.
+    <link rel="stylesheet" tal:attributes="href static/example.css"
+          type="text/css">
 
+  The keyword :keyword:`static` will be replaced by the reference to
+  the resource directory for the package in which the template was
+  registered.
+
+
 Security directives
 ~~~~~~~~~~~~~~~~~~~
 
@@ -411,73 +452,86 @@
 
 .. function:: grok.require(permission)
 
-A class level directive used to protect a View by requiring a certain permission. 
+  A class level directive used to protect a View by requiring a
+  certain permission.
 
-`permission` -- the name of the permission that is required
+  `permission` -- the name of the permission that is required
 
-** Example **::
+  **Example**
 
-	class ViewPainting(grok.Permission):
-	    grok.name('grok.ViewPainting')
+  .. code-block:: python
+
+    class ViewPainting(grok.Permission):
+	grok.name('grok.ViewPainting')
 	
+  .. seealso::
 
-.. seealso::
+    :class:`grok.Permission` component, :func:`@grok.require` decorator
 
-  :class:`grok.Permission` component, :func:`@grok.require` decorator
 
-
 Template directives
 ~~~~~~~~~~~~~~~~~~~
 
 :func:`grok.template`
 =====================
 
+A class level directive used to specify the template to be rendered
+for the View when no render method is defined.
+
 .. function:: grok.template(template)
 
-A class level directive used to specify the template to be rendered for the View when no render method is defined.
+  `template` -- name of the template file
 
-`template` -- name of the template file
+  **Convention**
 
-** Convention **
+  When not specified, Grok will look for a template file with the same
+  name as the view class itself, lowercased, in the templates directory
+  for this module.
 
-When not specified, Grok will look for a template file with the same name as the view class itself, lowercased, in the templates directory for this module.
+  .. seealso::
 
-.. seealso::
+    :func:`grok.templatedir`
 
-   :func:`grok.templatedir`
 
 :func:`grok.templatedir`
 ========================
 
-A module level directive used to specify the directory where Grok should look for template files.
+A module level directive used to specify the directory where Grok
+should look for template files.
 
-.. function:: grok.templatedir(directory)
+  .. function:: grok.templatedir(directory)
 
-`directory` -- the name of the directory inside the same package as the module
+    `directory` -- the name of the directory inside the same package
+                   as the module
 
-** Convention **
+  ** Convention **
 
-When not specified, Grok will look template files in a diretory named `<module>_templates` where `<module>` is the name of the current module.
+  When not specified, Grok will look template files in a diretory
+  named `<module>_templates` where `<module>` is the name of the current
+  module.
 
-.. seealso::
+  .. seealso::
 
-   :func:`grok.template`
+    :func:`grok.template`
 
+
 Uncategorized directives
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
 :func:`grok.site`
 =================
 
+A class level directive used in `grok.Indexes` sub-classes to define
+in which local component registry the indexes should be located.
+
 .. function:: grok.site(*arg)
 
-A class level directive used in `grok.Indexes` sub-classes to define in which local component registry the indexes should be located.
+  **Example**
 
-** Example **
-::
+  .. code-block:: python
 
-	class MammothIndexes(grok.Indexes):
-	    grok.site(Herd)
-	    grok.context(IMammoth)
+    class MammothIndexes(grok.Indexes):
+	grok.site(Herd)
+	grok.context(IMammoth)
 
-	    name = index.Field()
+	name = index.Field()

Modified: Sandbox/ulif/grok-testsetup/doc/reference/events.rst
===================================================================
--- Sandbox/ulif/grok-testsetup/doc/reference/events.rst	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/doc/reference/events.rst	2008-01-29 21:52:24 UTC (rev 83307)
@@ -3,9 +3,9 @@
 Events
 ******
 
-grok provides convenient access to a set of often-used events from Zope 3. Those
-events include object and containment events. All events are available as
-interface and implemented class.
+grok provides convenient access to a set of often-used events from
+Zope 3. Those events include object and containment events. All events
+are available as interface and implemented class.
 
 
 grok.IContainerModifiedEvent

Modified: Sandbox/ulif/grok-testsetup/doc/reference/exceptions.rst
===================================================================
--- Sandbox/ulif/grok-testsetup/doc/reference/exceptions.rst	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/doc/reference/exceptions.rst	2008-01-29 21:52:24 UTC (rev 83307)
@@ -3,32 +3,34 @@
 Exceptions
 **********
 
-grok tries to inform you about errors early and with as much guidance as
-possible. grok can detect some errors already while importing a module, which
-will lead to the :class:`GrokImportError`.  Other errors require more context
-and can only be detected while executing the :func:`grok` function.
+grok tries to inform you about errors early and with as much guidance
+as possible. grok can detect some errors already while importing a
+module, which will lead to the :class:`GrokImportError`.  Other errors
+require more context and can only be detected while executing the
+:func:`grok` function.
 
 
 :class:`grok.GrokImportError` -- errors while importing a module
 ================================================================
 
-This exception is raised if a grok-specific problem was found while importing a
-module of your application. :class:`GrokImportError` means there was a problem
-in how you are using a part of grok. The error message tries to be as
-informative as possible tell you why something went wrong and how you can fix
-it.
+This exception is raised if a grok-specific problem was found while
+importing a module of your application. :class:`GrokImportError` means
+there was a problem in how you are using a part of grok. The error
+message tries to be as informative as possible tell you why something
+went wrong and how you can fix it.
 
-:class:`GrokImportError` is a subclass of Python's :class:`ImportError`.
+:class:`GrokImportError` is a subclass of Python's
+:class:`ImportError`.
 
 Examples of situations in which a GrokImportError occurs:
 
-* Using a directive in the wrong context (e.g. grok.templatedir on class-level
-  instead of module-level.)
+  * Using a directive in the wrong context (e.g. grok.templatedir on
+    class-level instead of module-level.)
 
-* Using a decorator with wrong arguments (e.g. grok.subscribe without any
-  argument)
+  * Using a decorator with wrong arguments (e.g. grok.subscribe
+    without any argument)
 
-* ...
+  * ...
 
 
 :class:`grok.GrokError` -- errors while grokking a module
@@ -36,23 +38,23 @@
 
 This exception is raised if an error occurs while grokking a module.
 
-Typically a :class:`GrokError` will be raised if one of your modules uses a
-feature of grok that requires some sort of unambigous context to establish a
-reasonable default.
+Typically a :class:`GrokError` will be raised if one of your modules
+uses a feature of grok that requires some sort of unambigous context
+to establish a reasonable default.
 
-For example, the :class:`grok.View` requires exactly one model to be defined
-locally in the module to assume a default module to be associated with. Having
-no model defined, or more than one model, will lead to an error because the
-context is either underspecified or ambigous.
+For example, the :class:`grok.View` requires exactly one model to be
+defined locally in the module to assume a default module to be
+associated with. Having no model defined, or more than one model, will
+lead to an error because the context is either underspecified or
+ambigous.
 
-The error message of a :class:`GrokError` will include the reason for the error,
-the place in your code that triggered the error, and a hint, to help you fix the
-error.
+The error message of a :class:`GrokError` will include the reason for
+the error, the place in your code that triggered the error, and a
+hint, to help you fix the error.
 
 
 .. class:: GrokError(Exception)
 
-
    .. attribute:: GrokError.component
 
       The component that was grokked and triggered the error.

Modified: Sandbox/ulif/grok-testsetup/doc/reference/functions.rst
===================================================================
--- Sandbox/ulif/grok-testsetup/doc/reference/functions.rst	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/doc/reference/functions.rst	2008-01-29 21:52:24 UTC (rev 83307)
@@ -27,31 +27,34 @@
    directive, in that one field is omitted from the form before
    rendering:
 
-**Example:** ::
+   **Example:**
 
-   import grok
-   from zope import interface, schema
+   .. code-block:: python
 
-   class IMammoth(interface.Interface):
-       name = schema.TextLine(title=u"Name")
-       size = schema.TextLine(title=u"Size", default=u"Quite normal")
+     import grok
+     from zope import interface, schema
 
-   class Mammoth(grok.Model):
-       interface.implements(IMammoth)
+     class IMammoth(interface.Interface):
+         name = schema.TextLine(title=u"Name")
+         size = schema.TextLine(title=u"Size", default=u"Quite normal")
 
-   class Edit(grok.EditForm):
-       grok.context(Mammoth)
+     class Mammoth(grok.Model):
+         interface.implements(IMammoth)
 
-       form_fields = grok.AutoFields(Mammoth).omit('size')
+     class Edit(grok.EditForm):
+         grok.context(Mammoth)
 
-In this example the ``size`` attribute will not show up in the
-resulting edit view.
+         form_fields = grok.AutoFields(Mammoth).omit('size')
 
+   In this example the ``size`` attribute will not show up in the
+   resulting edit view.
 
-.. seealso::
 
-   :class:`grok.EditForm`, :func:`grok.Fields`
+   .. seealso::
 
+     :class:`grok.EditForm`, :func:`grok.Fields`
+
+
 :func:`grok.Fields` -- declare schema fields of a form
 ======================================================
 
@@ -63,8 +66,10 @@
    A :class:`grok.Fields` can receive keyword parameters with schema
    fields. These should be available in the definition order.
 
-   **Example:** ::
+   **Example:**
 
+   .. code-block:: python
+
       import grok
       from zope import schema
 
@@ -85,10 +90,10 @@
 
       :func:`grok.AutoFields`, :class:`grok.Form`
 
+
 :func:`grok.getSite`
 ===============================================
 
-
 .. function:: grok.getSite()
 
    Get the current site object.
@@ -103,7 +108,7 @@
    .. seealso::
 
       `Web Component Development With Zope 3, second edition <http://worldcookery.com/WhereToBuy>`_
-         By Philiip von Weitershaussen; Chapter 18 describes the use of Site objects.
+      By Philipp von Weitershausen; Chapter 18 describes the use of Site objects.
 
 
 :func:`grok.notify`
@@ -114,8 +119,10 @@
 
    Send `event` to event subscribers.
 
-   Example::
+   **Example:**
 
+   .. code-block:: python
+
       import grok
 
       class Mammoth(object):
@@ -135,7 +142,8 @@
    .. seealso::
 
       `Web Component Development With Zope 3, second edition <http://worldcookery.com/WhereToBuy>`_
-         By Philiip von Weitershaussen; Chapter 16 describes the Zope 3 event system.
+      By Philipp von Weitershausen; Chapter 16 describes the Zope 3
+      event system.
 
 
 :func:`grok.url`
@@ -146,16 +154,17 @@
 
    Construct a URL for the given `request` and `object`.
 
-   `name` may be a string that gets appended to the object URL. Commonly used to
-   construct an URL to a particular view on the object.
+   `name` may be a string that gets appended to the object
+   URL. Commonly used to construct an URL to a particular view on the
+   object.
 
    This function returns the constructed URL as a string.
 
 
    .. seealso::
 
-      View classes derived from :class:`grok.View` have a similar :meth:`url` method
-      for constructing URLs.
+      View classes derived from :class:`grok.View` have a similar
+      :meth:`url` method for constructing URLs.
 
 
 :func:`grok.grok` -- Grok a package or module
@@ -164,37 +173,40 @@
 
 .. function:: grok(dotted_name)
 
-.. note:: Usually you don't need to invoke this funtion in your code, since it's triggered from the `configure.zcml`. Grokking test fixtures is one  situation where it is useful to call this explicitly.
+.. note:: Usually you don't need to invoke this funtion in your code,
+          since it's triggered from the `configure.zcml`. Grokking
+          test fixtures is one situation where it is useful to call
+          this explicitly.
 
-Grokking a package or module activates the contained components (like models,
-views, adapters, templates, etc.) and registers them with Zope 3's component
-architecture.
+  Grokking a package or module activates the contained components
+  (like models, views, adapters, templates, etc.) and registers them
+  with Zope 3's component architecture.
 
-The `dotted_name` must specify either a Python module or package that is
-available from the current PYTHONPATH.
+  The `dotted_name` must specify either a Python module or package
+  that is available from the current PYTHONPATH.
 
-Grokking a module:
+  Grokking a module:
 
-#. Scan the module for known components: models, adapters, utilities, views,
-      traversers, templates and subscribers.
+    #. Scan the module for known components: models, adapters,
+       utilities, views, traversers, templates and subscribers.
 
-#. Check whether a directory with file system templates exists
-(:file:`<modulename>_templates`). If it exists, load the file system templates
-into the template registry for this module.
+    #. Check whether a directory with file system templates exists
+       (:file:`<modulename>_templates`). If it exists, load the file
+       system templates into the template registry for this module.
 
-#. Determine the module context.
+    #. Determine the module context.
 
-#. Register all components with the Zope 3 component architecture.
+    #. Register all components with the Zope 3 component architecture.
 
-#. Initialize schemata for registered models
+    #. Initialize schemata for registered models
 
-   Grokking a package:
+  Grokking a package:
 
-#. Grok the package as a module.
+    #. Grok the package as a module.
 
-#. Check for a static resource directory (:file:`static`) and register it if
-it exists.
+    #. Check for a static resource directory (:file:`static`) and
+       register it if it exists.
 
-#. Recursively grok all sub-modules and sub-packages.
+    #. Recursively grok all sub-modules and sub-packages.
 
 

Modified: Sandbox/ulif/grok-testsetup/setup.py
===================================================================
--- Sandbox/ulif/grok-testsetup/setup.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/setup.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -35,7 +35,7 @@
     include_package_data = True,
     zip_safe=False,
     install_requires=['setuptools',
-                      'martian >= 0.9.2',
+                      'martian >= 0.9.3',
                       'simplejson',
                       'pytz',
                       'ZODB3',

Modified: Sandbox/ulif/grok-testsetup/src/grok/__init__.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/__init__.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/__init__.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -42,7 +42,7 @@
 from grok.interfaces import IRESTSkinType
 from grok.directive import (context, name, title, template, templatedir,
                             provides, baseclass, global_utility, local_utility,
-                            permissions, require, site, layer, direct)
+                            permissions, require, site, layer, direct, order)
 from grok.decorators import subscribe, adapter, implementer
 from martian.error import GrokError, GrokImportError
 

Modified: Sandbox/ulif/grok-testsetup/src/grok/components.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/components.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/components.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -446,10 +446,10 @@
 
 
 class GrokForm(object):
-    """Mix-in to console zope.formlib's forms with grok.View and to
+    """Mix-in to consolidate zope.formlib's forms with grok.View and to
     add some more useful methods.
 
-    The consolation needs to happen because zope.formlib's Forms have
+    The consolidation needs to happen because zope.formlib's Forms have
     update/render methods which have different meanings than
     grok.View's update/render methods.  We deal with this issue by
     'renaming' zope.formlib's update() to update_form() and by

Modified: Sandbox/ulif/grok-testsetup/src/grok/directive.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/directive.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/directive.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -25,6 +25,7 @@
                                InterfaceDirective,
                                InterfaceOrClassDirective,
                                ModuleDirectiveContext,
+                               OptionalValueDirective,
                                ClassDirectiveContext,
                                ClassOrModuleDirectiveContext)
 from martian import util
@@ -104,6 +105,19 @@
     def value_factory(self, *args):
         return args
 
+class OrderDirective(OptionalValueDirective, OnceDirective):
+
+    order = 0
+
+    def value_factory(self, value=None):
+        OrderDirective.order += 1
+        if value is not None:
+            return value, OrderDirective.order
+        return super(OrderDirective, self).value_factory(value)
+
+    def default_value(self):
+        return 0, OrderDirective.order
+
 # Define grok directives
 name = SingleTextDirective('grok.name', ClassDirectiveContext())
 template = SingleTextDirective('grok.template', ClassDirectiveContext())
@@ -124,4 +138,5 @@
     'grok.permissions', ClassDirectiveContext())
 layer = InterfaceOrClassDirective('grok.layer',
                            ClassOrModuleDirectiveContext())
-direct = MarkerDirective('grok.direct', ClassDirectiveContext())
\ No newline at end of file
+direct = MarkerDirective('grok.direct', ClassDirectiveContext())
+order = OrderDirective('grok.order', ClassDirectiveContext())

Modified: Sandbox/ulif/grok-testsetup/src/grok/ftests/admin/docgrok.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/ftests/admin/docgrok.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/ftests/admin/docgrok.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -93,7 +93,19 @@
 
 and so on.
 
+A standard package, that should always be reachable, is the ``zope``
+package::
 
+  >>> browser.open('http://localhost:8080/docgrok/zope')
+  >>> print browser.contents
+  <html xmlns="http://www.w3.org/1999/xhtml">
+  ...
+  ...<span><a ...>zope</a></span>...
+  ...
+  ...(Python Package)...
+  ...
+  
+
 DocGrok for modules
 -------------------
 

Modified: Sandbox/ulif/grok-testsetup/src/grok/ftests/catalog/indexes_multiple_conflict.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/ftests/catalog/indexes_multiple_conflict.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/ftests/catalog/indexes_multiple_conflict.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -12,7 +12,7 @@
     ...
   GrokError: grok.Indexes in module <module
   'grok.ftests.catalog.indexes_multiple_conflict' from ...>
-  causes creation of catalog index 'name' in catalog u'', but an index
+  causes creation of catalog index 'name' in catalog '', but an index
   with that name is already present.
 
   >>> from zope.app.component.hooks import setSite

Modified: Sandbox/ulif/grok-testsetup/src/grok/interfaces.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/interfaces.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/interfaces.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -157,7 +157,26 @@
         It can only be used inside grok.Indexes subclasses.
         """
 
+    def order(value=None):
+        """Control the ordering of components.
 
+        If the value is specified, the order will be determined by sorting on 
+        it.
+        If no value is specified, the order will be determined by definition
+        order within the module.
+        If the directive is absent, the order will be determined by class name.
+        (unfortunately our preferred default behavior on absence which would
+        be like grok.order() without argument is hard to implement in Python)
+
+        Inter-module order is by dotted name of the module the
+        components are in; unless an explicit argument is specified to
+        ``grok.order()``, components are grouped by module.
+  
+        The function grok.util.sort_components can be used to sort
+        components according to these rules.
+        """
+
+
 class IGrokDecorators(interface.Interface):
 
     def subscribe(*classes_or_interfaces):

Modified: Sandbox/ulif/grok-testsetup/src/grok/meta.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/meta.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/meta.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -47,10 +47,28 @@
 import grok
 from grok import components, formlib, templatereg
 from grok.util import check_adapts, get_default_permission, make_checker
-from grok.util import determine_class_directive
+from grok.util import determine_class_directive, public_methods_from_class
+from grok.util import determine_module_context, determine_class_context
+from grok.util import check_context
 from grok.rest import RestPublisher
 from grok.interfaces import IRESTSkinType
 
+def get_context(module_info, factory):
+    context = module_info.getAnnotation('grok.context', None)
+    return determine_class_context(factory, context)
+
+def get_name_classname(factory):
+    return get_name(factory, factory.__name__.lower())
+
+def get_name(factory, default=''):
+    return grok.util.class_annotation(factory, 'grok.name', default)
+
+def get_provides(factory):
+    provides = util.class_annotation(factory, 'grok.provides', None)
+    if provides is None:
+        util.check_implements_one(factory)
+    return provides
+
 class ContextGrokker(martian.GlobalGrokker):
 
     priority = 1001
@@ -58,7 +76,7 @@
     def grok(self, name, module, module_info, config, **kw):
         possible_contexts = martian.scan_for_classes(module, [grok.Model,
                                                               grok.Container])
-        context = util.determine_module_context(module_info, possible_contexts)
+        context = determine_module_context(module_info, possible_contexts)
         module.__grok_context__ = context
         return True
 
@@ -67,13 +85,10 @@
     component_class = grok.Adapter
 
     def grok(self, name, factory, module_info, config, **kw):
-        context = module_info.getAnnotation('grok.context', None)
-        adapter_context = util.determine_class_context(factory, context)
-        provides = util.class_annotation(factory, 'grok.provides', None)
-        if provides is None:
-            util.check_implements_one(factory)
-        name = util.class_annotation(factory, 'grok.name', '')
-
+        adapter_context = get_context(module_info, factory)
+        provides = get_provides(factory)
+        name = get_name(factory)
+        
         config.action(
             discriminator=('adapter', adapter_context, provides, name),
             callable=component.provideAdapter,
@@ -85,11 +100,10 @@
     component_class = grok.MultiAdapter
 
     def grok(self, name, factory, module_info, config, **kw):
-        provides = util.class_annotation(factory, 'grok.provides', None)
-        if provides is None:
-            util.check_implements_one(factory)
+        provides = get_provides(factory)
+        name = get_name(factory)
+        
         check_adapts(factory)
-        name = util.class_annotation(factory, 'grok.name', '')
         for_ = component.adaptedBy(factory)
 
         config.action(
@@ -108,10 +122,9 @@
     priority = 1100
 
     def grok(self, name, factory, module_info, config, **kw):
-        provides = util.class_annotation(factory, 'grok.provides', None)
-        if provides is None:
-            util.check_implements_one(factory)
-        name = util.class_annotation(factory, 'grok.name', '')
+        provides = get_provides(factory)
+        name = get_name(factory)
+
         direct = util.class_annotation(factory, 'grok.direct', False)
         if not direct:
             factory = factory()
@@ -128,18 +141,14 @@
     component_class = grok.XMLRPC
 
     def grok(self, name, factory, module_info, config, **kw):
-        context = module_info.getAnnotation('grok.context', None)
-        view_context = util.determine_class_context(factory, context)
-        # XXX We should really not make __FOO__ methods available to
-        # the outside -- need to discuss how to restrict such things.
-        methods = util.methods_from_class(factory)
+        view_context = get_context(module_info, factory)
+        
+        methods = public_methods_from_class(factory)
 
         default_permission = get_default_permission(factory)
 
         for method in methods:
             name = method.__name__
-            if name.startswith('__'):
-                continue
 
             # Make sure that the class inherits MethodPublisher, so that the
             # views have a location
@@ -172,12 +181,10 @@
     component_class = grok.REST
 
     def grok(self, name, factory, module_info, config, **kw):
-        context = module_info.getAnnotation('grok.context', None)
-        view_context = util.determine_class_context(factory, context)
-        # XXX We should really not make __FOO__ methods available to
-        # the outside -- need to discuss how to restrict such things.
-        methods = util.methods_from_class(factory)
+        view_context = get_context(module_info, factory)
 
+        methods = public_methods_from_class(factory)
+
         default_permission = get_default_permission(factory)
 
         # grab layer from class or module
@@ -187,8 +194,6 @@
 
         for method in methods:
             name = method.__name__
-            if name.startswith('__'):
-                continue
 
             # Make sure that the class inherits RestPublisher, so that the
             # views have a location
@@ -221,12 +226,10 @@
     component_class = grok.View
 
     def grok(self, name, factory, module_info, config, **kw):
-        context = module_info.getAnnotation('grok.context', None)
-        view_context = util.determine_class_context(factory, context)
+        view_context = get_context(module_info, factory)
 
         factory.module_info = module_info
-        factory_name = factory.__name__.lower()
-
+        
         if util.check_subclass(factory, components.GrokForm):
             # setup form_fields from context class if we've encountered a form
             if getattr(factory, 'form_fields', None) is None:
@@ -245,7 +248,7 @@
             config.action(
                 discriminator=None,
                 callable=templates.checkTemplates,
-                args=(module_info, factory, factory_name)
+                args=(module_info, factory, factory.__name__.lower())
             )
 
         # safety belt: make sure that the programmer didn't use
@@ -263,8 +266,7 @@
                                                factory, module_info,
                                                default=IDefaultBrowserLayer)
 
-        view_name = util.class_annotation(factory, 'grok.name',
-                                          factory_name)
+        view_name = get_name_classname(factory)
         # __view_name__ is needed to support IAbsoluteURL on views
         factory.__view_name__ = view_name
         adapts = (view_context, view_layer)
@@ -292,13 +294,20 @@
     component_class = grok.JSON
 
     def grok(self, name, factory, module_info, config, **kw):
-        context = module_info.getAnnotation('grok.context', None)
-        view_context = util.determine_class_context(factory, context)
-        methods = util.methods_from_class(factory)
+        view_context = get_context(module_info, factory)
 
+        methods = public_methods_from_class(factory)
+
         default_permission = get_default_permission(factory)
 
         for method in methods:
+            # The grok.JSON component inherits methods from its baseclass
+            # (being zope.publisher.browser.BrowserPage) with names that
+            # do not start with an underscore, but should still not
+            # be registered as views. Ignore these methods:
+            if method.__name__ in ['browserDefault', 'publishTraverse']:
+                continue
+
             # Create a new class with a __view_name__ attribute so the
             # JSON class knows what method to call.
             method_view = type(
@@ -333,8 +342,7 @@
     component_class = grok.Traverser
 
     def grok(self, name, factory, module_info, config, **kw):
-        context = module_info.getAnnotation('grok.context', None)
-        factory_context = util.determine_class_context(factory, context)
+        factory_context = get_context(module_info, factory)
         adapts = (factory_context, IBrowserRequest)
 
         config.action(
@@ -444,7 +452,7 @@
             if interfaces is None:
                 # There's no explicit interfaces defined, so we assume the
                 # module context to be the thing adapted.
-                util.check_context(module_info.getModule(), context)
+                check_context(module_info.getModule(), context)
                 interfaces = (context, )
 
             config.action(
@@ -646,7 +654,7 @@
     priority = 1500
 
     def grok(self, name, factory, module_info, config, **kw):
-        id = util.class_annotation(factory, 'grok.name', None)
+        id = get_name(factory, None)
         if id is None:
             raise GrokError(
                 "A permission needs to have a dotted name for its id. Use "
@@ -672,7 +680,7 @@
     priority = PermissionGrokker.priority - 1
 
     def grok(self, name, factory, module_info, config, **kw):
-        id = util.class_annotation(factory, 'grok.name', None)
+        id = get_name(factory, None)
         if id is None:
             raise GrokError(
                 "A role needs to have a dotted name for its id. Use "
@@ -704,8 +712,9 @@
     component_class = grok.Annotation
 
     def grok(self, name, factory, module_info, config, **kw):
-        context = module_info.getAnnotation('grok.context', None)
-        adapter_context = util.determine_class_context(factory, context)
+        adapter_context = get_context(module_info, factory)
+        # XXX cannot use get_provides here, can we refactor others to reuse
+        # this bit?
         provides = util.class_annotation(factory, 'grok.provides', None)
         if provides is None:
             base_interfaces = interface.implementedBy(grok.Annotation)
@@ -714,7 +723,7 @@
             util.check_implements_one_from_list(real_interfaces, factory)
             provides = real_interfaces[0]
 
-        key = util.class_annotation(factory, 'grok.name', None)
+        key = get_name(factory, None)
         if key is None:
             key = factory.__module__ + '.' + factory.__name__
 
@@ -772,9 +781,8 @@
         indexes = util.class_annotation(factory, 'grok.indexes', None)
         if indexes is None:
             return False
-        context = module_info.getAnnotation('grok.context', None)
-        context = util.determine_class_context(factory, context)
-        catalog_name = util.class_annotation(factory, 'grok.name', u'')
+        context = get_context(module_info, factory)
+        catalog_name = get_name(factory)
 
         subscriber = IndexesSetupSubscriber(catalog_name, indexes,
                                             context, module_info)
@@ -844,8 +852,7 @@
     def grok(self, name, factory, module_info, config, **kw):
         layer = determine_class_directive('grok.layer', factory, module_info,
                                           default=IBrowserRequest)
-        name = grok.util.class_annotation(factory, 'grok.name',
-                                          factory.__name__.lower())
+        name = get_name_classname(factory)
         config.action(
             discriminator=None,
             callable=zope.component.interface.provideInterface,
@@ -859,8 +866,7 @@
     def grok(self, name, factory, module_info, config, **kw):
         layer = determine_class_directive('grok.layer', factory, module_info,
                                           default=IBrowserRequest)
-        name = grok.util.class_annotation(factory, 'grok.name',
-                                          factory.__name__.lower())
+        name = get_name_classname(factory)
         config.action(
             discriminator=None,
             callable=zope.component.interface.provideInterface,

Modified: Sandbox/ulif/grok-testsetup/src/grok/tests/form/fields.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/tests/form/fields.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/tests/form/fields.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -1,6 +1,6 @@
 """
 A grok.Fields can receive keyword parameters with schema fields. These
-should be avaible in the definition order.
+should be available in the definition order.
 
   >>> grok.testing.grok(__name__)
 

Modified: Sandbox/ulif/grok-testsetup/src/grok/tests/json/view_lookup.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/tests/json/view_lookup.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/tests/json/view_lookup.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -20,7 +20,44 @@
   >>> view = getMultiAdapter((mammoth, request), name='another')
   >>> view()
   '{"another": "grok"}'
-  
+
+Although principally all methods of the JSON class are registered as views,
+methods with names that start with an underscore are not::
+
+  >>> view = getMultiAdapter((mammoth, request), name='_private')
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: ((<grok.tests.json.view_lookup.Mammoth object at ...>,
+  <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
+  <InterfaceClass zope.interface.Interface>, '_private')
+
+Even more important, special methods like __call__ are not registered as viewws
+too. This test is here to make sure a previous bug has been fixed::
+
+  >>> view = getMultiAdapter((mammoth, request), name='__call__')
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: ((<grok.tests.json.view_lookup.Mammoth object at ...>,
+  <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
+  <InterfaceClass zope.interface.Interface>, '__call__')
+
+For JSON views we also need to confirm some methods that are defined on the
+baseclass (BrowserPage) are not registered as views::
+
+  >>> view = getMultiAdapter((mammoth, request), name='browserDefault')
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: ((<grok.tests.json.view_lookup.Mammoth object at ...>,
+  <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
+  <InterfaceClass zope.interface.Interface>, 'browserDefault')
+
+  >>> view = getMultiAdapter((mammoth, request), name='publishTraverse')
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: ((<grok.tests.json.view_lookup.Mammoth object at ...>,
+  <zope.publisher.browser.TestRequest instance URL=http://127.0.0.1>),
+  <InterfaceClass zope.interface.Interface>, 'publishTraverse')
+
 """
 import grok
 
@@ -35,4 +72,9 @@
 
     def another(self):
         return { 'another': 'grok'}
-    
+
+class SecondMammothView(grok.JSON):
+    grok.context(Mammoth)
+
+    def _private(self):
+        return {'should': 'not be registered'}

Copied: Sandbox/ulif/grok-testsetup/src/grok/tests/order (from rev 83306, grok/trunk/src/grok/tests/order)

Modified: Sandbox/ulif/grok-testsetup/src/grok/tests/test_grok.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/tests/test_grok.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/tests/test_grok.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -45,7 +45,7 @@
     for name in ['adapter', 'error', 'view', 'event', 'security', 'catalog',
                  'zcml', 'static', 'utility', 'xmlrpc', 'json', 'container',
                  'traversal', 'form', 'grokker', 'directive', 'util',
-                 'baseclass', 'annotation', 'application', 'template',
+                 'baseclass', 'annotation', 'application', 'template', 'order',
                  'testsetup']:
         suite.addTest(suiteFromPackage(name))
     return suite

Copied: Sandbox/ulif/grok-testsetup/src/grok/tests/util/public_methods_from_class.py (from rev 83306, grok/trunk/src/grok/tests/util/public_methods_from_class.py)
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/tests/util/public_methods_from_class.py	                        (rev 0)
+++ Sandbox/ulif/grok-testsetup/src/grok/tests/util/public_methods_from_class.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -0,0 +1,28 @@
+"""
+  >>> methods = grok.util.public_methods_from_class(A)
+  >>> sorted([m.__name__ for m in methods])
+  ['should_also_be_public', 'should_be_public']
+
+"""
+import grok
+import grok.util
+
+class A(object):
+
+    def __init__(self):
+        pass # this method is ignored
+
+    def __call__(self):
+        pass # this method is ignored
+
+    def __double_underscored(self):
+        pass # this method is ignored
+
+    def _single_underscored(self):
+        pass # this method is ignored
+
+    def should_be_public(self):
+        pass # this method is found
+
+    def should_also_be_public(self):
+        pass # this method is found

Modified: Sandbox/ulif/grok-testsetup/src/grok/util.py
===================================================================
--- Sandbox/ulif/grok-testsetup/src/grok/util.py	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/src/grok/util.py	2008-01-29 21:52:24 UTC (rev 83307)
@@ -25,7 +25,7 @@
 from zope.security.interfaces import IPermission
 
 from martian.error import GrokError, GrokImportError
-from martian.util import class_annotation
+from martian.util import class_annotation, methods_from_class
 
 def check_adapts(class_):
     if component.adaptedBy(class_) is None:
@@ -60,7 +60,7 @@
 
 def get_default_permission(factory):
     """Determine the default permission for a view.
-    
+
     There can be only 0 or 1 default permission.
     """
     permissions = class_annotation(factory, 'grok.require', [])
@@ -78,7 +78,7 @@
     """Given a request and an object, give the URL.
 
     Optionally pass a third argument name which gets added to the URL.
-    """    
+    """
     url = component.getMultiAdapter((obj, request), IAbsoluteURL)()
     if name is None:
         return url
@@ -105,3 +105,49 @@
     if directive is not None:
         return directive
     return default
+
+def public_methods_from_class(factory):
+    return [m for m in methods_from_class(factory) if \
+            not m.__name__.startswith('_')]
+
+def _sort_key(component):
+    explicit_order, implicit_order = class_annotation(component,
+                                                      'grok.order',
+                                                      (0,0))
+    return (explicit_order,
+            component.__module__,
+            implicit_order,
+            component.__class__.__name__)
+
+def sort_components(components):
+    # if components have a grok.order directive, sort by that
+    return sorted(components, key=_sort_key)
+
+AMBIGUOUS_CONTEXT = object()
+def check_context(component, context):
+    if context is None:
+        raise GrokError("No module-level context for %r, please use "
+                        "grok.context." % component, component)
+    elif context is AMBIGUOUS_CONTEXT:
+        raise GrokError("Multiple possible contexts for %r, please use "
+                        "grok.context." % component, component)
+
+def determine_module_context(module_info, models):
+    if len(models) == 0:
+        context = None
+    elif len(models) == 1:
+        context = models[0]
+    else:
+        context = AMBIGUOUS_CONTEXT
+
+    module_context = module_info.getAnnotation('grok.context', None)
+    if module_context:
+        context = module_context
+
+    return context
+
+
+def determine_class_context(class_, module_context):
+    context = class_annotation(class_, 'grok.context', module_context)
+    check_context(class_, context)
+    return context

Modified: Sandbox/ulif/grok-testsetup/versions.cfg
===================================================================
--- Sandbox/ulif/grok-testsetup/versions.cfg	2008-01-29 21:26:35 UTC (rev 83306)
+++ Sandbox/ulif/grok-testsetup/versions.cfg	2008-01-29 21:52:24 UTC (rev 83307)
@@ -1,7 +1,7 @@
 [versions]
 ClientForm = 0.2.7
 docutils = 0.4
-martian = 0.9.2
+martian = 0.9.3
 mechanize = 0.1.7b
 Pygments = 0.8.1
 pytz = 2007g
@@ -14,7 +14,7 @@
 ZODB3 = 3.8.0b2
 zodbcode = 3.4.0b1dev-r75670
 zope.annotation = 3.4.0
-zope.app.apidoc = 3.4.0a1
+zope.app.apidoc = 3.4.0
 zope.app.applicationcontrol = 3.4.1
 zope.app.appsetup = 3.4.1
 zope.app.authentication = 3.4.0a1



More information about the Checkins mailing list