[Checkins] SVN: Sandbox/ulif/grok-adminui-experimental/ Merged trunk into adminui-experimental branch.

Uli Fouquet uli at gnufix.de
Thu Aug 30 19:53:55 EDT 2007


Log message for revision 79388:
  Merged trunk into adminui-experimental branch.

Changed:
  A   Sandbox/ulif/grok-adminui-experimental/CHANGES.txt
  U   Sandbox/ulif/grok-adminui-experimental/CREDITS.txt
  U   Sandbox/ulif/grok-adminui-experimental/README.txt
  U   Sandbox/ulif/grok-adminui-experimental/buildout.cfg
  A   Sandbox/ulif/grok-adminui-experimental/doc/examples/MOVED.txt
  D   Sandbox/ulif/grok-adminui-experimental/doc/examples/adder/
  D   Sandbox/ulif/grok-adminui-experimental/doc/examples/animaltree/
  D   Sandbox/ulif/grok-adminui-experimental/doc/examples/bookshelf/
  D   Sandbox/ulif/grok-adminui-experimental/doc/examples/todolist/
  U   Sandbox/ulif/grok-adminui-experimental/doc/grok2html.py
  U   Sandbox/ulif/grok-adminui-experimental/doc/index.txt
  U   Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/index.txt
  U   Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/macros.txt
  A   Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/permissions.txt
  A   Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/xmlrpc.txt
  U   Sandbox/ulif/grok-adminui-experimental/doc/reference/directives.tex
  U   Sandbox/ulif/grok-adminui-experimental/doc/reference/reference.tex
  U   Sandbox/ulif/grok-adminui-experimental/grokwiki/src/grokwiki/wiki.py
  D   Sandbox/ulif/grok-adminui-experimental/setup.cfg
  U   Sandbox/ulif/grok-adminui-experimental/setup.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/__init__.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/_grok.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/README.txt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/__init__.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.txt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/objectinfo.txt
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/GROK_Logo.jpg
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok-relax.jpg
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok-relax5.png
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok.css
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/tests/test_grokadmin.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokclassview.pt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokgrokapplicationview.pt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokinterfaceview.pt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokmoduleview.pt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokpackageview.pt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgroktextfileview.pt
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/loginform.pt
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/logout.pt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/macros.pt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/server.pt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/components.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/directive.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftesting.zcml
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/README.txt
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/apps.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/brokenobjs.py
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/loginlogout.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/objectbrowser.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/catalog.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_app_interface.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_attribute.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_class.py
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_module.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple_conflict.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_name.py
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_no_app.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_nonexistent.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_set.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_site.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/setuporder.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/actions.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_applydata.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_catalog.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_classfields.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_schema.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/form.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/templateform.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/update.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/grant.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/handle_exception.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/json.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/require.py
  A   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/roles.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/xmlrpc.py
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/static/
  A   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/staticdir/
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/test_grok_functional.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverse.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverser.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/items_before_views.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/modeltraverse.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser_sets_parent.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/application.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/redirect.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url_function.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local_override.py
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_class.py
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_directive.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/public.py
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/publicnoncontainer.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/subclass.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/argument.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/index.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/macros.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/view.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc/xmlrpc.py
  D   Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc_helper.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/interfaces.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/meta.py
  A   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/catalog/
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json2.py
  A   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_name.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc2.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc3.py
  A   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_role_name.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_json.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_xmlrpc.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/view_decorator.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/test_grok.py
  A   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_class.py
  A   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_directive.py
  A   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/publicnoncontainer.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/view/dirtemplatesonly.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/tests/zcml/directiveerror.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/util.py
  U   Sandbox/ulif/grok-adminui-experimental/src/grok/zcml.py

