[Checkins] SVN: z3c.preference/trunk/ Added form for preference categories.

Michael Howitz mh at gocept.com
Mon Jan 2 15:30:09 UTC 2012


Log message for revision 123885:
  Added form for preference categories.

Changed:
  U   z3c.preference/trunk/CHANGES.txt
  U   z3c.preference/trunk/TODO.txt
  U   z3c.preference/trunk/setup.py
  U   z3c.preference/trunk/src/z3c/preference/browser.py
  A   z3c.preference/trunk/src/z3c/preference/categories.txt
  U   z3c.preference/trunk/src/z3c/preference/configure.zcml
  U   z3c.preference/trunk/src/z3c/preference/tests.py

-=-
Modified: z3c.preference/trunk/CHANGES.txt
===================================================================
--- z3c.preference/trunk/CHANGES.txt	2012-01-02 15:27:45 UTC (rev 123884)
+++ z3c.preference/trunk/CHANGES.txt	2012-01-02 15:30:08 UTC (rev 123885)
@@ -5,7 +5,7 @@
 0.1.2 (unreleased)
 ------------------
 
-- Nothing changed yet.
+- Added form for preference categories, see `Editing preference group trees`_.
 
 
 0.1.1 (2010-07-17)

Modified: z3c.preference/trunk/TODO.txt
===================================================================
--- z3c.preference/trunk/TODO.txt	2012-01-02 15:27:45 UTC (rev 123884)
+++ z3c.preference/trunk/TODO.txt	2012-01-02 15:30:08 UTC (rev 123885)
@@ -1,8 +1,6 @@
 To do
 =======
 
-- Add a tree to access preferences deeper in the preference tree.
-
 - Render preference description.
 
-- Document how to use it in own projects. (ZCML and skin)
\ No newline at end of file
+- Document how to use it in own projects. (ZCML and skin)

Modified: z3c.preference/trunk/setup.py
===================================================================
--- z3c.preference/trunk/setup.py	2012-01-02 15:27:45 UTC (rev 123884)
+++ z3c.preference/trunk/setup.py	2012-01-02 15:30:08 UTC (rev 123885)
@@ -31,6 +31,7 @@
             '.. contents::',
             read('CHANGES.txt'),
             read('src/z3c/preference/README.txt'),
+            read('src/z3c/preference/categories.txt'),
             read('TODO.txt'),
         ]),
     license = "ZPL 2.1",

Modified: z3c.preference/trunk/src/z3c/preference/browser.py
===================================================================
--- z3c.preference/trunk/src/z3c/preference/browser.py	2012-01-02 15:27:45 UTC (rev 123884)
+++ z3c.preference/trunk/src/z3c/preference/browser.py	2012-01-02 15:30:08 UTC (rev 123885)
@@ -13,20 +13,43 @@
 #############################################################################
 
 import z3c.form.field
+import z3c.form.group
 import z3c.formui.form
 import zope.security.proxy
 
 
+def to_fields(context):
+    """Convert a preference group to a z3c.form.field.Field."""
+    schema = zope.security.proxy.getObject(context.__schema__)
+    if schema is None:
+        # no schema set on preference group, so we have no fields
+        return z3c.form.field.Fields()
+    return z3c.form.field.Fields(schema)
+
+
 class EditForm(z3c.formui.form.EditForm):
+    """Edit form for preference groups."""
 
     def __init__(self, *args, **kw):
         super(EditForm, self).__init__(*args, **kw)
         self.label = self.context.__title__
+        self.fields = to_fields(self.context)
 
-    @property
-    def fields(self):
-        schema = zope.security.proxy.getObject(self.context.__schema__)
-        if schema is None:
-            # no schema set on prefence group, so we have no fields
-            return z3c.form.field.Fields()
-        return z3c.form.field.Fields(schema)
+
+class PreferenceGroup(z3c.form.group.Group):
+    """z3c.form group of a preference group."""
+
+    def __init__(self, *args, **kw):
+        super(PreferenceGroup, self).__init__(*args, **kw)
+        self.fields = to_fields(self.context)
+
+
+class CategoryEditForm(z3c.form.group.GroupForm,
+                       EditForm):
+    """Edit form for preference categories."""
+
+    def __init__(self, *args, **kw):
+        super(CategoryEditForm, self).__init__(*args, **kw)
+        groups = [PreferenceGroup(pref, self.request, self)
+                  for pref in self.context.values()]
+        self.groups = tuple(groups)

Copied: z3c.preference/trunk/src/z3c/preference/categories.txt (from rev 123872, z3c.preference/trunk/src/z3c/preference/README.txt)
===================================================================
--- z3c.preference/trunk/src/z3c/preference/categories.txt	                        (rev 0)
+++ z3c.preference/trunk/src/z3c/preference/categories.txt	2012-01-02 15:30:08 UTC (rev 123885)
@@ -0,0 +1,125 @@
+Editing preference group trees
+==============================
+
+`zope.preference` has the concept of `preference group trees`_ and
+`preference categories` to group preferences.
+
+.. _`preference group trees`: http://pypi.python.org/pypi/zope.preference#preference-group-trees
+
+If a `preference category` is displayed using `z3c.preference` automatically
+all `preference groups` belonging to the category are rendered as groups in the
+edit form (aka ``GroupForm``).
+
+**Note:** Currently only the preference category and its *direct* children
+are rendered in the tree.
+
+
+Set up
+------
+
+At first we have to define some preference interfaces presenting the tree. In
+this example we think of a web application with some areas:
+
+  >>> import zope.interface
+  >>> import zope.schema
+  >>> class IGeneralSettings(zope.interface.Interface):
+  ...     """General preferences"""
+  ...
+  ...     language = zope.schema.Choice(
+  ...         title=u"Language",
+  ...         description=u"The language which should be used for display.",
+  ...         values=['German', 'English', 'Russian'],
+  ...         default='German')
+
+  >>> class IRSSSettings(zope.interface.Interface):
+  ...     """Preferences for the RSS area of the application."""
+  ...
+  ...     number = zope.schema.Int(
+  ...         title=u"Item count",
+  ...         description=u"Maximum number of items in each feed.")
+
+  >>> class ISearchSettings(zope.interface.Interface):
+  ...     """Preferences for the search area of the application."""
+  ...
+  ...     store_searches = zope.schema.Bool(
+  ...         title=u"Store searches?",
+  ...         description=u"Should searches be kept for later use?",
+  ...         default=True)
+
+The interfaces must be registered for preferences:
+
+  >>> from zope.configuration import xmlconfig
+  >>> import zope.preference
+  >>> context = xmlconfig.file('meta.zcml', zope.preference)
+
+  >>> context = xmlconfig.string('''
+  ...     <configure
+  ...         xmlns="http://namespaces.zope.org/zope"
+  ...         i18n_domain="test">
+  ...
+  ...       <preferenceGroup
+  ...           id="app"
+  ...           title="General Settings"
+  ...           schema="z3c.preference.categories.IGeneralSettings"
+  ...           category="true"
+  ...           />
+  ...
+  ...       <preferenceGroup
+  ...           id="app.rss"
+  ...           title="RSS Settings"
+  ...           schema="z3c.preference.categories.IRSSSettings"
+  ...           category="false"
+  ...           />
+  ...
+  ...       <preferenceGroup
+  ...           id="app.search"
+  ...           title="Search Settings"
+  ...           schema="z3c.preference.categories.ISearchSettings"
+  ...           category="false"
+  ...           />
+  ...
+  ...     </configure>''', context)
+
+
+To access the forms a browser is needed, the user must be authorized as
+the preferences are stored in the principal annotations:
+
+>>> from zope.app.wsgi.testlayer import Browser
+>>> browser = Browser()
+>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+
+
+Editing preference group trees using browser
+--------------------------------------------
+
+There is a namespace to access the preferences. On the page a form is
+displayed which shows the default values:
+
+>>> browser.handleErrors = False
+>>> browser.open('http://localhost/++preferences++/app')
+>>> browser.getControl('Language').displayValue
+['German']
+>>> browser.getControl('Item count').value
+''
+>>> browser.getControl('yes').selected
+True
+>>> browser.getControl('no').selected
+False
+
+The values can be changed and submitting the form makes them persistent:
+
+>>> browser.getControl('Language').displayValue = ['English']
+>>> browser.getControl('Item count').value = '20'
+>>> browser.getControl('no').click()
+>>> browser.getControl('Apply').click()
+
+After submitting the form gets displayed again and shows the changed values:
+
+>>> 'Data successfully updated.' in browser.contents
+True
+>>> browser.getControl('Language').displayValue
+['English']
+>>> browser.getControl('Item count').value
+'20'
+>>> browser.getControl('no').selected
+True

Modified: z3c.preference/trunk/src/z3c/preference/configure.zcml
===================================================================
--- z3c.preference/trunk/src/z3c/preference/configure.zcml	2012-01-02 15:27:45 UTC (rev 123884)
+++ z3c.preference/trunk/src/z3c/preference/configure.zcml	2012-01-02 15:30:08 UTC (rev 123885)
@@ -15,6 +15,13 @@
       permission="z3c.preference.EditPreference"
       class=".browser.EditForm" />
 
+  <z3c:pagelet
+      for="zope.preference.interfaces.IPreferenceCategory"
+      layer=".interfaces.IPreferenceLayer"
+      name="index.html"
+      permission="z3c.preference.EditPreference"
+      class=".browser.CategoryEditForm" />
+
   <browser:defaultView
       layer=".interfaces.IPreferenceLayer"
       name="index.html" />

Modified: z3c.preference/trunk/src/z3c/preference/tests.py
===================================================================
--- z3c.preference/trunk/src/z3c/preference/tests.py	2012-01-02 15:27:45 UTC (rev 123884)
+++ z3c.preference/trunk/src/z3c/preference/tests.py	2012-01-02 15:30:08 UTC (rev 123885)
@@ -20,14 +20,17 @@
 
 def setUp(test):
     zope.testing.module.setUp(test, 'z3c.preference.README')
+    zope.testing.module.setUp(test, 'z3c.preference.categories')
 
 
 def tearDown(test):
-    zope.component.testing.tearDown(test)
     zope.testing.module.tearDown(test)
 
 
 def test_suite():
-    suite = doctest.DocFileSuite('README.txt', setUp=setUp, tearDown=tearDown)
+    suite = doctest.DocFileSuite(
+        'README.txt',
+        'categories.txt',
+        setUp=setUp, tearDown=tearDown)
     suite.layer = z3c.preference.testing.Layer
     return suite



More information about the checkins mailing list