-=-
Copied: Sandbox/ulif/grok-adminui-experimental/CHANGES.txt (from rev 79383, grok/trunk/CHANGES.txt)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/CHANGES.txt	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/CHANGES.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,64 @@
+Grok changes
+************
+
+0.11 (unreleased)
+=================
+
+Feature changes
+---------------
+
+* Removed grok.define_permission in favor of the grok.Permission
+  component base class
+
+* Add the grok.Role component base class.
+
+Restructuring
+-------------
+
+* The <grok:grok /> ZCML directive now emits a configuration action
+  instead of grokking right away at XML parsing time.  That way
+  grokkers can depend on components that are set up using regular ZCML
+  (e.g. checking for a permission that's defined in ZCML).
+
+* Changed the way grok's functional tests are set up.  Instead of each
+  test case doing its own test setup, it is now done once by the
+  ftesting layer.  This avoids ordering problems when some ftests
+  would influence the environment of other ftests that were run later
+  in time.
+
+0.10 (2007-08-21)
+=================
+
+Feature changes
+---------------
+
+* Integrated admin user interface.
+
+* Configuration using Martian (http://pypi.python.org/pypi/martian).
+
+* Flash message infrastructure included.
+
+* Adjust dependencies for Grok so that grokproject should work on
+  Windows.
+
+Bug fixes
+---------
+ 
+* A fix in Martian where multiple grok.Model or grok.Container classes
+  could result in something being found as a context twice.
+
+0.9 series (early 2007 until july 2007)
+=======================================
+
+Feature changes
+---------------
+
+Grok was released in "continuous release" mode from SVN during this period.
+
+0.1 series (september 2006 until early 2007)
+============================================
+
+Feature changes
+---------------
+
+Grok was created in september 2006.

Modified: Sandbox/ulif/grok-adminui-experimental/CREDITS.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/CREDITS.txt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/CREDITS.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -11,6 +11,8 @@
 
 * Jan-Wijbrand Kolman (Grok Zwei sprint, meta grokker improvements)
 
+* Uli Fouquet (admin interface, summer of code student)
+
 * Darryl Cousins (website, admin interface)
 
 * Kevin Teague (website)
@@ -25,6 +27,8 @@
 
 * Mikhail Kashkin
 
+* Wim Boucqaert (admin interface layout improvements)
+
 * ME GROK (team mascot)
 
 Thank you

Modified: Sandbox/ulif/grok-adminui-experimental/README.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/README.txt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/README.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,3 +1,6 @@
+Grok
+****
+
 What is grok?
 =============
 
@@ -10,6 +13,9 @@
 configuration language like ZCML nor a lot of repetition are needed to
 create a web application with grok.
 
+You can find out much more about Grok at our http://grok.zope.org
+website.
+
 Who is grok?
 ============
 

Modified: Sandbox/ulif/grok-adminui-experimental/buildout.cfg
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/buildout.cfg	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/buildout.cfg	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,7 +2,12 @@
 develop = . doc grokwiki
 parts = docs grokwiki zopectl data test
 find-links = http://download.zope.org/distribution/
+index = http://download.zope.org/ppix
+versions = release-0.10
 
+[release-0.10]
+ZODB3 = 3.8.0b2
+
 [docs]
 recipe = zc.recipe.egg
 eggs = grokdocs
@@ -52,5 +57,5 @@
 
 [test]
 recipe = zc.recipe.testrunner
-eggs = grok
+eggs = grok 
 defaults = ['--tests-pattern', '^f?tests$', '-v']

Copied: Sandbox/ulif/grok-adminui-experimental/doc/examples/MOVED.txt (from rev 79383, grok/trunk/doc/examples/MOVED.txt)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/examples/MOVED.txt	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/doc/examples/MOVED.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,3 @@
+The examples were moved to the grokapps dir at the root of this repository:
+
+http://svn.zope.org/grokapps/

Modified: Sandbox/ulif/grok-adminui-experimental/doc/grok2html.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/grok2html.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/grok2html.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -178,6 +178,12 @@
     rest_files.append(RestFile('testing', 
                               os.path.join(source_dir, 'minitutorials', 'testing.txt'),
                               os.path.join(www_dir, 'minitutorials', 'testing.html')))
+    rest_files.append(RestFile('xmlrpc', 
+                              os.path.join(source_dir, 'minitutorials', 'xmlrpc.txt'),
+                              os.path.join(www_dir, 'minitutorials', 'xmlrpc.html')))
+    rest_files.append(RestFile('permissions', 
+                              os.path.join(source_dir, 'minitutorials', 'permissions.txt'),
+                              os.path.join(www_dir, 'minitutorials', 'permissions.html')))
     rest_files.append(RestFile('zc.buildout', 
                   'http://svn.zope.org/*checkout*/zc.buildout/trunk/doc/tutorial.txt',
                   os.path.join(www_dir, 'minitutorials', 'buildout.html')))

Modified: Sandbox/ulif/grok-adminui-experimental/doc/index.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/index.txt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/index.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -53,7 +53,7 @@
 * `Introduction to Grok`_ is a talk given by Philipp von Weitershausen to a group of Zope developers.
 
 .. _Simple ToDo: http://www.archive.org/details/grok_todo_part1 
-.. _Introduction to Grok: http://comlounge.tv/blog/archive/2007/02/11/cltv23-snow-sprint-2007-grok-presentation
+.. _Introduction to Grok: http://comlounge.tv/blog/zope/cltv23-snow-sprint-2007-grok-presentation
 
 
 What does Grok code look like?
@@ -108,8 +108,9 @@
 ME GROK MINI-TUTORIALS!
 -----------------------
 
-* `Newbie Search HowTo <minitutorials/searching.html>`_
-* `Newbie Macros HowTo <minitutorials/macros.html>`_
+* `Newbie Search HowTo <minitutorials/searching.html>`_ Sebastian Ware
+* `Newbie Macros HowTo <minitutorials/macros.html>`_ Uli Fouquet
+* `Newbie XMLRPC HowTo <minitutorials/xmlrpc.html>`_ Kushal Das
 
 ME GROK SPRINTS AND BLOGS!
 --------------------------

Modified: Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/index.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/index.txt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/index.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -26,6 +26,14 @@
 
   Author: Uli Fouquet
 
+* `XMLRPC With Grok </minitutorials/xmlrpc.html>`_:
+
+  XMLRPC (http://xmlrpc.com) is a spec and a set of implementations
+  that allow software running on disparate operating systems, running in
+  different environments to make procedure calls over the Internet.
+
+  Author: Kushal Das
+
 Buildout
 ========
 

Modified: Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/macros.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/macros.txt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/macros.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -71,7 +71,7 @@
 
     metal:define-slot=<slot-name> 
 
-Let's define a very plain page macro:
+Let's define a very plain page macro in ``app_templates/mymacros.pt``:
 
 .. code-block:: html
 
@@ -140,8 +140,8 @@
 
     <html metal:use-macro="context/@@mymacros/mypage">
       <body>
-        <!-- slot 'mybody' was defined in the macro above -->
-        <div metal:fill-slot="mybody">
+        <!-- slot 'mycontent' was defined in the macro above -->
+        <div metal:fill-slot="mycontent">
           My content from index.pt
         </div>
       </body>

Copied: Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/permissions.txt (from rev 79383, grok/trunk/doc/minitutorials/permissions.txt)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/permissions.txt	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/permissions.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,245 @@
+===========================
+Newbie Permissions Tutorial
+===========================
+
+:Author: Luis De la Parra; Uli Fouquet; Jan-Wijbrand Kolman
+
+Intended Audience:
+
+  * Python Developers
+
+  * Zope 2 Developers
+
+  * Zope 3 Developers
+
+Introduction
+-------------
+
+Zope3 and Grok come with authorization capabilities out of the box.  While a
+vanilla Zope3 application protects all content by default and performs
+authorization checks on the content objects themselves, Grok allows access to
+everything unless you explicitly restrict it. The authorization checks here
+are done based on the ``Views`` used to access (display/manipulate) the
+content.
+
+Setup
+-----
+
+.. code-block:: python
+
+     #contact.py
+     from zope import component, interface, schema
+     import grok
+
+     class IContactInfo(interface.Interface):
+         """ Interface/Schema for Contact Information """
+         first_name = schema.Text(title=u'First Name')
+         last_name  = schema.Text(title=u'Last Name')
+         email      = schema.Text(title=u'E-mail')
+
+
+     class ContactInfo(grok.Model):
+         interface.implements(IContactInfo)
+
+         first_name = ''
+         last_name  = ''
+         email = ''
+
+     class ViewContact(grok.View)
+         """Display Contact Info, without e-mail.
+
+         Anyone can use this view, even unauthenticated users
+         over the internet
+         """
+         def render(self):
+             contact = self.context
+             return 'Contact: ' + contact.first_name + contact.last_name
+
+Defining Permissions and restricting access
+-------------------------------------------
+
+As all Views in Grok default to public access, anyone can use the
+``ViewContact``-view defined above. If you want to restrict access to a view,
+you have to explicitly protect it with a permission:
+
+.. code-block:: python
+
+     # Define Permissions. The grok.name can be any string, but it is strongly
+     # recommended to make them unique by prefixing them with the application
+     # name.
+     class ViewContacts(grok.Permission):
+         grok.name('mysite.ViewContacts')
+         grok.title('View Contacts') # optional
+
+     class AddContacts(grok.Permission):
+         grok.name('mysite.AddContacts')
+
+     class EditContacts(grok.Permission):
+         grok.name('mysite.EditContacts')
+
+     class ViewContactComplete(grok.View)
+         """Display Contact Info, including email.
+
+         Only users which have the permission 'mysite.ViewContacts'
+         can use this view.
+         """"
+         grok.require('mysite.ViewContacts')  #this is the security declaration
+
+         def render(self):
+             contact = self.context
+             return 'Contact: %s%s%s' % (contact.first_name,
+                                         contact.last_name,
+                                         contact.email)
+
+*Note* The ``grok.Permission`` component base class was introduced *after* the
+release 0.10. In earlier versions of Grok a permission was defined using a
+module level directive, like so:
+
+.. code-block:: python
+
+     grok.define_permission('mysite.ViewContacts')
+
+If you are using ``grokproject`` this change currently does not affect your
+installation. In this case use ``grok.define_permission`` as described above.
+
+Granting Permissions
+--------------------
+
+You can grant permissions to principals with a ``PermissionManager``. For
+example, if all registered users should have permission to view contact
+details and to create new contacts, you could grant them the permissions when
+the user account is created:
+
+.. code-block:: python
+
+     from zope.app.security.interfaces import IAuthentication
+     from zope.app.securitypolicy.interfaces import IPrincipalPermissionManager
+
+     def addUser(username, password, realname):
+         """Create a new user.
+
+         create a new user and give it the authorizations,
+         ``ViewContacts`` and ``EditContacts``. This example assumes
+         you are using a Pluggable Authentication Utility (PAU) /
+         PrincipalFolder, which you have to create and register when
+         creating your Application.
+         """
+
+         pau = component.getUtility(IAuthentication)
+         principals = pau['principals']
+         principals[username] = InternalPrincipal(username, password, realname)
+
+         # grant the user permission to view and create contacts
+         # everywhere in the site
+         permission_man = IPrincipalPermissionManager(grok.getSite())
+
+         # NOTE that you need a principal ID. If you are
+         # authenticating users with a PAU this is normally the user
+         # name prepended with the principals-folder prefix (and the
+         # PAU-prefix as well, if set)
+         permission_man.grantPermissionToPrincipal (
+            'mysite.ViewContacts',
+            principals.prefix + username)
+         permission_man.grantPermissionToPrincipal(
+            'mysite.AddContacts',
+            principals.prefix + username)
+
+Permissions are granted for the context for which the PermissionManager is
+created, and -- if not explicitly overridden -- all its children. The above
+example grants ``View`` and ``Add`` permissions for the complete site, unless
+a folder down in the hierarchy revokes the permission.
+
+If you want users to be able to edit only their own ``ContactInfos``, you have
+to give them the ``Edit`` permission only within the context of the
+``ContactInfo``-object itself
+
+.. code-block:: python
+
+     class AddContact(grok.AddForm):
+         """Add a contact.
+         """
+
+         # Only users with permission 'mysite.AddContacts' can use
+         # this.
+         #
+         # NOTE that if you don't protect this Form, anyone -- even
+         # anonymous/unauthenticated users -- could add ``Contacts``
+         # to the site.
+         grok.require('mysite.AddContacts')
+
+         #automagically generate form fields
+         form_fields = grok.AutoFields(IContactInfo)
+
+         @grok.action('Create')
+         def create(self, **kw):
+             # Create and add the ``ContactInfo`` to our context
+             # (normally a folder/container)
+             contact = ContactInfo()
+             self.applyData(contact, **kw)
+             self.context[contact.first_name] = contact
+
+             # Grant the current user the Edit permission, but only in
+	     # the context of the newly created object.
+             permission_man = IPrincipalPermissionManager(contact)
+             permission_man.grantPermissionToPrincipal(
+                 'mysite.EditContacts',
+                 self.request.principal.id)
+             self.redirect(self.url(contact))
+
+     class EditContact(grok.EditForm):
+         """Edit a contact.
+         """
+
+         #only users with permission 'mysite.EditContacts' can use this
+         grok.require('mysite.EditContacts')
+
+         form_fields = grok.AutoFields(IContactInfo)
+
+         @grok.action('Save Changes')
+         def edit(self, **data):
+             self.applyData(self.context, **data)
+             self.redirect(self.url(self.context))
+
+Checking Permissions
+--------------------
+
+[FIXME How to check permissions in a page template and from python
+code?  User Interfaces should not contain any links/actions which
+users cannot access / for which users don't have authorizations]
+
+Defining Roles
+--------------
+
+Permissions can be grouped together in ``Roles``, which makes granting all the
+permissions for a particular type of user much easier. Defining roles is
+similar to defining permissions.
+
+As an example, let's group all permissions in two roles: one for normal site
+members, and one for administrators:
+
+.. code-block:: python
+
+     class MemberRole(grok.Role):
+         grok.name('mysite.Member')
+         grok.title('Contacts Member') # optional
+         grok.permissions(
+             'mysite.ViewContacts',
+             'mysite.AddContacts')
+
+     class AdministratorRole(grok.Role):
+         grok.name('mysite.Editor')
+         grok.title('Contacts Administrator') # optional
+         grok.permissions(
+             'mysite.ViewContacts',
+             'mysite.AddContacts',
+             'mysite.EditContacts')
+
+Now, if the context here is the site/application, users with the administrator
+role can edit all ContactInfos, regardless of who the creator is.
+
+.. code-block:: python
+
+     from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+
+     role_man = IPrincipalRoleManager(context)
+     role_man.assignRoleToPrincipal('mysite.Administrator', principalID)

Copied: Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/xmlrpc.txt (from rev 79383, grok/trunk/doc/minitutorials/xmlrpc.txt)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/xmlrpc.txt	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/doc/minitutorials/xmlrpc.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,149 @@
+====================
+XML-RPC using Grok
+====================
+
+:Author: Kushal Das
+
+What is XML-RPC ?
+------------------
+
+From the site (http://xmlrpc.com): it's a spec and a set of implementations
+that allow software running on disparate operating systems, running in
+different environments to make procedure calls over the Internet.
+
+So, What is Grok?
+------------------
+
+From the site: Grok is a web application framework for Python developers. It
+is aimed at both beginners and very experienced web developers. Grok has an
+emphasis on agile development. Grok is easy and powerful.
+
+Grok accomplishes this by being based on Zope 3, an advanced object-oriented
+web framework. While Grok is based on Zope 3, and benefits a lot from it, you
+do not need to know Zope at all in order to get productive with Grok. 
+
+So, it is cool, isn't it? :)
+
+Installation
+--------------
+
+To install the latest grok, give the following command::
+
+    $ sudo easy_install grokproject
+
+This will download and install grok for you. After this we are ready to rock...
+
+Creating our first project
+-----------------------------
+
+Let's create the project named "Foo". For that give the command::
+
+    $ grokproject Foo
+
+This will create a subdirectory in the current directory named "Foo", then it
+will download Zope3 and install Grok with that which you can start working
+with. It will ask you a few questions like::
+
+    Enter module (Name of a demo Python module placed into the package) ['app.py']:
+
+Press Enter for the default value. Then::
+
+    Enter user (Name of an initial administrator user): grok
+    Enter passwd (Password for the initial administrator user): grok
+
+We typed "grok" for both the user and password.
+
+Starting up Zope
+--------------------
+
+Switch to the Foo directory, and give the command::
+
+    $ bin/zopectl fg
+
+This will startup Zope for you, you can access it through a web browser 
+pointing to http://localhost:8080/ . Then add an application named *foo*.
+
+You can access it by http://localhost:8080/foo, it will show::
+
+    Congratulations!
+
+    Your Grok application is up and running. Edit foo/app_templates/index.pt to
+    change this page.
+
+Now we are going to write our xmlrpc stuffs inside it.
+
+XML-RPC class
+-----------------
+
+Now you can open the file src/foo/app.py in a text editor. The default is
+shown below::
+
+    import grok
+
+    class Foo(grok.Application, grok.Container):
+        pass
+    
+    class Index(grok.View):
+        pass # see app_templates/index.pt
+
+We will another class which will be available through this application class,
+the new class should inherit ``grok.XMLRPC for this``, and we will write a 
+``say()`` method. It will return "Hello World!". So, the changed file::
+
+    import grok
+
+    class Foo(grok.Application, grok.Container):
+        pass
+
+    class Index(grok.View):
+        pass # see app_templates/index.pt
+
+    class FooXMLRPC(grok.XMLRPC):
+        """The methods in this class will be available as XMLRPC methods
+           on 'Foo' applications."""
+
+        def say(self):
+            return 'Hello world!'
+
+The name of the class doesn't matter, so you can give it any name.
+Restart the Zope in the console, and you can connect to it through any xmlrpc
+client. Below is an example (fooclient.py)::
+
+    #!/usr/bin/env python
+    import xmlrpclib
+    
+    s = xmlrpclib.Server('http://localhost:8080/foo')
+    print s.say()
+
+Run this and see !!
+
+Class in a different file
+---------------------------
+
+What if you want to write the class in a different file in the src/foo
+directory and still want to have the methods to be available under Foo
+application. For that you need to tell grok explicitly that the new class to
+associate it to the Foo model by using the grok.context class annotation.
+
+What is a class annotation?
+-----------------------------
+
+A class annotation is a declarative way to tell grok something about a Python
+class. Let's see the example, we write a Boom.py with a Boom class::
+
+    import grok
+    from app import Foo
+
+    class Boom(grok.XMLRPC):
+        grok.context(Foo)
+
+        def dance(self):
+            return "Boom is dancing!!"
+
+Look at the line where it says ``grok.context(Foo)`` this is doing all the
+magic. In the fooclient.py you just need to call ``s.dance()`` instead of 
+``s.say()``.
+
+So, now write your dream system...
+
+

Modified: Sandbox/ulif/grok-adminui-experimental/doc/reference/directives.tex
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/reference/directives.tex	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/reference/directives.tex	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,38 +1,194 @@
 \chapter{Directives}
 
 The \module{grok} module defines a set of directives that allow you to
-configure and register your components. Most directives assume a default, based
-on the environment of a module. (For example, a view will be automatically
-associated with a model if the association can be made unambigously.)
+configure and register your components. Most directives assume a
+default, based on the environment of a module. (For example, a view
+will be automatically associated with a model if the association can
+be made unambigously.)
 
-If no default can be assumed for a value, grok will explicitly tell you what is
-missing and how you can provide a default or explicit assignment for the value
-in question.
+If no default can be assumed for a value, grok will explicitly tell
+you what is missing and how you can provide a default or explicit
+assignment for the value in question.
 
-    \section{\function{grok.AutoFields}}
 
-        \begin{funcdesc}{grok.AutoFields}{*arg}
-        foobar
+    \section{\function{grok.AutoFields} -- deduce schema fields automatically}
+
+        \begin{funcdesc}{grok.AutoFields}{class_or_interface}
+          A class level directive, which can be used inside
+          \class{Form} classes to automatically deduce the form fields
+          from the schema of the context \var{class_or_interface}.
+
+          Different to most other directives,
+          \function{grok.AutoFields} is used more like a function and
+          less like a pure declaration.
+
+          The following example makes use of the
+          \function{grok.AutoFields} directive, in that one field is
+          omitted from the form before rendering:
+
+          \strong{Example:}
+
+          \begin{verbatim}
+import grok
+from zope import interface, schema
+
+class IMammoth(interface.Interface):
+    name = schema.TextLine(title=u"Name")
+    size = schema.TextLine(title=u"Size", default=u"Quite normal")
+
+class Mammoth(grok.Model):
+    interface.implements(IMammoth)
+
+class Edit(grok.EditForm):
+    grok.context(Mammoth)
+
+    form_fields = grok.AutoFields(Mammoth).omit('size')
+          \end{verbatim}
+
+          In this example the \code{size} attribute will not show up
+          in the resulting edit view.
+
+          \begin{seealso}
+            \class{grok.EditForm}, \class{grok.Fields}
+          \end{seealso}
+
         \end{funcdesc}
 
-    \section{\function{grok.adapts}}
+    \section{\function{grok.adapts} -- declare that a class adapts
+      certain objects}
 
-        \begin{funcdesc}{grok.adapts}{*interfaces}
-        foobar
+        \begin{funcdesc}{grok.adapts}{*classes_or_interfaces}
+          A class-level directive to declare that a class adapts
+          objects of the classes or interfaces given in
+          \var{*classes_or_interfaces}.
+
+          This directive accepts several arguments.
+
+          It works much like the \module{zope.component}s
+          \function{adapts()}, but you do not have to make a ZCML
+          entry to register the adapter.
+
+          \strong{Example:}
+
+          \begin{verbatim}
+import grok
+from zope import interface, schema
+from zope.size.interfaces import ISized
+
+class IMammoth(interface.Interface):
+    name = schema.TextLine(title=u"Name")
+    size = schema.TextLine(title=u"Size", default=u"Quite normal")
+
+class Mammoth(grok.Model):
+    interface.implements(IMammoth)
+
+class MammothSize(object):
+    grok.implements(ISized)
+    grok.adapts(IMammoth)
+
+    def __init__(self, context):
+        self.context = context
+
+    def sizeForSorting(self):
+        return ('byte', 1000)
+
+    def sizeForDisplay(self):
+        return ('1000 bytes')
+          \end{verbatim}
+
+          Having \class{MammothSize} available, you can register it as
+          an adapter, without a single line of ZCML:
+
+          \begin{verbatim}
+>>> manfred = Mammoth()
+>>> from zope.component import provideAdapter
+>>> provideAdapter(MammothSize)
+>>> from zope.size.interfaces import ISized
+>>> size = ISized(manfred)
+>>> size.sizeForDisplay()
+'1000 bytes'
+          \end{verbatim}
+
+          \begin{seealso}
+            \class{grok.implements}
+          \end{seealso}
+
         \end{funcdesc}
 
-    \section{\function{grok.baseclass}}
+    \section{\function{grok.baseclass} -- declare a class as base}
 
-        \begin{funcdesc}{grok.baseclass}{*interfaces}
-        foobar
+        \begin{funcdesc}{grok.baseclass}{}
+          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 \code{'Base'}.
+
+          The baseclass mark is not inherited by subclasses, so those
+          subclasses will be grokked (except they are explicitly
+          declared as baseclasses as well).
+
+          \strong{Example:}
+
+          \begin{verbatim}
+import grok
+
+class ModelBase(grok.Model):
+    pass
+
+class ViewBase(grok.View):
+    def render(self):
+        return "hello world"
+
+class AnotherView(grok.View):
+    grok.baseclass()
+
+    def render(self):
+        return "hello world"
+
+class WorkingView(grok.View):
+    pass
+          \end{verbatim}
+
+          Using this example, only the \class{WorkingView} will serve
+          as a view, while calling the \class{ViewBase} or
+          \class{AnotherView} will lead to a
+          \exception{ComponentLookupError}.
+
+
         \end{funcdesc}
 
-    \section{\function{grok.define_permission}}
+    \section{\function{grok.define_permission} -- define a permission}
 
-        \begin{funcdesc}{grok.define_permission}{*arg}
-        foobar
+        \begin{funcdesc}{grok.define_permission}{name}
+
+          A module-level directive to define a permission with name
+          \var{name}. Usually permission names are prefixed by a
+          component- or application name and a dot to keep them
+          unique.
+
+          Because in Grok by default everything is accessible by
+          everybody, it is important to define permissions, which
+          restrict access to certain principals or roles.
+
+          \strong{Example:}
+
+          \begin{verbatim}
+import grok
+grok.define_permission('cave.enter')
+          \end{verbatim}
+
+          \begin{seealso}
+            \function{grok.require()}, \class{grok.Permission},
+            \class{grok.Role}
+          \end{seealso}
+
+          \versionchanged[replaced by \class{grok.Permission}]{0.11}
+          
         \end{funcdesc}
 
+
+
     \section{\function{grok.Fields}}
 
         \begin{funcdesc}{grok.Fields}{*arg}

Modified: Sandbox/ulif/grok-adminui-experimental/doc/reference/reference.tex
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/doc/reference/reference.tex	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/doc/reference/reference.tex	2007-08-30 23:53:54 UTC (rev 79388)
@@ -15,7 +15,7 @@
 % the rest is at your discretion.
 \authoraddress{
     The grok team\\
-    Email: <grok-dev at zope.org>
+    Email: $<$grok-dev at zope.org$>$
 }
 
 \date{\today}   % update before release!

Modified: Sandbox/ulif/grok-adminui-experimental/grokwiki/src/grokwiki/wiki.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/grokwiki/src/grokwiki/wiki.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/grokwiki/src/grokwiki/wiki.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -18,7 +18,7 @@
 import grokwiki.page
 
 class Wiki(grok.Application, grok.Container):
-    """This is our wiki application wich contains all wiki pages."""
+    """This is Grok's sample wiki application."""
 
 class Index(grok.View):
     def render(self):

Deleted: Sandbox/ulif/grok-adminui-experimental/setup.cfg
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/setup.cfg	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/setup.cfg	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,3 +0,0 @@
-[egg_info]
-tag_build = dev
-tag_svn_revision = true

Modified: Sandbox/ulif/grok-adminui-experimental/setup.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/setup.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/setup.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,16 +1,37 @@
 from setuptools import setup, find_packages
+import os
 
+# some of the dependencies containing C code have been hardcoded to
+# make sure we only depend on versions for which there is a windows
+# binary. In some cases this means we rely on an earlier version than the
+# latest/greatest version as no Windows binary has been released for it yet.
+# in some cases we also need to do this for non-binary dependencies, as
+# more recent versions rely on versions for which no binary eggs exist.
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+long_description = (
+    read('README.txt')
+    + '\n' +
+    read('CHANGES.txt')
+    + '\n' +
+    'Download\n'
+    '********\n'
+    )
+
+open('doc.txt', 'w').write(long_description)
+
 setup(
     name='grok',
-    version='0.9',
+    version='0.10',
     author='Grok Team',
     author_email='grok-dev at zope.org',
-    url='https://launchpad.net/grok',
-    download_url='svn://svn.zope.org/repos/main/grok/trunk#egg=grok-dev',
+    url='http://grok.zope.org',
+    download_url='http://cheeseshop.python.org/pypi/grok/',
     description='Grok: Now even cavemen can use Zope 3!',
-    long_description=open('README.txt').read(),
+    long_description=long_description,
     license='ZPL',
-
     packages=find_packages('src'),
     package_dir = {'': 'src'},
     include_package_data = True,
@@ -19,7 +40,7 @@
                       'martian',
                       'simplejson',
                       'pytz',
-                      'ZODB3',
+                      'ZODB3 == 3.8.0b2',
                       'zope.annotation',
                       'zope.app.apidoc',
                       'zope.app.applicationcontrol',
@@ -27,9 +48,11 @@
                       'zope.app.authentication',
                       'zope.app.catalog',
                       'zope.app.component',
-                      'zope.app.container',
+                      'zope.app.container == 3.5.0.a1',
                       'zope.app.folder',
                       'zope.app.intid',
+                      # not binary, but needed for ZODB 3.8.0b2
+                      'zope.app.keyreference == 3.4.0a1',
                       'zope.app.pagetemplate',
                       'zope.app.publication',
                       'zope.app.publisher',
@@ -45,17 +68,19 @@
                       'zope.deprecation',
                       'zope.event',
                       'zope.formlib',
-                      'zope.interface',
+                      'zope.hookable',
+                      'zope.i18nmessageid',
+                      'zope.interface == 3.4.0',
                       'zope.lifecycleevent',
                       'zope.pagetemplate',
-                      'zope.proxy',
+                      'zope.proxy == 3.4.0',
                       'zope.publisher',
                       'zope.schema',
-                      'zope.security',
+                      'zope.security == 3.4.0b5',
                       'zope.testing',
                       'zope.traversing',
                       'zope.testbrowser',
                       'zc.catalog',
-                      'z3c.flashmessage >=1.0dev-r77761',
+                      'z3c.flashmessage >=1.0b1',
                       ],
 )

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/__init__.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/__init__.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/__init__.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -35,9 +35,10 @@
 from grok.components import Site, GlobalUtility, LocalUtility, Annotation
 from grok.components import Application, Form, AddForm, EditForm, DisplayForm
 from grok.components import Indexes
-from grok.directive import (context, name, template, templatedir, provides,
-                            baseclass, global_utility, local_utility,
-                            define_permission, require, site)
+from grok.components import Permission, Role
+from grok.directive import (context, name, title, template, templatedir,
+                            provides, baseclass, global_utility, local_utility,
+                            permissions, require, site)
 from grok._grok import do_grok as grok  # Avoid name clash within _grok
 from grok._grok import grok_component
 from grok._grok import SubscribeDecorator as subscribe

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/_grok.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/_grok.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/_grok.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -82,7 +82,6 @@
 
 def grok_component(name, component,
                    context=None, module_info=None, templates=None):
-    #import pdb; pdb.set_trace()
     return the_multi_grokker.grok(name, component,
                                   context=context,
                                   module_info=module_info,

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/README.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/README.txt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/README.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,67 +3,110 @@
 =====================
 
 The internal name of the admin UI is:
-Grok Application Interface Application or, for short gaia.
+Grok Application Interface Application or, for short GAIA.
 
-Overview
---------
+GAIA is itself a Grok application and a subproject to the core Grok
+development. Its main goal is making developing of Zope 3 and Grok
+applications a faster and smarter job with more fun for everybody.
 
-* List of all instanciated applications (grouped by application?)
 
-* "Add new application" form: drop down for selecting the application
-   and a field for the id.
+Login - what is my username/password?
+-------------------------------------
 
-* "Delete application" form: checkboxes displayed with listed installed
-  applications. Selected items may be deleted.
+Before you can use the admin UI, you first must log in.
 
+The username and password of the manager principal (kind of super
+user) can be found in the file ``buildout.cfg`` in the root of your
+subversion checkout. 
 
-TODO:
------
+In case you do not know, what 'subversion checkout' means, look for a
+file ``site.zcml`` in your installation.
 
-Layout/Design/Templates:
-........................
+Users of ``grokproject``, might find this file in
+``<installdir>/parts/app/site.zcml``.
 
-* Get rid of garbage in docgrok-views
 
-* Get a new layout
+Using the admin-UI
+------------------
 
-* Rename topics:
+After login you can visit some of the main management topics, as
+described below:
 
-  - z3index -> server
+On top of the admin-UI you can always find three links to the main
+management activities currently possible with GAIA:
 
-  - appsindex -> applications
 
-* AJAXification using some framework (MojiKit or KSS most probably)
+Applications
+------------
 
+* List of all instanciated applications
 
-Functional:
-...........
+* You can add new instances of Grok applications
 
-* Debugging
+* For each installed application you can directly call:
 
-  - Debugger
+  - the object browser (telling you more about this concrete object)
 
-  - Error Logs, usable for developers
+  - the class browser (telling you more about the class of your app)
 
-* Profiling
+* For each available application type you can directly call:
 
-* Object browser / Introspection tool
+  - the class browser (telling you more about the class of your app)
 
-  - Give information concerning installed apps, their containers
-    and contained objects.
+* You can delete your installed applications.
 
-* Better application handling
 
-  - Configure apps.
+Server
+------
 
-* Display hints for where to find username / password for new users
+* Start/Restart the server. Caution! This does not work, if the server
+  was started in 'foreground mode' (with 'zopectl fg').
 
-* Login/Logout(?)
+* Get basic information about the running Zope system.
 
-* Display username(?)
+* Enter a message to be displayed on top. You can, for example, leave
+  a message here for your co-admins. To delete the message, just enter
+  the empty string in the appropriate input box.
 
-* Error Messages:
 
-  - Give message, when input errors (no appname given etc.) occur
+Documentation
+-------------
 
-  - Customizable error pages(?)
+* From here you get starting points to the more elaborated
+  documentation features of Grok, namely:
+
+  - The object browser:
+
+    helps browsing the ZODB and other objects.
+
+  - The class browser:
+
+    gives documentation to classes, packages and other things, which
+    are not instances.
+
+
+Bugs, Caveats and Ways to Get Help
+----------------------------------
+
+The Grok admin UI was developed basically during a Google Summer of
+Code project.
+
+It is still full of bugs.
+
+For bugreports use:
+
+    https://launchpad.net/grok
+
+For discussions subscribe to the ``grok-dev`` mailing list, hosted on:
+
+    http://lists.zope.org.
+
+The projects' home is the grok subversion repository at:
+
+    http://svn.zope.org/grok/
+
+Grok's cave can be found at
+
+    http://grok.zope.org/
+
+Enjoy!

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/__init__.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/__init__.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/__init__.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,131 +1,14 @@
-"""Initialize grok admin application.
-
-The grok admin application provides a session based login, which
-eventually must be enabled using Pluggable Authentication
-Utilities. This is done here.
-"""
-
-from zope.component import adapter, provideHandler
-from zope.app.appsetup.interfaces import IDatabaseOpenedWithRootEvent
-
-
-def getPrincipalCredentialsFromZCML():
-    """Read all principals' attributes from site.zcml.
-    """
-    import xml.sax
-    from zope.app.appsetup.appsetup import getConfigSource
-
-    class SAXPrincipalFinder(xml.sax.ContentHandler):
-        """Parse an XML file and get attributes of ``principal`` tags.
-
-        The principal tags of site.xml contain the credentials of
-        principals as attributes. The attributes usually are 'id',
-        'login', 'password', 'title' and other more. And usually only
-        one pricipal is defined: the manager.
-        """
-        result = []
-
-        def startElement(self, name, attrs):
-            if name != 'principal':
-                return
-            self.result.append(dict(attrs.copy()))
-
-    site_zcml_file = getConfigSource()
-    principal_finder = SAXPrincipalFinder()
-    xml.sax.parse(site_zcml_file, principal_finder)
-    return principal_finder.result
-
-
-def setupSessionAuthentication(root_folder=None,
-                               principal_credentials=[{u'id': u'zope.manager',
-                                                      u'login': u'grok',
-                                                      u'password': u'grok',
-                                                      u'title': u'Manager'
-                                                      }],
-                               auth_foldername=u'authentication',
-                               userfolder_name=u'Users',
-                               userfolder_prefix=u'grokadmin'
-                               ):
-    """Add session authentication PAU to root_folder.
-
-    Add a PluggableAuthentication in site manager of
-    root_folder. ``auth_foldername`` gives the name of the PAU to
-    install, userfolder_prefix the prefix of the authenticator plugin
-    (a simple ``PrincipalFolder``), which will be created in the PAU
-    and gets name ``userfolder_name``. ``principal_credentials`` is a
-    list of dicts with, well, principal_credentials. The keys ``id``,
-    ``login``, ``password`` and ``title`` are required for each
-    element of this list.
-    """
-    from zope.component import getUtilitiesFor
-    from zope.security.proxy import removeSecurityProxy
-    from zope.app.security.interfaces import IAuthentication
-    from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
-    from zope.app.securitypolicy.interfaces import IRole
-    from zope.app.authentication import PluggableAuthentication
-    from zope.app.authentication.interfaces import IAuthenticatorPlugin
-    from zope.app.authentication.principalfolder import PrincipalFolder
-    from zope.app.authentication.principalfolder import InternalPrincipal
-
-    sm = root_folder.getSiteManager()
-    if auth_foldername in sm.keys():
-        # There is already a folder of this name.
-        return
-
-    pau = PluggableAuthentication()
-    users = PrincipalFolder(userfolder_prefix)
-
-    # Add users into principals folder to enable login...
-    for user in principal_credentials:
-        # XXX make sure, the keys exist...
-        user['id'] = user['id'].rsplit('.',1)[-1]
-        user_title = user['title']
-        principal = InternalPrincipal(user['login'],
-                                      user['password'],
-                                      user['title'])
-        users[user['id']] = principal
-
-    # Configure the PAU...
-    pau.authenticatorPlugins = (userfolder_name,)
-    pau.credentialsPlugins = ("No Challenge if Authenticated",
-                              "Session Credentials")
-
-    # Add the pau and its plugin to the root_folder...
-    sm[auth_foldername] = pau
-    sm[auth_foldername][userfolder_name] = users
-    pau.authenticatorPlugins = (users.__name__,)
-
-    # Register the PAU with the site...
-    sm.registerUtility(pau, IAuthentication)
-    sm.registerUtility(users, IAuthenticatorPlugin, name=userfolder_name)
-
-    # Add manager roles to new users...
-    # XXX the real roles could be obtained from site.zcml.
-    role_ids = [name for name, util in getUtilitiesFor(IRole, root_folder)]
-    user_ids = [users.prefix + p['id'] for p in principal_credentials]
-    role_manager = IPrincipalRoleManager(root_folder)
-    role_manager = removeSecurityProxy(role_manager)
-    for role in role_ids:
-        for user_id in user_ids:
-            role_manager.assignRoleToPrincipal(role,user_id)
-
-
-
-# If a new database is created, initialize a session based
-# authentication.
+##############################################################################
 #
-# First create an eventhandler `adminSetup`, that is
-# called, whenever a database is opened...
- at adapter(IDatabaseOpenedWithRootEvent)
-def adminSetup(event):
-    from zope.app.appsetup.bootstrap import getInformationFromEvent
-    
-    db, connection, root, root_folder = getInformationFromEvent(event)
-    principal_credentials = getPrincipalCredentialsFromZCML()
-    setupSessionAuthentication(root_folder = root_folder,
-                               principal_credentials = principal_credentials)
-
-
-# ...then install the event handler:
-provideHandler(adminSetup)
-
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+# a package

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -55,8 +55,11 @@
 DOCGROK_ITEM_NAMESPACE = 'docgrok-obj'
 
 grok.context(IRootFolder)
-grok.define_permission('grok.ManageApplications')
 
+class ManageApplications(grok.Permission):
+    grok.name('grok.ManageApplications')
+
+
 def find_filepath(dotted_path):
     """Find the filepath for a dotted name.
 
@@ -661,4 +664,3 @@
         content = file.read()
         file.close()
         return content.decode('utf-8')
-

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.txt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/docgrok.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -77,7 +77,7 @@
 `DocGrokPackage` :
 
     >>> from grok.admin.docgrok import DocGrokPackage
-    >>> doctor = DocGrokPackage('grok.admin')
+    >>> doctor = DocGrokPackage('grok')
     >>> doctor
     <grok.admin.docgrok.DocGrokPackage ...>
 
@@ -85,7 +85,7 @@
 cares for:
 
     >>> doctor.getPath()
-    'grok.admin'
+    'grok'
 
 Fine. Obviously DocGrokPackages know as much as DocGroks. That's
 little. But a ``DocGrokPackage`` knows also about package-things:
@@ -201,7 +201,7 @@
 class. But, where can we find the definition of it in file system? Ask
 the doc:
 
-    >>> doctor.getFilePath()
+    >>> pnorm(doctor.getFilePath())
     '.../grok/__init__.py'
 
 This is not exactly, what we wanted to know, is it? We got the package
@@ -214,7 +214,7 @@
 To check it, let's see, what happens, if we give the real dotted path:
 
     >>> doctor = DocGrokGrokView('grok.components.View')
-    >>> doctor.getFilePath()
+    >>> pnorm(doctor.getFilePath())
     '.../grok/components.py'
 
 Ah, right. This is, what we wanted. Now we can use some of the derived

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/objectinfo.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/objectinfo.txt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/objectinfo.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -141,7 +141,7 @@
 
   >>> filename = ObjectInfo(grok.admin.objectinfo.ObjectInfo).getfile()
   >>> filename = filename[-1] == 'c' and filename or filename + 'c'
-  >>> filename
+  >>> pnorm(filename)
   '.../grok/admin/objectinfo.pyc'
 
 
@@ -154,7 +154,7 @@
   >>> info.getsourcefile() is None
   True
 
-  >>> ObjectInfo(grok.admin.objectinfo.ObjectInfo).getsourcefile()
+  >>> pnorm(ObjectInfo(grok.admin.objectinfo.ObjectInfo).getsourcefile())
   '.../grok/admin/objectinfo.py'
 
   >>> info.getsourcelines() is None

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/GROK_Logo.jpg
===================================================================
(Binary files differ)

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok-relax.jpg
===================================================================
(Binary files differ)

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok-relax5.png
===================================================================
(Binary files differ)

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok.css
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok.css	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/static/grok.css	2007-08-30 23:53:54 UTC (rev 79388)
@@ -204,6 +204,10 @@
 margin-left:1.5em;
 }
 
+.menu-label1 { 
+width: 40em;
+}
+
 /* ---- docgrok related ---- */
 .docgrok-entry {
 margin-bottom:0.5em;

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/tests/test_grokadmin.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/tests/test_grokadmin.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/tests/test_grokadmin.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -11,8 +11,9 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Test setup for grok admin UI."""
+"""Setup for tests."""
 
+import os
 import unittest
 from pkg_resources import resource_listdir
 from zope.testing import doctest, cleanup
@@ -47,13 +48,22 @@
         suite.addTest(test)
     return suite
 
+def pnorm(path):
+    """Normalization of paths to use forward slashes. This is needed
+    to make sure the tests work on windows.
+    """
+    return path.replace(os.sep, '/')
+
 def test_suite():
     suite = unittest.TestSuite()
+    globs = {'pnorm': pnorm}
+
     for name in []:
         suite.addTest(suiteFromPackage(name))
     for name in ['docgrok.txt','objectinfo.txt', 'utilities.py']:
         suite.addTest(doctest.DocFileSuite(name,
                                            package='grok.admin',
+                                           globs=globs,
                                            setUp=setUpZope,
                                            tearDown=cleanUpZope,
                                            optionflags=doctest.ELLIPSIS+

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -32,7 +32,6 @@
 
 import zope.component
 from zope.interface import Interface
-from zope.app import zapi
 from zope.interface.interface import InterfaceClass
 from zope.app.applicationcontrol.interfaces import IServerControl
 from zope.app.applicationcontrol.applicationcontrol import applicationController
@@ -56,8 +55,10 @@
 
 
 grok.context(IRootFolder)
-grok.define_permission('grok.ManageApplications')
 
+class ManageApplications(grok.Permission):
+    grok.name('grok.ManageApplications')
+
 class Add(grok.View):
     """Add an application.
     """
@@ -66,14 +67,16 @@
 
     def update(self, inspectapp=None, application=None):
         if inspectapp is not None:
-            self.redirect(self.url("docgrok") + "/%s/index"%(
-                application.replace('.','/'),))
-        return 
+            self.redirect(self.url("docgrok") + "/%s/index"%(application.replace('.','/'),))
+        return
 
-    def render(self, application, name):
+    def render(self, application, name, inspectapp=None):
         if name is None or name == "":
             self.redirect(self.url(self.context))
             return
+        if name is None or name == "":
+            self.redirect(self.url(self.context))
+            return
         app = zope.component.getUtility(grok.interfaces.IApplication,
                                         name=application)
         try:
@@ -307,44 +310,9 @@
         self.redirect(self.url('applications'))
 
 
-class LoginForm(GAIAView):
-    """A login screen for session based authentication.
-
-    To activate loginForm, i.e. session based authentication, an
-    appropriate PluggableAuthenticationUtility (PAU) must be set up in
-    the applications root folder (which happens here to be the global
-    root folder). The setup is done for the admin app in __init__.py.
-    """
-    # 'loginForm.html' is the page template name, that standard
-    # session based authentication looks for. The form must provide an
-    # input field 'login' for the username and another input field
-    # 'password'.
-    grok.name('loginForm.html')
-
-    def update(self, login=None, password=None, camefrom=None):
-        request = self.request
-        if (not IUnauthenticatedPrincipal.providedBy(request.principal)):
-            camefrom = request.get('camefrom', '.')
-            self.redirect(camefrom)
-        return
-
-class Logout(GAIAView):
-    """Log out screen."""
-
-    grok.name('logout')
-
-    def update(self):
-        auth = zope.component.getUtility(IAuthentication)
-        logout = ILogout(auth)
-        logout.logout(self.request)
-        pass
-
-
-
 class Applications(GAIAView):
     """View for application management.
 
-    TODO: Handle broken objects, which are not in root.
     """
 
     grok.name('applications')
@@ -415,7 +383,7 @@
 
     @property
     def server_control(self):
-        return zapi.getUtility(IServerControl)
+        return zope.component.getUtility(IServerControl)
 
     @property
     def runtime_info(self):

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokclassview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokclassview.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokclassview.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -27,20 +27,12 @@
 	  <span class="docgrok-description1">Python path:</span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/path">path.in.python</span>
-	  <div class="docgrok-annotation2">
-	    Use <span class="docgrok-pycode1">from <span tal:replace="context/module_path">path</span> 
-	    import <span tal:replace="context/name">path</span></span>
-	    to use the functionality of this module in your application or component.
-	  </div>
 	</div>
 
 	<div class="docgrok-entry">
 	  <span class="docgrok-description1">Absolute file path: </span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/getFilePath">/absolute/file/path</span>
-	  <div class="docgrok-annotation2">
-	    This is the file, wherein this class is defined.
-	  </div>
 	</div>
 
       </div>
@@ -70,14 +62,6 @@
 	       tal:condition="item/doc"
 	       tal:content="structure item/doc">
 	  </div>
-	  <div class="docgrok-annotation2"
-	       tal:condition="not: item/doc">
-	    Use <span class="docgrok-pycode1">from <span
-	    tal:replace="item/path">x</span> import <span
-	    tal:replace="item/name">y</span></span> to make the
-	    functionality of this class available in your application
-	    or component.
-	  </div>
 	</div>
 
 	<h2>Interfaces</h2>
@@ -108,14 +92,6 @@
 	       tal:condition="item/doc"
 	       tal:content="structure item/doc">
 	  </div>
-	  <div class="docgrok-annotation2"
-	       tal:condition="not: item/doc">
-	    Use <span class="docgrok-pycode1">from <span
-	    tal:replace="item/path">x</span> import <span
-	    tal:replace="item/name">y</span></span> to make the
-	    functionality of this class available in your application
-	    or component.
-	  </div>
 	</div>
 
 
@@ -158,14 +134,6 @@
 		   tal:condition="iface/doc"
 		   tal:content="structure iface/doc">
 	      </div>
-	      <div class="docgrok-annotation2"
-		   tal:condition="not: iface/doc">
-		Use <span class="docgrok-pycode1">from <span
-		tal:replace="iface/path">x</span> import <span
-		tal:replace="iface/name">y</span></span> to make the
-		functionality of this class available in your application
-		or component.
-	      </div>
 	    </div>
 	    
 	  </div>
@@ -202,14 +170,6 @@
 		 tal:condition="item/doc"
 		 tal:content="structure item/doc">
 	    </div>
-	    <div class="docgrok-annotation2"
-		 tal:condition="not: item/doc">
-	      Use <span class="docgrok-pycode1">from <span
-	      tal:replace="context/path">x</span> import <span
-	      tal:replace="item/name">y</span></span> to make the
-	      functionality of this function available in your application
-	      or component.
-	    </div>
 	  </div>
 	</div>
 
@@ -248,14 +208,6 @@
 		   tal:condition="iface/doc"
 		   tal:content="structure iface/doc">
 	      </div>
-	      <div class="docgrok-annotation2"
-		   tal:condition="not: iface/doc">
-		Use <span class="docgrok-pycode1">from <span
-		tal:replace="iface/path">x</span> import <span
-		tal:replace="iface/name">y</span></span> to make the
-		functionality of this class available in your application
-		or component.
-	      </div>
 	    </div>
 	    
 	  </div>

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokgrokapplicationview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokgrokapplicationview.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokgrokapplicationview.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -27,20 +27,12 @@
 	  <span class="docgrok-description1">Python path:</span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/path">path.in.python</span>
-	  <div class="docgrok-annotation2">
-	    Use <span class="docgrok-pycode1">from <span tal:replace="context/module_path">path</span> 
-	    import <span tal:replace="context/name">path</span></span>
-	    to use the functionality of this module in your application or component.
-	  </div>
 	</div>
 
 	<div class="docgrok-entry">
 	  <span class="docgrok-description1">Absolute file path: </span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/getFilePath">/absolute/file/path</span>
-	  <div class="docgrok-annotation2">
-	    This is the file, wherein this class is defined.
-	  </div>
 	</div>
 
       </div>
@@ -70,14 +62,6 @@
 	       tal:condition="item/doc"
 	       tal:content="structure item/doc">
 	  </div>
-	  <div class="docgrok-annotation2"
-	       tal:condition="not: item/doc">
-	    Use <span class="docgrok-pycode1">from <span
-	    tal:replace="item/path">x</span> import <span
-	    tal:replace="item/name">y</span></span> to make the
-	    functionality of this class available in your application
-	    or component.
-	  </div>
 	</div>
 
 	<h2>Interfaces</h2>
@@ -104,14 +88,6 @@
 	       tal:condition="item/doc"
 	       tal:content="structure item/doc">
 	  </div>
-	  <div class="docgrok-annotation2"
-	       tal:condition="not: item/doc">
-	    Use <span class="docgrok-pycode1">from <span
-	    tal:replace="item/path">x</span> import <span
-	    tal:replace="item/name">y</span></span> to make the
-	    functionality of this class available in your application
-	    or component.
-	  </div>
 	</div>
 
 
@@ -156,14 +132,6 @@
 		   tal:condition="iface/doc"
 		   tal:content="structure iface/doc">
 	      </div>
-	      <div class="docgrok-annotation2"
-		   tal:condition="not: iface/doc">
-		Use <span class="docgrok-pycode1">from <span
-		tal:replace="iface/path">x</span> import <span
-		tal:replace="iface/name">y</span></span> to make the
-		functionality of this class available in your application
-		or component.
-	      </div>
 	    </div>
 	    
 	  </div>
@@ -201,14 +169,6 @@
 		 tal:condition="item/doc"
 		 tal:content="structure item/doc">
 	    </div>
-	    <div class="docgrok-annotation2"
-		 tal:condition="not: item/doc">
-	      Use <span class="docgrok-pycode1">from <span
-	      tal:replace="context/path">x</span> import <span
-	      tal:replace="item/name">y</span></span> to make the
-	      functionality of this function available in your application
-	      or component.
-	    </div>
 	  </div>
 	</div>
 
@@ -247,14 +207,6 @@
 		   tal:condition="iface/doc"
 		   tal:content="structure iface/doc">
 	      </div>
-	      <div class="docgrok-annotation2"
-		   tal:condition="not: iface/doc">
-		Use <span class="docgrok-pycode1">from <span
-		tal:replace="iface/path">x</span> import <span
-		tal:replace="iface/name">y</span></span> to make the
-		functionality of this class available in your application
-		or component.
-	      </div>
 	    </div>
 	    
 	  </div>

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokinterfaceview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokinterfaceview.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokinterfaceview.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -27,20 +27,12 @@
 	  <span class="docgrok-description1">Python path:</span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/path">path.in.python</span>
-	  <div class="docgrok-annotation2">
-	    Use <span class="docgrok-pycode1">from <span tal:replace="context/module_path">path</span> 
-	    import <span tal:replace="context/name">path</span></span>
-	    to use the functionality of this module in your application or component.
-	  </div>
 	</div>
 
 	<div class="docgrok-entry">
 	  <span class="docgrok-description1">Absolute file path: </span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/getFilePath">/absolute/file/path</span>
-	  <div class="docgrok-annotation2">
-	    This is the file, wherein this class is defined.
-	  </div>
 	</div>
 
       </div>
@@ -70,14 +62,6 @@
 	       tal:condition="item/doc"
 	       tal:content="structure item/doc">
 	  </div>
-	  <div class="docgrok-annotation2"
-	       tal:condition="not: item/doc">
-	    Use <span class="docgrok-pycode1">from <span
-	    tal:replace="item/path">x</span> import <span
-	    tal:replace="item/name">y</span></span> to make the
-	    functionality of this class available in your application
-	    or component.
-	  </div>
 	</div>
 
 
@@ -120,14 +104,6 @@
 		   tal:condition="iface/doc"
 		   tal:content="structure iface/doc">
 	      </div>
-	      <div class="docgrok-annotation2"
-		   tal:condition="not: iface/doc">
-		Use <span class="docgrok-pycode1">from <span
-		tal:replace="iface/path">x</span> import <span
-		tal:replace="iface/name">y</span></span> to make the
-		functionality of this class available in your application
-		or component.
-	      </div>
 	    </div>
 	    
 	  </div>
@@ -165,14 +141,6 @@
 		 tal:condition="item/doc"
 		 tal:content="structure item/doc">
 	    </div>
-	    <div class="docgrok-annotation2"
-		 tal:condition="not: item/doc">
-	      Use <span class="docgrok-pycode1">from <span
-	      tal:replace="context/path">x</span> import <span
-	      tal:replace="item/name">y</span></span> to make the
-	      functionality of this function available in your application
-	      or component.
-	    </div>
 	  </div>
 	</div>
 
@@ -211,14 +179,6 @@
 		   tal:condition="iface/doc"
 		   tal:content="structure iface/doc">
 	      </div>
-	      <div class="docgrok-annotation2"
-		   tal:condition="not: iface/doc">
-		Use <span class="docgrok-pycode1">from <span
-		tal:replace="iface/path">x</span> import <span
-		tal:replace="iface/name">y</span></span> to make the
-		functionality of this class available in your application
-		or component.
-	      </div>
 	    </div>
 	    
 	  </div>

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokmoduleview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokmoduleview.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokmoduleview.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -22,20 +22,12 @@
 	  <span class="docgrok-description1">Python path:</span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/path">path.in.python</span>
-	  <div class="docgrok-annotation2">
-	    Use <span class="docgrok-pycode1">import 
-	    <span tal:replace="context/path">path</span></span>
-	    to use the functionality of this module in your application or component.
-	  </div>
 	</div>
 
 	<div class="docgrok-entry">
 	  <span class="docgrok-description1">Absolute file path: </span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/getFilePath">/absolute/file/path</span>
-	  <div class="docgrok-annotation2">
-	    This is the file, where this module is located in file system.
-	  </div>
 	</div>
 
       </div>
@@ -57,14 +49,6 @@
 		 tal:condition="item/doc"
 		 tal:content="structure item/doc">
 	    </div>
-	    <div class="docgrok-annotation2"
-		 tal:condition="not: item/doc">
-	      Use <span class="docgrok-pycode1">from <span
-	      tal:replace="context/path">x</span> import <span
-	      tal:replace="item/name">y</span></span> to make the
-	      functionality of this class available in your application
-	      or component.
-	    </div>
 	  </div>
 	</div>
 
@@ -84,14 +68,6 @@
 		 tal:condition="item/doc"
 		 tal:content="structure item/doc">
 	    </div>
-	    <div class="docgrok-annotation2"
-		 tal:condition="not: item/doc">
-	      Use <span class="docgrok-pycode1">from <span
-	      tal:replace="context/path">x</span> import <span
-	      tal:replace="item/name">y</span></span> to make this
-	      interface definition available in your application
-	      or component.
-	    </div>
 	  </div>
 	</div>
 
@@ -111,14 +87,6 @@
 		 tal:condition="item/doc"
 		 tal:content="structure item/doc">
 	    </div>
-	    <div class="docgrok-annotation2"
-		 tal:condition="not: item/doc">
-	      Use <span class="docgrok-pycode1">from <span
-	      tal:replace="context/path">x</span> import <span
-	      tal:replace="item/name">y</span></span> to make the
-	      functionality of this class available in your application
-	      or component.
-	    </div>
 	  </div>
 	</div>
 

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokpackageview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokpackageview.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgrokpackageview.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -21,20 +21,12 @@
 	  <span class="docgrok-description1">Python path:</span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/path">path.in.python</span>
-	  <div class="docgrok-annotation2">
-	    Use <span class="docgrok-pycode1">import 
-	    <span tal:replace="context/path">path</span></span>
-	    to use the functionality of this package in your application or component.
-	  </div>
 	</div>
 
 	<div class="docgrok-entry">
 	  <span class="docgrok-description1">Absolute file path: </span>
 	  <span class="docgrok-pathvalue" 
 		tal:content="context/getFilePath">absolute/file/path</span>
-	  <div class="docgrok-annotation2">
-	    This is, where this package is located in file system.
-	  </div>
 	</div>
 
 	<h2>Textfiles:</h2>
@@ -76,14 +68,6 @@
 		 tal:condition="item/doc"
 		 tal:content="structure item/doc">
 	    </div>
-	    <div class="docgrok-annotation2"
-		 tal:condition="not: item/doc">
-	      You can use <span class="docgrok-pycode1">import <span
-	      tal:replace="string: ${context/path}.${item/name}">a.b</span>
-	    </span>
-	    to make the elements of this package available in your 
-	    application or component.
-	    </div>
 	  </div>
 	</div>
 
@@ -103,14 +87,6 @@
 		 tal:condition="item/doc"
 		 tal:content="structure item/doc">
 	    </div>
-	    <div class="docgrok-annotation2"
-		 tal:condition="not: item/doc">
-	      You can use <span class="docgrok-pycode1">import <span
-	      tal:replace="string: ${context/path}.${item/name}">a.b</span>
-	    </span>
-	    to make the elements of this module available in your 
-	    application or component.
-	    </div>
 	  </div>
 	</div>
 

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgroktextfileview.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgroktextfileview.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/docgroktextfileview.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -26,9 +26,6 @@
 		>
 	    /home/uli/blah...
 	  </span>
-	  <div class="docgrok-annotation1">
-	    This is, where this text file can be found.
-	  </div>
 	</div>
       </div>
       <div class="docgrok-sourcetext" 

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/loginform.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/loginform.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/loginform.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,35 +0,0 @@
-<html metal:use-macro="context/@@macros/gaia-page">
-  <head>
-    <title metal:fill-slot="title">Grok Login</title>
-  </head>
-  <body>
-    <div metal:fill-slot="menu-links" />
-    <div metal:fill-slot="content">
-      <h1>Welcome to Grok</h1>
-      <form method="post">
-	<fieldset>
-	  <legend>Login</legend>
-
-	  <table>
-	    <tr>
-	      <td><label for="login">Username:</label></td>
-	      <td><input id="login" type="text" name="login" /></td>
-	    </tr>
-	    <tr>
-	      <td><label for="password">Password:</label></td>
-	      <td><input id="password" type="password" name="password" /></td>
-	    </tr>
-	    <tr>
-	      <td></td>
-	      <td><input type="submit" value="Login"/></td>
-	    </tr>
-	  </table>
-	  <p>
-	    Note: To proceed you must have cookies enabled in your browser
-	  </p>
-
-	</fieldset>
-      </form>
-    </div>
-  </body>
-</html>
\ No newline at end of file

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/logout.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/logout.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/logout.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,8 +0,0 @@
-<html>
-<head>
-  <title>Logged out</title>
-</head>
-<body>
-  You have been logged out.
-</body>
-</html>
\ No newline at end of file

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/macros.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/macros.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/macros.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -26,9 +26,7 @@
 	  <span i18n:translate="">User:
 	  <span tal:replace="request/principal/title"
 		i18n:name="user_title">User</span>
-	  </span>&nbsp;
-	  [<a href=""
-	  tal:attributes="href string:${view/root_url}/logout">log out</a>]
+	  </span>
 	</span>
       </div>
 

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/server.pt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/server.pt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/admin/view_templates/server.pt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -16,7 +16,7 @@
       <fieldset>
         <legend>Admin message</legend>
 
-        <p>Let's you display an administrative message on all pages.<br />
+        <p>Lets you display an administrative message on all pages.<br />
 
         <input
           type="text"
@@ -27,8 +27,8 @@
         <input type="hidden" name="submitted" value="true"/>
         <input type="submit" name="save_message" class="button" value="Save"/>
 
+	</p>
       </fieldset>
-
       <span class="header">Server process info</span>
       <div id="server-processes">
       <dl tal:define="ri view/runtime_info">

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/components.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/components.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/components.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -479,3 +479,9 @@
         self.__grok_module__ = martian.util.caller_module()
 
 Indexes = IndexesClass('Indexes')
+
+class Permission(object):
+    pass
+
+class Role(object):
+    pass

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/directive.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/directive.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/directive.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -17,7 +17,8 @@
 from zope.interface.interfaces import IInterface
 
 from martian.error import GrokImportError
-from martian.directive import (MultipleTimesDirective, BaseTextDirective,
+from martian.directive import (OnceDirective,
+                               MultipleTimesDirective, BaseTextDirective,
                                SingleValue, SingleTextDirective,
                                MultipleTextDirective,
                                MarkerDirective,
@@ -47,7 +48,7 @@
         if provides is None:
             provides = util.class_annotation(factory, 'grok.provides', None)
         self.provides = provides
-        
+
         if name is u'':
             name = util.class_annotation(factory, 'grok.name', u'')
         self.name = name
@@ -93,6 +94,14 @@
             return func
         return decorator
 
+class MultiValueOnceDirective(OnceDirective):
+
+    def check_arguments(self, *values):
+        pass
+
+    def value_factory(self, *args):
+        return args
+
 # Define grok directives
 name = SingleTextDirective('grok.name', ClassDirectiveContext())
 template = SingleTextDirective('grok.template', ClassDirectiveContext())
@@ -105,8 +114,9 @@
                                         ModuleDirectiveContext())
 local_utility = LocalUtilityDirective('grok.local_utility',
                                       ClassDirectiveContext())
-define_permission = MultipleTextDirective('grok.define_permission',
-                                          ModuleDirectiveContext())
 require = RequireDirective('grok.require', ClassDirectiveContext())
 site = InterfaceOrClassDirective('grok.site',
                                  ClassDirectiveContext())
+title = SingleTextDirective('grok.title', ClassDirectiveContext())
+permissions = MultiValueOnceDirective(
+    'grok.permissions', ClassDirectiveContext())

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftesting.zcml
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftesting.zcml	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftesting.zcml	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
 <configure
    xmlns="http://namespaces.zope.org/zope"
+   xmlns:grok="http://namespaces.zope.org/grok"
    i18n_domain="grok"
    package="grok"
    >
 
   <include package="grok" />
+  <grok:grok package="grok.ftests" />
 
   <securityPolicy
       component="zope.app.securitypolicy.zopepolicy.ZopeSecurityPolicy"

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/README.txt
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/README.txt	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/README.txt	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,6 +0,0 @@
-Creating functional tests
--------------------------
-
-Unfortunately, functional doctests do not import themselves (as the
-unit-test ones do), so you need to manually import the module in the
-doctest part.

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/apps.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/apps.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/apps.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -13,9 +13,6 @@
 ##############################################################################
 """
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.admin.apps')
-
   >>> from zope.testbrowser.testing import Browser
   >>> browser = Browser()
   >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
@@ -36,26 +33,21 @@
   >>> print browser.contents
   <html xmlns="http://www.w3.org/1999/xhtml">
   ...
-  ... <p ...>Currently no working applications are...installed.</p>
+  ... <p ...>Currently no working...applications are installed.</p>
   ...
 
 We are able to add a mammoth manager...
 
-  >>> browser.getControl('Name your new app:',index=13).value = 'my-mammoth-manager'
-  >>> browser.getControl('Create',index=13).click()
+  >>> browser.getControl('Name your new app:', index=2).value = 'my-mammoth-manager'
+  >>> browser.getControl('Create', index=2).click()
 
   >>> print browser.contents
   <html xmlns="http://www.w3.org/1999/xhtml">
   ...
-  ... <legend>Installed applications</legend>
-  ... <input type="checkbox" class="checkbox" name="items"
-             value="my-mammoth-manager" />
-      <a href="http://localhost/my-mammoth-manager">
-           my-mammoth-manager
-           (MammothManager)
-        </a>
-  ... <legend>Add application</legend>
+  ...<legend>Installed applications</legend>
   ...
+  ...<a href="http://localhost/my-mammoth-manager">
+  ...
 
 Launch the added mammoth manager
 
@@ -90,7 +82,7 @@
   >>> print browser.contents
   <html xmlns="http://www.w3.org/1999/xhtml">
   ...
-  ... <p ...>Currently no working applications are...installed.</p>
+  ... <p ...>Currently no working applications...are installed.</p>
   ...
   ...<legend>Add application</legend>
   ...

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/brokenobjs.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/brokenobjs.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/brokenobjs.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -27,14 +27,12 @@
 usual:
 
   >>> browser.open('http://localhost/applications')
-  >>> 'broken' not in browser.contents
+  >>> 'Broken applications:' not in browser.contents
   True
 
 Now we grok this module, to have a new application type available,
 which is intentionally broken:
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.admin.brokenobjs')
   >>> browser.open('http://localhost/applications')
   >>> 'PseudoBroken' in browser.contents
   True
@@ -82,6 +80,6 @@
 import grok
 from ZODB.broken import Broken
 class PseudoBroken(grok.Application, grok.Container, Broken):
-    """A class intentianally broken.
+    """A class intentionally broken.
     """
     pass

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/loginlogout.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/loginlogout.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/loginlogout.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,105 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2007 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""
-
-  >>> import grok
-  >>> grok.grok('grok.ftests.admin.loginlogout')
-
-First setup the pluggable authentication system for session based
-authentication. This is normaly invoked by an event
-handler. Unfortunately the event handler seems not to be called, if
-the ftesting setup is set up. We therefore set up the PAU manually.
-
-  >>> root = getRootFolder()
-  >>> root is not None
-  True
-
-  >>> import grok.admin
-  >>> principal_credentials = grok.admin.getPrincipalCredentialsFromZCML()
-  >>> principal_credentials
-  [{u'login': u'mgr', u'password': u'mgrpw', u'id': u'zope.mgr', u'title': u'Manager'}]
-
-  >>> grok.admin.setupSessionAuthentication(root_folder = root, principal_credentials = principal_credentials)
-
-We should get a login page if trying to get something unauthenticated.
-
-  >>> from zope.testbrowser.testing import Browser
-  >>> browser = Browser()
-  >>> browser.handleErrors = True
-  >>> browser.open("http://localhost/")
-
-  >>> print browser.contents
-  <html xmlns="http://www.w3.org/1999/xhtml">
-  ... <title>Grok Login</title>
-  ...
-
-Now try to log in using *wrong* credentials
-
-  >>> browser.getControl(name='login').value = 'dumbtry'
-  >>> browser.getControl('Login').click()
-  >>> print browser.contents
-  <html xmlns="http://www.w3.org/1999/xhtml">
-  ... <title>Grok Login</title>
-  ...
-
-Okay, we got the login screen again. What about the correct credentials?
-
-  >>> browser.getControl(name='login').value = 'mgr'
-  >>> browser.getControl(name='password').value = 'mgrpw'
-  >>> browser.getControl('Login').click()
-  >>> print browser.contents
-  <html xmlns="http://www.w3.org/1999/xhtml">
-  ... <title>grok administration interface</title>
-  ...
-
-The new screen should contain a link for logging out:
-
-  >>> print browser.contents
-  <html xmlns="http://www.w3.org/1999/xhtml">
-  ... <span>User:
-  ...Manager
-  ...[<a href="http://localhost/logout">log out</a>]
-  ...
-  
-Fine. Now we are authorized and can do, whatever we want. Let's log out:
-
-  >>> outlink = browser.getLink('log out')
-  >>> outlink
-  <Link text='log out' url='http://localhost/logout'>
-
-  >>> outlink.click()
-  >>> print browser.contents
-  <html>
-  ... You have been logged out.
-  ...
-
-Looks okay. But are we really logged out? Let's try to fetch a page:
-
-  >>> browser.open("http://localhost/")
-  >>> print browser.contents
-  <html xmlns="http://www.w3.org/1999/xhtml">
-  ... <title>Grok Login</title>
-  ...
-  ... <td><input id="login" type="text" name="login" /></td>
-  ...
-
-Yes, we are.
-
-  ...
-  ...      <legend>Add application</legend>
-  ...
-
-
-"""
-

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/objectbrowser.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/objectbrowser.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/admin/objectbrowser.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -13,9 +13,6 @@
 ##############################################################################
 """
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.admin.objectbrowser')
-
   >>> from zope.testbrowser.testing import Browser
   >>> browser = Browser()
   >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/catalog.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/catalog.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/catalog.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,8 +1,4 @@
 """
-  >>> import grok
-  >>> from grok.ftests.catalog.catalog import Mammoth, Herd
-  >>> grok.grok('grok.ftests.catalog.catalog')
-
 Let's setup a site in which we manage a couple of objects:
 
   >>> herd = Herd()

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,12 +2,8 @@
 Grok allows you to set up catalog indexes in your application with a
 special indexes declaration.
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes import Herd, Herd2, Mammoth
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> from zope.app.component.hooks import setSite

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_app_interface.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_app_interface.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_app_interface.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
 special indexes declaration. Here we see how we can register indexes for
 an interface instead of an application directly.
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_app_interface')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes_app_interface import Herd, Herd2, Mammoth
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> from zope.app.component.hooks import setSite

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_attribute.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_attribute.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_attribute.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,12 +4,8 @@
 from the attribute, you can do so, by passing an explicit `attribute`
 keyword argument to the field.
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_attribute')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes_attribute import Herd, Mammoth
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> from zope.app.component.hooks import setSite

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_class.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_class.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_class.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
 special indexes declaration. This can also be done without explicit interface.
 The context of the indexes applies to a class in this case.
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_class')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes_class import Herd, Mammoth
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> from zope.app.component.hooks import setSite

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_module.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_module.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_module.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,16 +0,0 @@
-"""
-You can create an index on module level, but that should lead to a GrokError:
-
-  >>> import grok
-  >>> from grok.ftests.catalog.indexes_module import func
-  >>> func()
-  Traceback (most recent call last):
-    ...
-  GrokImportError: <class 'grok.index.Field'> can only be instantiated on
-  class level.
-"""
-from grok import index
-
-def func():
-    foo = index.Field()
-    

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
 special indexes declaration. In fact, we have multiple grok.Indexes
 setting up more than one set of indexes in the same catalog.
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_multiple')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes_multiple import Herd
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> from zope.app.component.hooks import setSite

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple_conflict.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple_conflict.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_multiple_conflict.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,12 +4,8 @@
 setting up more than one set of indexes in the same catalog. What if these
 indexes define the same names?
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_multiple_conflict')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes_multiple_conflict import Herd
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   Traceback (most recent call last):

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_name.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_name.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_name.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
 special indexes declaration. We can specify the catalog name using
 grok.name.
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_name')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes_name import Herd, Mammoth
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> from zope.app.component.hooks import setSite

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_no_app.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_no_app.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_no_app.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,30 +0,0 @@
-"""
-Grok allows you to set up catalog indexes in your application with a
-special indexes declaration.  We do need to specify a site (such as
-the application) for the Indexes however, otherwise we get a GrokError:
-
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_no_app')
-  Traceback (most recent call last):
-    ...
-  GrokError: No site specified for grok.Indexes subclass in module
-  <module 'grok.ftests.catalog.indexes_no_app' from ...>.
-  Use grok.site() to specify.
-  
-"""
-import grok
-from grok import index
-
-class Herd(grok.Container, grok.Application):
-    pass
-
-class Mammoth(grok.Model):
-    pass
-
-class MammothIndexes(grok.Indexes):
-    grok.context(Mammoth)
-    grok.name('foo_catalog')
-    
-    name = index.Field()
-    age = index.Field()
-    message = index.Text()

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_nonexistent.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_nonexistent.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_nonexistent.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
 special indexes declaration. Here we show what happens if you try
 to set up an index for an attribute that does not exist on the interface.
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_nonexistent')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes_nonexistent import Herd
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   Traceback (most recent call last):

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_set.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_set.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_set.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,12 +1,8 @@
 """
 We now demonstrate the use of a SetIndex with Grok::
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_set')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes_set import Herd, Mammoth
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> from zope.app.component.hooks import setSite

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_site.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_site.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/indexes_site.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,12 +3,8 @@
 special indexes declaration. In fact, these indexes can be set up for
 any site::
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.catalog.indexes_site')
-
 Let's set up a site in which we manage a couple of objects::
 
-  >>> from grok.ftests.catalog.indexes_site import Herd
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> from zope.app.component.hooks import setSite

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/setuporder.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/setuporder.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/catalog/setuporder.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,10 +2,6 @@
 This is similar to catalog.py, except that the site uses a base class
 which also defines a local utility.
 
-  >>> import grok
-  >>> from grok.ftests.catalog.setuporder import Mammoth, Herd
-  >>> grok.grok('grok.ftests.catalog.setuporder')
-
 Let's setup a site in which we manage a couple of objects:
 
   >>> herd = Herd()

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/actions.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/actions.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/actions.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,9 +4,6 @@
 'Apply' action) is not available anymore, but it can triggered
 manually by calling self.applyData(object, data).
 
-  >>> import grok
-  >>> from grok.ftests.form.actions import Mammoth
-  >>> grok.grok('grok.ftests.form.actions')
   >>> getRootFolder()["manfred"] = Mammoth()
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,9 +1,6 @@
 """
 We can use grok.AddForm to render an add form for objects:
 
-  >>> import grok
-  >>> from grok.ftests.form.addform import Zoo, Mammoth
-  >>> grok.grok('grok.ftests.form.addform')
   >>> getRootFolder()["zoo"] = Zoo()
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_applydata.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_applydata.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_applydata.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,9 +3,6 @@
 object.  The object doesn't yet need to have the attributes that are
 going to be set on it.
 
-  >>> import grok
-  >>> from grok.ftests.form.addform_applydata import Zoo, Mammoth
-  >>> grok.grok('grok.ftests.form.addform_applydata')
   >>> getRootFolder()["zoo"] = Zoo()
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_catalog.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_catalog.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/addform_catalog.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
 Thanks to Zope's event system, newly added objects are automatically
 catalogued, should a catalog be present.
 
-  >>> import grok
-  >>> from grok.ftests.form.addform_catalog import Zoo, Mammoth
-  >>> grok.grok('grok.ftests.form.addform_catalog')
   >>> getRootFolder()["zoo"] = Zoo()
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,9 +3,6 @@
 the object.  Update mode means that only those fields are changed on
 the object that need to be changed.
 
-  >>> import grok
-  >>> from grok.ftests.form.editform_applydata import Mammoth
-  >>> grok.grok('grok.ftests.form.editform_applydata')
   >>> getRootFolder()["manfred"] = Mammoth('Manfred the Mammoth', 'Really big')
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_classfields.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_classfields.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_classfields.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -6,9 +6,6 @@
 This is essentially the same narrative as 'editform_applydata'. Here
 we test the whole procedure on fields defined on the model class:
 
-  >>> import grok
-  >>> from grok.ftests.form.editform_applydata_classfields import Mammoth
-  >>> grok.grok('grok.ftests.form.editform_applydata_classfields')
   >>> getRootFolder()["manfred"] = mammoth = Mammoth()
   >>> mammoth.name = 'Manfred the Mammoth'
   >>> mammoth.size = 'Really big'

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_schema.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_schema.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/editform_applydata_schema.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -6,9 +6,6 @@
 This is essentially the same narrative as 'editform_applydata'. Here
 we test the whole procedure on fields from schemas:
 
-  >>> import grok
-  >>> from grok.ftests.form.editform_applydata_schema import Mammoth
-  >>> grok.grok('grok.ftests.form.editform_applydata_schema')
   >>> getRootFolder()["manfred"] = Mammoth('Manfred the Mammoth', 'Really big')
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/form.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/form.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/form.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,9 +1,6 @@
 """
 A grok.EditForm is a special grok.View that renders an edit form.
 
-  >>> import grok
-  >>> from grok.ftests.form.form import Mammoth
-  >>> grok.grok('grok.ftests.form.form')
   >>> getRootFolder()["manfred"] = Mammoth()
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/templateform.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/templateform.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/templateform.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,10 +2,6 @@
 If a form does not have a template, a simple default template is
 associated with them. Otherwise, the supplied template is used.
 
-  >>> import grok
-  >>> from grok.ftests.form.templateform import Mammoth
-  >>> grok.grok('grok.ftests.form.templateform')
-
   >>> from zope.publisher.browser import TestRequest
   >>> request = TestRequest()
   >>> from zope import component

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/update.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/update.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/form/update.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
 Forms can implement an update() method that will be called before any
 form processing has happened:
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.form.update')
-  >>> from grok.ftests.form.update import Mammoth
   >>> getRootFolder()["manfred"] = Mammoth()
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/grant.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/grant.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/grant.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,12 +1,8 @@
 # -*- coding: latin-1 -*-
 """
-We can define a few permissions with grok.define_permission:
+We can define a few permissions with grok.Permission and then take a
+look at them in Zope 3's grant view:
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.security.grant')
-
-and then take a look at them in Zope 3's grant view:
-
   >>> from zope.testbrowser.testing import Browser
   >>> browser = Browser()
   >>> browser.handleErrors = False
@@ -22,10 +18,10 @@
 
 """
 import grok
-grok.define_permission('grok.ascii-permission')
 
+class ASCIIPermission(grok.Permission):
+    grok.name('grok.ascii-permission')
+
 # TODO Technically, it's absolutely possible to give permissions
 # non-ASCII names. However the way Zope 3's grant view uses widgets to
 # display form controls for each permission is not unicode-safe.
-
-#grok.define_permission(u'grok.ünicöde-permission')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/handle_exception.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/handle_exception.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/handle_exception.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,8 +4,6 @@
 and cause the grok security to fail, we have a simple test here that assures
 that we don't hit this:
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.security.handle_exception')
   >>> from zope.testbrowser.testing import Browser
   >>> browser = Browser()
   >>> browser.open("http://localhost/@@cave")

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/json.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/json.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/json.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,9 +1,6 @@
 """
 Let's test whether require decorators work for json methods.
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.security.json')
-  
   >>> from zope.testbrowser.testing import Browser
   >>> browser = Browser()
   >>> browser.handleErrors = False

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/require.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/require.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/require.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
 """
-  >>> import grok
-  >>> grok.grok('grok.ftests.security.require')
-
 Viewing a protected view with insufficient privileges will yield
 Unauthorized:
 
@@ -33,7 +30,8 @@
 import grok
 import zope.interface
 
-grok.define_permission('grok.ViewPainting')
+class ViewPainting(grok.Permission):
+    grok.name('grok.ViewPainting')
 
 class CavePainting(grok.View):
 

Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/roles.py (from rev 79383, grok/trunk/src/grok/ftests/security/roles.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/roles.py	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/roles.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,97 @@
+"""
+Viewing a protected view with insufficient privileges will yield
+Unauthorized:
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+
+  >>> browser.open("http://localhost/@@cavepainting")
+  Traceback (most recent call last):
+  HTTPError: HTTP Error 401: Unauthorized
+
+  >>> browser.open("http://localhost/@@editcavepainting")
+  Traceback (most recent call last):
+  HTTPError: HTTP Error 401: Unauthorized
+
+  >>> browser.open("http://localhost/@@erasecavepainting")
+  Traceback (most recent call last):
+  HTTPError: HTTP Error 401: Unauthorized
+
+Let's now grant anonymous the PaintingOwner role locally (so that we
+don't have to modify the global setup).  Then we can access the views
+just fine:
+
+  >>> from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+  >>> root = getRootFolder()
+  >>> IPrincipalRoleManager(root).assignRoleToPrincipal(
+  ...    'grok.PaintingOwner', 'zope.anybody')
+
+  >>> browser.open("http://localhost/@@cavepainting")
+  >>> print browser.contents
+  What a beautiful painting.
+
+  >>> browser.open("http://localhost/@@editcavepainting")
+  >>> print browser.contents
+  Let's make it even prettier.
+
+  >>> browser.open("http://localhost/@@erasecavepainting")
+  >>> print browser.contents
+  Oops, mistake, let's erase it.
+
+  >>> browser.open("http://localhost/@@approvecavepainting")
+  Traceback (most recent call last):
+  HTTPError: HTTP Error 401: Unauthorized
+"""
+
+import grok
+import zope.interface
+
+class View(grok.Permission):
+    grok.name('grok.ViewPainting')
+
+class Edit(grok.Permission):
+    grok.name('grok.EditPainting')
+
+class Erase(grok.Permission):
+    grok.name('grok.ErasePainting')
+
+class Approve(grok.Permission):
+    grok.name('grok.ApprovePainting')
+
+class PaintingOwner(grok.Role):
+    grok.name('grok.PaintingOwner')
+    grok.title('Painting Owner')
+    grok.permissions(
+        'grok.ViewPainting', 'grok.EditPainting', 'grok.ErasePainting')
+
+class CavePainting(grok.View):
+
+    grok.context(zope.interface.Interface)
+    grok.require('grok.ViewPainting')
+
+    def render(self):
+        return 'What a beautiful painting.'
+
+class EditCavePainting(grok.View):
+
+    grok.context(zope.interface.Interface)
+    grok.require('grok.EditPainting')
+
+    def render(self):
+        return 'Let\'s make it even prettier.'
+
+class EraseCavePainting(grok.View):
+
+    grok.context(zope.interface.Interface)
+    grok.require('grok.ErasePainting')
+
+    def render(self):
+        return 'Oops, mistake, let\'s erase it.'
+
+class ApproveCavePainting(grok.View):
+
+    grok.context(zope.interface.Interface)
+    grok.require('grok.ApprovePainting')
+
+    def render(self):
+        return 'Painting owners cannot approve their paintings.'

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/xmlrpc.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/xmlrpc.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/security/xmlrpc.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,9 +1,5 @@
 """
-  >>> import grok
-  >>> grok.grok('grok.ftests.security.xmlrpc')
-
-  >>> from grok.ftests.xmlrpc_helper import ServerProxy
-
+  >>> from zope.app.testing.xmlrpc import ServerProxy
   >>> server = ServerProxy("http://localhost/")
   >>> mgr_server = ServerProxy("http://mgr:mgrpw@localhost/")
 

Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/staticdir (from rev 79383, grok/trunk/src/grok/ftests/staticdir)

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/test_grok_functional.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/test_grok_functional.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/test_grok_functional.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -42,7 +42,7 @@
 
 def test_suite():
     suite = unittest.TestSuite()
-    for name in ['view', 'static', 'xmlrpc', 'traversal', 'form', 'url',
+    for name in ['view', 'staticdir', 'xmlrpc', 'traversal', 'form', 'url',
                  'security', 'utility', 'catalog','admin']:
         suite.addTest(suiteFromPackage(name))
     return suite

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverse.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverse.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverse.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,9 +3,6 @@
 implementing a 'traverse' method, but the behavior falls back to
 basic container traversal if the 'traverse' method returns None:
 
-  >>> import grok
-  >>> from grok.ftests.traversal.containertraverse import Herd, Mammoth
-  >>> grok.grok('grok.ftests.traversal.containertraverse')
   >>> getRootFolder()["herd"] = herd = Herd()
   >>> herd['manfred'] = Mammoth('Manfred')
   >>> herd['ellie'] = Mammoth('Ellie')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverser.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverser.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/containertraverser.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -3,9 +3,6 @@
 The behavior falls back to basic container traversal if the 'traverse'
 method returns None:
 
-  >>> import grok
-  >>> from grok.ftests.traversal.containertraverser import Herd, Mammoth
-  >>> grok.grok('grok.ftests.traversal.containertraverser')
   >>> getRootFolder()["herd"] = herd = Herd()
   >>> herd['manfred'] = Mammoth('Manfred')
   >>> herd['ellie'] = Mammoth('Ellie')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/items_before_views.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/items_before_views.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/items_before_views.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,9 +4,6 @@
 method returns None. Normal behaviour also means that the standard
 Zope 3 paradigm"items before views" is supported in the fallback.
 
-  >>> import grok
-  >>> from grok.ftests.traversal.items_before_views import Herd, Mammoth
-  >>> grok.grok('grok.ftests.traversal.items_before_views')
   >>> getRootFolder()["herd"] = herd = Herd()
   >>> herd['manfred'] = Mammoth('Manfred')
   >>> herd['ellie'] = Mammoth('Ellie')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/modeltraverse.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/modeltraverse.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/modeltraverse.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
 Models can determine how they want to be traversed by
 implementing a 'traverse' method:
 
-  >>> import grok
-  >>> from grok.ftests.traversal.modeltraverse import Herd
-  >>> grok.grok('grok.ftests.traversal.modeltraverse')
   >>> getRootFolder()["herd"] = Herd('The Big Mammoth Herd')
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
 Apart from using the ``traverse`` method on a model, you can
 also create a separate traverser component:
 
-  >>> import grok
-  >>> from grok.ftests.traversal.traverser import Herd
-  >>> grok.grok('grok.ftests.traversal.traverser')
   >>> getRootFolder()["herd"] = Herd('The Big Mammoth Herd')
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser_sets_parent.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser_sets_parent.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/traversal/traverser_sets_parent.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,9 +2,6 @@
 A traverser can set the __parent__ (and __name__) attributes itself,
 in which case Grok's traverser won't interfere:
 
-  >>> import grok
-  >>> from grok.ftests.traversal.traverser_sets_parent import Herd
-  >>> grok.grok('grok.ftests.traversal.traverser_sets_parent')
   >>> getRootFolder()["herd"] = Herd('The Big Mammoth Herd')
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/application.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/application.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/application.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,10 +2,6 @@
 Views have an application_url() method to easily retrieve the url of the
 application::
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.url.application')
-
-  >>> from grok.ftests.url.application import Cave, CaveMan
   >>> getRootFolder()['cave'] = cave = Cave()
   >>> cave['caveman'] = CaveMan()
 

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/redirect.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/redirect.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/redirect.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,6 @@
 """
 Views have a redirect() method to easily create redirects:
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.url.redirect')
-
-  >>> from grok.ftests.url.redirect import Mammoth
   >>> getRootFolder()['manfred'] = manfred = Mammoth()
 
 Since the index view redirects to mammoth, we expect to see the URL

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,10 +2,6 @@
 """
 Views have a method that can be used to construct URLs:
 
-  >>> import grok
-  >>> grok.grok('grok.ftests.url.url')
-
-  >>> from grok.ftests.url.url import Herd, Mammoth
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> manfred = Mammoth()

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url_function.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url_function.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/url/url_function.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,10 +4,7 @@
 absolute URL of objects.
 
   >>> from grok import url
-  >>> import grok
-  >>> grok.grok('grok.ftests.url.url_function')
   
-  >>> from grok.ftests.url.url_function import Herd, Mammoth
   >>> herd = Herd()
   >>> getRootFolder()['herd'] = herd
   >>> manfred = Mammoth()

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,15 +2,10 @@
 Local Utilities can be registered on subclasses of grok.Site using
 grok.local_utility:
 
-  >>> import grok
-  >>> from zope import component
-  >>> from grok.ftests.utility.local import *
-
-  >>> grok.grok('grok.ftests.utility.local')
-
   >>> cave = Cave()
   >>> getRootFolder()["cave"] = cave
 
+  >>> from zope import component
   >>> from zope.app.component.hooks import getSite, setSite
   >>> setSite(cave)
   

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local_override.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local_override.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/local_override.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -2,15 +2,10 @@
 Local Utilities can be registered on subclasses of grok.Site using
 grok.local_utility:
 
-  >>> import grok
-  >>> from zope import component
-  >>> from grok.ftests.utility.local_override import *
-
-  >>> grok.grok('grok.ftests.utility.local_override')
-
   >>> cave = SpikyCave()
   >>> getRootFolder()['cave'] = cave
 
+  >>> from zope import component
   >>> from zope.app.component.hooks import getSite, setSite
   >>> setSite(cave)
 

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_class.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_class.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_class.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,33 +0,0 @@
-"""
-When you try to register multiple classes with the same (interface, name)
-combination multiple times using grok.local_utility, we expect an error:
-
-  >>> import grok
-  >>> from zope import component
-  >>> from grok.ftests.utility.multiple_class import *
-
-  >>> grok.grok('grok.ftests.utility.multiple_class')
-  Traceback (most recent call last):
-    ...
-  GrokError: Conflicting local utility registration
-  <class 'grok.ftests.utility.multiple_class.Fireplace2'> in site
-  <class 'grok.ftests.utility.multiple_class.Cave'>.
-  Local utilities are registered multiple times for interface
-  <InterfaceClass grok.ftests.utility.multiple_class.IFireplace> and
-  name 'Foo'.  
-"""
-import grok
-from zope import interface
-
-class IFireplace(interface.Interface):
-    pass
-
-class Fireplace(grok.LocalUtility):
-    grok.implements(IFireplace)
-
-class Fireplace2(grok.LocalUtility):
-    grok.implements(IFireplace)
-    
-class Cave(grok.Model, grok.Site):
-    grok.local_utility(Fireplace, name='Foo')
-    grok.local_utility(Fireplace2, name='Foo')

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_directive.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_directive.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/multiple_directive.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,33 +0,0 @@
-"""
-When you call the grok.local_utility directive multiple times specifying
-the same (interface, name) combination, we expect an error:
-
-  >>> import grok
-  >>> from zope import component
-  >>> from grok.ftests.utility.multiple_directive import *
-
-  >>> grok.grok('grok.ftests.utility.multiple_directive')
-  Traceback (most recent call last):
-    ...
-  GrokError: Conflicting local utility registration
-  <class 'grok.ftests.utility.multiple_directive.Fireplace2'> in site
-  <class 'grok.ftests.utility.multiple_directive.Cave'>.
-  Local utilities are registered multiple times for interface
-  <InterfaceClass grok.ftests.utility.multiple_directive.IFireplace> and
-  name u''.  
-"""
-import grok
-from zope import interface
-
-class IFireplace(interface.Interface):
-    pass
-
-class Fireplace(grok.LocalUtility):
-    grok.implements(IFireplace)
-
-class Fireplace2(grok.LocalUtility):
-    grok.implements(IFireplace)
-    
-class Cave(grok.Model, grok.Site):
-    grok.local_utility(Fireplace, provides=IFireplace)
-    grok.local_utility(Fireplace2, provides=IFireplace)

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/public.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/public.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/public.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -4,14 +4,10 @@
 that is the site. The name the utility should have in the container can
 be controlled using name_in_container:
 
-  >>> import grok
-  >>> from zope import component
-  >>> from grok.ftests.utility.public import *
-  >>> grok.grok('grok.ftests.utility.public')
-
   >>> cave = Cave()
   >>> getRootFolder()["cave"] = cave
 
+  >>> from zope import component
   >>> from zope.app.component.hooks import getSite, setSite
   >>> setSite(cave)
   >>> cave['fireplace'] is component.getUtility(IFireplace)

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/publicnoncontainer.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/publicnoncontainer.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/publicnoncontainer.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,26 +0,0 @@
-"""
-You cannot use local_utility with 'public' set to True if the site class
-isn't a container:
-
-  >>> import grok
-  >>> from zope import component
-  >>> from grok.ftests.utility.publicnoncontainer import *
-  >>> grok.grok('grok.ftests.utility.publicnoncontainer')
-  Traceback (most recent call last):
-    ...
-  GrokError: Cannot set public to True with grok.local_utility as the site
-  (<class 'grok.ftests.utility.publicnoncontainer.Cave'>) is not a container.
-
-"""
-
-import grok
-from zope import interface
-
-class IFireplace(interface.Interface):
-    pass
-
-class Fireplace(grok.LocalUtility):
-    grok.implements(IFireplace)
-    
-class Cave(grok.Model, grok.Site):
-    grok.local_utility(Fireplace, public=True, name_in_container='fireplace')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/subclass.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/subclass.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/utility/subclass.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,15 +1,10 @@
 """
 Subclassed sites inherit all local utilities of their base classes:
 
-  >>> import grok
-  >>> from zope import component
-  >>> from grok.ftests.utility.subclass import *
-
-  >>> grok.grok('grok.ftests.utility.subclass')
-
   >>> cave = BigCave()
   >>> getRootFolder()["cave"] = cave
 
+  >>> from zope import component
   >>> from zope.app.component.hooks import getSite, setSite
 
   >>> setSite(cave)

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/argument.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/argument.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/argument.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
 """
-  >>> import grok
-  >>> from grok.ftests.view.argument import Mammoth
-  >>> grok.grok('grok.ftests.view.argument')
   >>> getRootFolder()["manfred"] = Mammoth()
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/index.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/index.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/index.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
 """
-  >>> import grok
-  >>> from grok.ftests.view.index import Mammoth
-  >>> grok.grok('grok.ftests.view.index')
   >>> getRootFolder()["manfred"] = Mammoth()
 
 The default view name for a model is 'index':

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/macros.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/macros.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/macros.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
 """
-  >>> import grok
-  >>> from grok.ftests.view.macros import Mammoth
-  >>> grok.grok('grok.ftests.view.macros')
   >>> getRootFolder()["manfred"] = Mammoth()
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/view.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/view.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/view/view.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,7 +1,4 @@
 """
-  >>> import grok
-  >>> from grok.ftests.view.view import Mammoth
-  >>> grok.grok('grok.ftests.view.view')
   >>> getRootFolder()["manfred"] = Mammoth()
 
   >>> from zope.testbrowser.testing import Browser

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc/xmlrpc.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc/xmlrpc.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc/xmlrpc.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,12 +1,9 @@
 """
-  >>> import grok
-  >>> grok.grok('grok.ftests.xmlrpc.xmlrpc')
-  >>> from grok.ftests.xmlrpc.xmlrpc import Mammoth
   >>> getRootFolder()["Manfred"] = Mammoth()
 
-  >>> from grok.ftests.xmlrpc_helper import ServerProxy
-
+  >>> from zope.app.testing.xmlrpc import ServerProxy
   >>> server = ServerProxy("http://localhost/")
+
   >>> server.Manfred.stomp()
   'Manfred stomped.'
   >>> server.Manfred.dance()

Deleted: Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc_helper.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc_helper.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/ftests/xmlrpc_helper.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,77 +0,0 @@
-# XXX This code is duplicated from Zope 3 trunk (future Zope 3.4) as we want to
-# stay compatible with Zope 3.3
-#
-##############################################################################
-#
-# Copyright (c) 2006 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""XMLRPC testing helpers for Zope 3.
-
-$Id$
-"""
-
-import StringIO
-import xmlrpclib 
-
-from zope.app.testing.functional import HTTPCaller
-
-
-class ZopeTestTransport(xmlrpclib.Transport):
-    """xmlrpclib transport that delegates to
-    zope.app.testing.functional.HTTPCaller.
-
-    It can be used like a normal transport, including support for basic
-    authentication.
-    """
-
-    verbose = False
-    handleErrors = True
-
-    def request(self, host, handler, request_body, verbose=0):
-        request = "POST %s HTTP/1.0\n" % (handler,)
-        request += "Content-Length: %i\n" % len(request_body)
-        request += "Content-Type: text/xml\n"
-
-        host, extra_headers, x509 = self.get_host_info(host)
-        if extra_headers:
-            request += "Authorization: %s\n" \
-                       % (dict(extra_headers)["Authorization"],)
-
-        request += "\n" + request_body
-        response = HTTPCaller()(request, handle_errors=self.handleErrors)
-
-        errcode = response.getStatus()
-        errmsg = response.getStatusString()
-        # This is not the same way that the normal transport deals
-        # with the headers.
-        headers = response.getHeaders()
-
-        if errcode != 200:
-            raise xmlrpclib.ProtocolError(
-                host + handler,
-                errcode, errmsg,
-                headers
-                )
-
-        return self._parse_response(
-            StringIO.StringIO(response.getBody()), sock=None)
-
-
-def ServerProxy(uri, transport=ZopeTestTransport(), encoding=None,
-                verbose=0, allow_none=0, handleErrors=True):
-    """A factory that creates a server proxy using the ZopeTestTransport
-    by default.
-    
-    """
-    if isinstance(transport, ZopeTestTransport):
-        transport.handleErrors = handleErrors
-    return xmlrpclib.ServerProxy(uri, transport, encoding, verbose, allow_none)

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/interfaces.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/interfaces.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/interfaces.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -122,14 +122,15 @@
         name_in_container - the name to use for storing the utility
         """
 
-    def define_permission(permission):
-        """Defines a new permission with the id ``permission``."""
+    def permissions(permissions):
+        """Specify the permissions that comprise a role.
+        """
 
     def require(permission):
         """Protect a view class or an XMLRPC method with ``permision``.
 
         ``permission`` must already be defined, e.g. using
-        grok.define_permission.
+        grok.Permission.
 
         grok.require can be used as a class-level directive or as a
         method decorator."""
@@ -204,7 +205,7 @@
         Note that context, module_info and templates might be required
         for some grokkers which rely on them.
         """
-    
+
     def url(request, obj, name=None):
         """Generate the URL to an object with optional name attached.
         """

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/meta.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/meta.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/meta.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -23,6 +23,9 @@
 from zope.publisher.interfaces.xmlrpc import IXMLRPCRequest
 from zope.security.permission import Permission
 from zope.security.interfaces import IPermission
+from zope.app.securitypolicy.role import Role
+from zope.app.securitypolicy.rolepermission import rolePermissionManager
+
 from zope.annotation.interfaces import IAnnotations
 
 from zope.app.publisher.xmlrpc import MethodPublisher
@@ -489,26 +492,43 @@
     site_manager.registerUtility(utility, provided=provides,
                                  name=name)
 
+class DefinePermissionGrokker(martian.ClassGrokker):
+    component_class = grok.Permission
+    priority = 1500
 
-class DefinePermissionGrokker(martian.GlobalGrokker):
+    def grok(self, name, factory, context, module_info, templates):
+        permission_name = util.class_annotation(factory, 'grok.name', None)
+        if permission_name is None:
+            raise GrokError(
+                "A permission needs to have a dotted name for its id. Use "
+                "grok.name to specify one.", factory)
+        permission_name = unicode(permission_name)
+        title = unicode(
+            util.class_annotation(factory, 'grok.title', permission_name))
+        # TODO permission description
+        component.provideUtility(
+            Permission(permission_name, title=title),
+            name=permission_name)
+        return True
 
-    priority = 1500
+class DefineRoleGrokker(martian.ClassGrokker):
+    component_class = grok.Role
+    priority = DefinePermissionGrokker.priority - 1
 
-    def grok(self, name, module, context, module_info, templates):
-        permissions = module_info.getAnnotation('grok.define_permission', [])
+    def grok(self, name, factory, context, module_info, templates):
+        role_name = util.class_annotation(factory, 'grok.name', None)
+        if role_name is None:
+            raise GrokError(
+                "A role needs to have a dotted name for its id. Use "
+                "grok.name to specify one.", factory)
+        title = unicode(util.class_annotation(factory, 'grok.title', role_name))
+        component.provideUtility(Role(role_name, title=title), name=role_name)
+
+        permissions = util.class_annotation(factory, 'grok.permissions', ())
         for permission in permissions:
-            # IPermission.title says that permission ids (and titles,
-            # descriptions) *must* be unicode objects.  Good news is
-            # that the directive handler already made sure we either
-            # got pure ASCII or unicode here:
-            permission = unicode(permission)
-            # TODO permission title and description
-            component.provideUtility(Permission(permission, title=permission),
-                                     name=permission)
-
+            rolePermissionManager.grantPermissionToRole(permission, role_name)
         return True
 
-
 class AnnotationGrokker(martian.ClassGrokker):
     component_class = grok.Annotation
 

Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/catalog (from rev 79383, grok/trunk/src/grok/tests/catalog)

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
 """
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in grok.require().
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in grok.require().
 
   >>> grok.grok(__name__)
   Traceback (most recent call last):
-  GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission.MissingPermission'>. Use grok.define_permission first.
+  GrokError: Undefined permission 'doesnt.exist' in <class
+  'grok.tests.security.missing_permission.MissingPermission'>. Use
+  grok.Permission first.
 
 """
 

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
 """
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in grok.require() in an JSON class.
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in grok.require() in an JSON class.
 
   >>> grok.grok(__name__)
   Traceback (most recent call last):
-  GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_json.MissingPermission'>. Use grok.define_permission first.
+  GrokError: Undefined permission 'doesnt.exist' in <class
+  'grok.tests.security.missing_permission_json.MissingPermission'>. Use
+  grok.Permission first.
 
 """
 

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json2.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json2.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_json2.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
 """
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in @grok.require().
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in @grok.require().
 
   >>> grok.grok(__name__)
   Traceback (most recent call last):
-  GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_json2.MissingPermission'>. Use grok.define_permission first.
+  GrokError: Undefined permission 'doesnt.exist' in <class
+  'grok.tests.security.missing_permission_json2.MissingPermission'>. Use
+  grok.Permission first.
 
 """
 

Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_name.py (from rev 79383, grok/trunk/src/grok/tests/security/missing_permission_name.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_name.py	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_name.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,15 @@
+"""
+A role has to have a name to be defined.
+
+  >>> grok.grok(__name__)
+  Traceback (most recent call last):
+  ...
+  GrokError: A permission needs to have a dotted name for its id.
+  Use grok.name to specify one.
+"""
+
+import grok
+import zope.interface
+
+class MissingName(grok.Permission):
+    pass

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
 """
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in grok.require() in an XMLRPC class.
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in grok.require() in an XMLRPC class.
 
   >>> grok.grok(__name__)
   Traceback (most recent call last):
-  GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_xmlrpc.MissingPermission'>. Use grok.define_permission first.
+  GrokError: Undefined permission 'doesnt.exist' in <class
+  'grok.tests.security.missing_permission_xmlrpc.MissingPermission'>. Use
+  grok.Permission first.
 
 """
 

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc2.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc2.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc2.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,10 +1,12 @@
 """
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in @grok.require().
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in @grok.require().
 
   >>> grok.grok(__name__)
   Traceback (most recent call last):
-  GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_xmlrpc2.MissingPermission'>. Use grok.define_permission first.
+  GrokError: Undefined permission 'doesnt.exist' in <class
+  'grok.tests.security.missing_permission_xmlrpc2.MissingPermission'>. Use
+  grok.Permission first.
 
 """
 

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc3.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc3.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_permission_xmlrpc3.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -1,19 +1,22 @@
 """
-A permission has to be defined first (using grok.define_permission for
-example) before it can be used in grok.require() in an XMLRPC class. This
-is even the case for a default permission that is never used.
+A permission has to be defined first (using grok.Permission for example)
+before it can be used in grok.require() in an XMLRPC class. This is even the
+case for a default permission that is never used.
 
   >>> grok.grok(__name__)
   Traceback (most recent call last):
    ...
-  GrokError: Undefined permission 'doesnt.exist' in <class 'grok.tests.security.missing_permission_xmlrpc3.MissingPermission'>. Use grok.define_permission first.
+  GrokError: Undefined permission 'doesnt.exist' in <class
+  'grok.tests.security.missing_permission_xmlrpc3.MissingPermission'>. Use
+  grok.Permission first.
 
 """
 
 import grok
 import zope.interface
 
-grok.define_permission('foo')
+class Foo(grok.Permission):
+    grok.name('foo')
 
 class MissingPermission(grok.XMLRPC):
     grok.context(zope.interface.Interface)

Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_role_name.py (from rev 79383, grok/trunk/src/grok/tests/security/missing_role_name.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_role_name.py	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/missing_role_name.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,14 @@
+"""
+A role has to have a name to be defined.
+
+  >>> grok.grok(__name__)
+  Traceback (most recent call last):
+  GrokError: A role needs to have a dotted name for its id.
+  Use grok.name to specify one.
+"""
+
+import grok
+import zope.interface
+
+class MissingName(grok.Role):
+    pass

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -10,9 +10,12 @@
 import grok
 import zope.interface
 
-grok.define_permission('permission.1')
-grok.define_permission('permission.2')
+class One(grok.Permission):
+    grok.name('permission.1')
 
+class Two(grok.Permission):
+    grok.name('permission.2')
+
 class MultipleView(grok.View):
     grok.context(zope.interface.Interface)
     grok.require('permission.1')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_json.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_json.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_json.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -5,14 +5,17 @@
   Traceback (most recent call last):
     ...
   GrokError: grok.require was called multiple times in <class 'grok.tests.security.multiple_require_json.MultipleJSON'>. It may only be set once for a class.
-  
+
 """
 import grok
 import zope.interface
 
-grok.define_permission('permission.1')
-grok.define_permission('permission.2')
+class One(grok.Permission):
+    grok.name('permission.1')
 
+class Two(grok.Permission):
+    grok.name('permission.2')
+
 class MultipleJSON(grok.JSON):
     grok.context(zope.interface.Interface)
     grok.require('permission.1')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_xmlrpc.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_xmlrpc.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/multiple_require_xmlrpc.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -9,9 +9,12 @@
 import grok
 import zope.interface
 
-grok.define_permission('permission.1')
-grok.define_permission('permission.2')
+class One(grok.Permission):
+    grok.name('permission.1')
 
+class Two(grok.Permission):
+    grok.name('permission.2')
+
 class MultipleXMLRPC(grok.XMLRPC):
     grok.context(zope.interface.Interface)
     grok.require('permission.1')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/view_decorator.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/view_decorator.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/security/view_decorator.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -11,7 +11,8 @@
 import grok
 import zope.interface
 
-grok.define_permission('bogus.perm')
+class Bogus(grok.Permission):
+    grok.name('bogus.perm')
 
 class BogusView(grok.View):
     grok.context(zope.interface.Interface)

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/test_grok.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/test_grok.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/test_grok.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -32,7 +32,7 @@
 
 def test_suite():
     suite = unittest.TestSuite()
-    for name in ['adapter', 'error', 'view', 'event', 'security',
+    for name in ['adapter', 'error', 'view', 'event', 'security', 'catalog',
                  'zcml', 'static', 'utility', 'xmlrpc', 'json', 'container',
                  'traversal', 'form', 'site', 'grokker', 'directive', 'util',
                  'baseclass', 'annotation', 'application']:

Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_class.py (from rev 79383, grok/trunk/src/grok/tests/utility/multiple_class.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_class.py	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_class.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,29 @@
+"""
+When you try to register multiple classes with the same (interface, name)
+combination multiple times using grok.local_utility, we expect an error:
+
+  >>> grok.grok(__name__)
+  Traceback (most recent call last):
+    ...
+  GrokError: Conflicting local utility registration
+  <class 'grok.tests.utility.multiple_class.Fireplace2'> in site
+  <class 'grok.tests.utility.multiple_class.Cave'>.
+  Local utilities are registered multiple times for interface
+  <InterfaceClass grok.tests.utility.multiple_class.IFireplace> and
+  name 'Foo'.  
+"""
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+    pass
+
+class Fireplace(grok.LocalUtility):
+    grok.implements(IFireplace)
+
+class Fireplace2(grok.LocalUtility):
+    grok.implements(IFireplace)
+    
+class Cave(grok.Model, grok.Site):
+    grok.local_utility(Fireplace, name='Foo')
+    grok.local_utility(Fireplace2, name='Foo')

Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_directive.py (from rev 79383, grok/trunk/src/grok/tests/utility/multiple_directive.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_directive.py	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/multiple_directive.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,29 @@
+"""
+When you call the grok.local_utility directive multiple times specifying
+the same (interface, name) combination, we expect an error:
+
+  >>> grok.grok(__name__)
+  Traceback (most recent call last):
+    ...
+  GrokError: Conflicting local utility registration
+  <class 'grok.tests.utility.multiple_directive.Fireplace2'> in site
+  <class 'grok.tests.utility.multiple_directive.Cave'>.
+  Local utilities are registered multiple times for interface
+  <InterfaceClass grok.tests.utility.multiple_directive.IFireplace> and
+  name u''.  
+"""
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+    pass
+
+class Fireplace(grok.LocalUtility):
+    grok.implements(IFireplace)
+
+class Fireplace2(grok.LocalUtility):
+    grok.implements(IFireplace)
+    
+class Cave(grok.Model, grok.Site):
+    grok.local_utility(Fireplace, provides=IFireplace)
+    grok.local_utility(Fireplace2, provides=IFireplace)

Copied: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/publicnoncontainer.py (from rev 79383, grok/trunk/src/grok/tests/utility/publicnoncontainer.py)
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/publicnoncontainer.py	                        (rev 0)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/utility/publicnoncontainer.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -0,0 +1,23 @@
+"""
+You cannot use local_utility with 'public' set to True if the site class
+isn't a container:
+
+  >>> grok.grok(__name__)
+  Traceback (most recent call last):
+    ...
+  GrokError: Cannot set public to True with grok.local_utility as the site
+  (<class 'grok.tests.utility.publicnoncontainer.Cave'>) is not a container.
+
+"""
+
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+    pass
+
+class Fireplace(grok.LocalUtility):
+    grok.implements(IFireplace)
+    
+class Cave(grok.Model, grok.Site):
+    grok.local_utility(Fireplace, public=True, name_in_container='fireplace')

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/view/dirtemplatesonly.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/view/dirtemplatesonly.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/view/dirtemplatesonly.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -8,7 +8,7 @@
 
   >>> grok.grok(__name__)
     From tests.py's showwarning():
-    ... UserWarning: File 'invalid.txt' has an unrecognized extension in directory '...dirtemplatesonly_templates'
+    ... UserWarning: File 'invalid.txt' has an unrecognized extension in directory '...dirtemplatesonly_templates'...
     
   >>> warnings.warn = saved_warn
 

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/tests/zcml/directiveerror.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/tests/zcml/directiveerror.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/tests/zcml/directiveerror.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -14,9 +14,8 @@
   ... </configure>''', context=context)
   Traceback (most recent call last):
     ...
-  ZopeXMLConfigurationError: File "...", line ...
-  GrokError: No module-level context for
-  <class 'grok.tests.zcml.directiveerror.CavePainting'>, please use grok.context.
+  ConfigurationExecutionError: martian.error.GrokError: No module-level context for <class 'grok.tests.zcml.directiveerror.CavePainting'>, please use grok.context.
+  ...
 
 """
 import grok

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/util.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/util.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/util.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -55,7 +55,7 @@
     if component.queryUtility(IPermission,
                               name=permission) is None:
        raise GrokError('Undefined permission %r in %r. Use '
-                       'grok.define_permission first.'
+                       'grok.Permission first.'
                        % (permission, factory), factory)
 
 def get_default_permission(factory):

Modified: Sandbox/ulif/grok-adminui-experimental/src/grok/zcml.py
===================================================================
--- Sandbox/ulif/grok-adminui-experimental/src/grok/zcml.py	2007-08-30 20:00:34 UTC (rev 79387)
+++ Sandbox/ulif/grok-adminui-experimental/src/grok/zcml.py	2007-08-30 23:53:54 UTC (rev 79388)
@@ -30,4 +30,8 @@
 
 
 def grokDirective(_context, package):
-    grok.grok(package.__name__)
+    _context.action(
+        discriminator=('grok', package.__name__),
+        callable=grok.grok,
+        args=(package.__name__,)
+        )



More information about the Checkins mailing list