[Checkins] SVN: zope.app.preference/tags/3.5.0/ Tag 3.5.0

Dan Korostelev nadako at gmail.com
Sat Jan 17 08:36:57 EST 2009


Log message for revision 94793:
  Tag 3.5.0

Changed:
  A   zope.app.preference/tags/3.5.0/
  D   zope.app.preference/tags/3.5.0/CHANGES.txt
  A   zope.app.preference/tags/3.5.0/CHANGES.txt
  D   zope.app.preference/tags/3.5.0/buildout.cfg
  A   zope.app.preference/tags/3.5.0/buildout.cfg
  D   zope.app.preference/tags/3.5.0/setup.py
  A   zope.app.preference/tags/3.5.0/setup.py
  D   zope.app.preference/tags/3.5.0/src/zope/app/preference/README.txt
  A   zope.app.preference/tags/3.5.0/src/zope/app/preference/README.txt
  D   zope.app.preference/tags/3.5.0/src/zope/app/preference/SETUP.cfg
  D   zope.app.preference/tags/3.5.0/src/zope/app/preference/preference-configure.zcml
  D   zope.app.preference/tags/3.5.0/src/zope/app/preference/preference-meta.zcml

-=-
Deleted: zope.app.preference/tags/3.5.0/CHANGES.txt
===================================================================
--- zope.app.preference/trunk/CHANGES.txt	2009-01-17 13:10:51 UTC (rev 94790)
+++ zope.app.preference/tags/3.5.0/CHANGES.txt	2009-01-17 13:36:57 UTC (rev 94793)
@@ -1,14 +0,0 @@
-=======
-CHANGES
-=======
-
-3.4.1 (2007-10-30)
-------------------
-
-- Avoid deprecation warnings for ``ZopeMessageFactory``.
-
-
-3.4.0 (2007-10-25)
-------------------
-
-- Initial release independent of the main Zope tree.

Copied: zope.app.preference/tags/3.5.0/CHANGES.txt (from rev 94792, zope.app.preference/trunk/CHANGES.txt)
===================================================================
--- zope.app.preference/tags/3.5.0/CHANGES.txt	                        (rev 0)
+++ zope.app.preference/tags/3.5.0/CHANGES.txt	2009-01-17 13:36:57 UTC (rev 94793)
@@ -0,0 +1,28 @@
+=======
+CHANGES
+=======
+
+3.5.0 (2009-01-17)
+------------------
+
+- Get rid of zope.app.zapi dependency, replacing its
+  uses with direct imports from original places.
+
+- Change mailing address from zope3-dev to zope-dev, as
+  the first one is retired now.
+
+- Fix tests for python 2.6.
+
+- Remove zpkg stuff and zcml include files for
+  old mkzopeinstance-based instances.
+
+3.4.1 (2007-10-30)
+------------------
+
+- Avoid deprecation warnings for ``ZopeMessageFactory``.
+
+
+3.4.0 (2007-10-25)
+------------------
+
+- Initial release independent of the main Zope tree.

Deleted: zope.app.preference/tags/3.5.0/buildout.cfg
===================================================================
--- zope.app.preference/trunk/buildout.cfg	2009-01-17 13:10:51 UTC (rev 94790)
+++ zope.app.preference/tags/3.5.0/buildout.cfg	2009-01-17 13:36:57 UTC (rev 94793)
@@ -1,7 +0,0 @@
-[buildout]
-develop = .
-parts = test
-
-[test]
-recipe = zc.recipe.testrunner
-eggs = zope.app.preference

Copied: zope.app.preference/tags/3.5.0/buildout.cfg (from rev 94792, zope.app.preference/trunk/buildout.cfg)
===================================================================
--- zope.app.preference/tags/3.5.0/buildout.cfg	                        (rev 0)
+++ zope.app.preference/tags/3.5.0/buildout.cfg	2009-01-17 13:36:57 UTC (rev 94793)
@@ -0,0 +1,7 @@
+[buildout]
+develop = .
+parts = test
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = zope.app.preference [test]

Deleted: zope.app.preference/tags/3.5.0/setup.py
===================================================================
--- zope.app.preference/trunk/setup.py	2009-01-17 13:10:51 UTC (rev 94790)
+++ zope.app.preference/tags/3.5.0/setup.py	2009-01-17 13:36:57 UTC (rev 94793)
@@ -1,79 +0,0 @@
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""Setup for zope.app.preference package
-
-$Id$
-"""
-import os
-from setuptools import setup, find_packages
-
-def read(*rnames):
-    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-
-setup(name = 'zope.app.preference',
-      version = '3.5.0',
-      author='Zope Corporation and Contributors',
-      author_email='zope3-dev at zope.org',
-      description='User Preferences Framework',
-      long_description=(
-          read('README.txt')
-          + '\n\n' +
-          'Detailed Dcoumentation\n' +
-          '======================\n'
-          + '\n\n' +
-          read('src', 'zope', 'app', 'preference', 'README.txt')
-          + '\n\n' +
-          read('CHANGES.txt')
-          ),
-      keywords = "zope3 user preference",
-      classifiers = [
-          'Development Status :: 5 - Production/Stable',
-          'Environment :: Web Environment',
-          'Intended Audience :: Developers',
-          'License :: OSI Approved :: Zope Public License',
-          'Programming Language :: Python',
-          'Natural Language :: English',
-          'Operating System :: OS Independent',
-          'Topic :: Internet :: WWW/HTTP',
-          'Framework :: Zope3'],
-      url='http://cheeseshop.python.org/pypi/zope.app.preference',
-      license='ZPL 2.1',
-      packages=find_packages('src'),
-      package_dir = {'': 'src'},
-      namespace_packages=['zope', 'zope.app'],
-      extras_require=dict(test=['zope.app.testing',
-                                'zope.testing']),
-      install_requires = ['setuptools',
-                          'ZODB3',
-                          'zope.annotation',
-                          'zope.app.basicskin',
-                          'zope.app.component',
-                          'zope.app.container',
-                          'zope.app.form',
-                          'zope.app.pagetemplate',
-                          'zope.app.renderer',
-                          'zope.app.tree',
-                          'zope.component',
-                          'zope.configuration',
-                          'zope.i18n',
-                          'zope.i18nmessageid',
-                          'zope.interface',
-                          'zope.location',
-                          'zope.schema',
-                          'zope.security',
-                          'zope.traversing',
-                          ],
-      include_package_data = True,
-      zip_safe = False,
-      )

Copied: zope.app.preference/tags/3.5.0/setup.py (from rev 94792, zope.app.preference/trunk/setup.py)
===================================================================
--- zope.app.preference/tags/3.5.0/setup.py	                        (rev 0)
+++ zope.app.preference/tags/3.5.0/setup.py	2009-01-17 13:36:57 UTC (rev 94793)
@@ -0,0 +1,79 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""Setup for zope.app.preference package
+
+$Id$
+"""
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup(name = 'zope.app.preference',
+      version = '3.5.0',
+      author='Zope Corporation and Contributors',
+      author_email='zope-dev at zope.org',
+      description='User Preferences Framework',
+      long_description=(
+          read('README.txt')
+          + '\n\n' +
+          'Detailed Dcoumentation\n' +
+          '======================\n'
+          + '\n\n' +
+          read('src', 'zope', 'app', 'preference', 'README.txt')
+          + '\n\n' +
+          read('CHANGES.txt')
+          ),
+      keywords = "zope3 user preference",
+      classifiers = [
+          'Development Status :: 5 - Production/Stable',
+          'Environment :: Web Environment',
+          'Intended Audience :: Developers',
+          'License :: OSI Approved :: Zope Public License',
+          'Programming Language :: Python',
+          'Natural Language :: English',
+          'Operating System :: OS Independent',
+          'Topic :: Internet :: WWW/HTTP',
+          'Framework :: Zope3'],
+      url='http://pypi.python.org/pypi/zope.app.preference',
+      license='ZPL 2.1',
+      packages=find_packages('src'),
+      package_dir = {'': 'src'},
+      namespace_packages=['zope', 'zope.app'],
+      extras_require=dict(test=['zope.app.testing',
+                                'zope.testing']),
+      install_requires = ['setuptools',
+                          'ZODB3',
+                          'zope.annotation',
+                          'zope.app.basicskin',
+                          'zope.app.component',
+                          'zope.app.container',
+                          'zope.app.form',
+                          'zope.app.pagetemplate',
+                          'zope.app.renderer',
+                          'zope.app.tree',
+                          'zope.component',
+                          'zope.configuration',
+                          'zope.i18n',
+                          'zope.i18nmessageid',
+                          'zope.interface',
+                          'zope.location',
+                          'zope.schema',
+                          'zope.security',
+                          'zope.traversing',
+                          ],
+      include_package_data = True,
+      zip_safe = False,
+      )

Deleted: zope.app.preference/tags/3.5.0/src/zope/app/preference/README.txt
===================================================================
--- zope.app.preference/trunk/src/zope/app/preference/README.txt	2009-01-17 13:10:51 UTC (rev 94790)
+++ zope.app.preference/tags/3.5.0/src/zope/app/preference/README.txt	2009-01-17 13:36:57 UTC (rev 94793)
@@ -1,482 +0,0 @@
-================
-User Preferences
-================
-
-Implementing user preferences is usually a painful task, since it requires a
-lot of custom coding and constantly changing preferences makes it hard to
-maintain the data and UI. The `preference` package
-
-  >>> from zope.app.preference import preference
-
-eases this pain by providing a generic user preferences framework that uses
-schemas to categorize and describe the preferences.
-
-We also have to do some additional setup beforehand:
-
-  >>> from zope.app.testing import setup
-
-  >>> import zope.app.component.hooks
-  >>> zope.app.component.hooks.setHooks()
-  >>> setup.setUpTraversal()
-  >>> setup.setUpSiteManagerLookup()
-
-
-Preference Groups
-------------------
-
-Preferences are grouped in preference groups and the preferences inside a
-group are specified via the preferences group schema:
-
-  >>> import zope.interface
-  >>> import zope.schema
-  >>> class IZMIUserSettings(zope.interface.Interface):
-  ...     """Basic User Preferences"""
-  ...
-  ...     email = zope.schema.TextLine(
-  ...         title=u"E-mail Address",
-  ...         description=u"E-mail Address used to send notifications")
-  ...
-  ...     skin = zope.schema.Choice(
-  ...         title=u"Skin",
-  ...         description=u"The skin that should be used for the ZMI.",
-  ...         values=['Rotterdam', 'ZopeTop', 'Basic'],
-  ...         default='Rotterdam')
-  ...
-  ...     showZopeLogo = zope.schema.Bool(
-  ...         title=u"Show Zope Logo",
-  ...         description=u"Specifies whether Zope logo should be displayed "
-  ...                     u"at the top of the screen.",
-  ...         default=True)
-
-Now we can instantiate the preference group. Each preference group must have an
-ID by which it can be accessed and optional title and description fields for UI
-purposes:
-
-  >>> settings = preference.PreferenceGroup(
-  ...     "ZMISettings",
-  ...     schema=IZMIUserSettings,
-  ...     title=u"ZMI User Settings",
-  ...     description=u"")
-
-Note that the preferences group provides the interface it is representing:
-
-  >>> IZMIUserSettings.providedBy(settings)
-  True
-
-and the id, schema and title of the group are directly available:
-
-  >>> settings.__id__
-  'ZMISettings'
-  >>> settings.__schema__
-  <InterfaceClass zope.app.preference.README.IZMIUserSettings>
-  >>> settings.__title__
-  u'ZMI User Settings'
-
-So let's ask the preference group for the `skin` setting:
-
-  >>> settings.skin #doctest:+ELLIPSIS
-  Traceback (most recent call last):
-  ...
-  NoInteraction
-
-
-So why did the lookup fail? Because we have not specified a principal yet, for
-which we want to lookup the preferences. To do that, we have to create a new
-interaction:
-
-  >>> class Principal:
-  ...     def __init__(self, id):
-  ...         self.id = id
-  >>> principal = Principal('zope.user')
-
-  >>> class Participation:
-  ...     interaction = None
-  ...     def __init__(self, principal):
-  ...         self.principal = principal
-
-  >>> participation = Participation(principal)
-
-  >>> import zope.security.management
-  >>> zope.security.management.newInteraction(participation)
-
-We also need an IAnnotations adapter for principals, so we can store the
-settings:
-
-  >>> from zope.annotation.interfaces import IAnnotations
-  >>> class PrincipalAnnotations(dict):
-  ...     zope.interface.implements(IAnnotations)
-  ...     data = {}
-  ...     def __new__(class_, principal, context):
-  ...         try:
-  ...             annotations = class_.data[principal.id]
-  ...         except KeyError:
-  ...             annotations = dict.__new__(class_)
-  ...             class_.data[principal.id] = annotations
-  ...         return annotations
-  ...     def __init__(self, principal, context):
-  ...         pass
-
-  >>> from zope.app.testing import ztapi
-  >>> ztapi.provideAdapter((Principal, zope.interface.Interface), IAnnotations,
-  ...                      PrincipalAnnotations)
-
-Let's now try to access the settings again:
-
-  >>> settings.skin
-  'Rotterdam'
-
-which is the default value, since we have not set it yet. We can now reassign
-the value:
-
-  >>> settings.skin = 'Basic'
-  >>> settings.skin
-  'Basic'
-
-However, you cannot just enter any value, since it is validated before the
-assignment:
-
-  >>> settings.skin = 'MySkin'
-  Traceback (most recent call last):
-  ...
-  ConstraintNotSatisfied: MySkin  
-
-
-Preference Group Trees
-----------------------
-
-The preferences would not be very powerful, if you could create a full
-preferences. So let's create a sub-group for our ZMI user settings, where we
-can adjust the look and feel of the folder contents view:
-
-  >>> import sets
-  >>> class IFolderSettings(zope.interface.Interface):
-  ...     """Basic User Preferences"""
-  ...
-  ...     shownFields = zope.schema.Set(
-  ...         title=u"Shown Fields",
-  ...         description=u"Fields shown in the table.",
-  ...         value_type=zope.schema.Choice(['name', 'size', 'creator']),
-  ...         default=sets.Set(['name', 'size']))
-  ...
-  ...     sortedBy = zope.schema.Choice(
-  ...         title=u"Sorted By",
-  ...         description=u"Data field to sort by.",
-  ...         values=['name', 'size', 'creator'],
-  ...         default='name')
-
-  >>> folderSettings = preference.PreferenceGroup(
-  ...     "ZMISettings.Folder",
-  ...     schema=IFolderSettings,
-  ...     title=u"Folder Content View Settings")
-
-Note that the id was chosen so that the parent id is the prefix of the child's
-id. Our new preference sub-group should now be available as an attribute or an
-item on the parent group ...
-
-  >>> settings.Folder
-  Traceback (most recent call last):
-  ...
-  AttributeError: 'Folder' is not a preference or sub-group.
-
-... but not before we register the groups as utilities:
-
-  >>> from zope.app.preference import interfaces
-  >>> from zope.app.testing import ztapi
-
-  >>> ztapi.provideUtility(interfaces.IPreferenceGroup, settings,
-  ...                      name='ZMISettings')
-  >>> ztapi.provideUtility(interfaces.IPreferenceGroup, folderSettings,
-  ...                      name='ZMISettings.Folder')
-
-If we now try to lookup the sub-group again, we should be successful:
-
-  >>> settings.Folder #doctest:+ELLIPSIS
-  <zope.app.preference.preference.PreferenceGroup object at ...>
-
-  >>> settings['Folder'] #doctest:+ELLIPSIS
-  <zope.app.preference.preference.PreferenceGroup object at ...>
-
-While the registry of the preference groups is flat, the careful naming of the
-ids allows us to have a tree of preferences. Note that this pattern is very
-similar to the way modules are handled in Python; they are stored in a flat
-dictionary in ``sys.modules``, but due to the naming they appear to be in a
-namespace tree.
-
-While we are at it, there are also preference categories that can be compared
-to Python packages. They basically are just a higher level grouping concept
-that is used by the UI to better organize the preferences. A preference group
-can be converted to a category by simply providing an additional interface:
-
-  >>> zope.interface.alsoProvides(settings, interfaces.IPreferenceCategory)
-
-  >>> interfaces.IPreferenceCategory.providedBy(settings)
-  True
-
-
-Default Preferences
--------------------
-
-It sometimes desirable to define default settings on a site-by-site basis,
-instead of just using the default value from the schema. The preferences
-package provides a module
- 
-  >>> from zope.app.preference import default
-
-that implements a default preferences provider that can be added as a unnamed
-utility for each site. So the first step is to create a site:
-  
-  >>> root = setup.buildSampleFolderTree()
-  >>> rsm = setup.createSiteManager(root, True)
-
-Now we can register the default preference provider with the root site:
-
-  >>> provider = setup.addUtility(rsm, '', 
-  ...                             interfaces.IDefaultPreferenceProvider, 
-  ...                             default.DefaultPreferenceProvider())
-
-So before we set an explicit default value for a preference, the schema field
-default is used:
-
-  >>> settings.Folder.sortedBy
-  'name'
-
-But if we now set a new default value with the provider,
-
-  >>> defaultFolder = provider.getDefaultPreferenceGroup('ZMISettings.Folder')
-  >>> defaultFolder.sortedBy = 'size'
-
-then the default of the setting changes:
-  
-  >>> settings.Folder.sortedBy
-  'size'
-
-The default preference providers also implicitly acquire default values from
-parent sites. So if we make `folder1` a site and set it as the active site
-
-  >>> folder1 = root['folder1']
-  >>> sm1 = setup.createSiteManager(folder1, True)
-
-and add a default provider there,
-
-  >>> provider1 = setup.addUtility(sm1, '', 
-  ...                              interfaces.IDefaultPreferenceProvider, 
-  ...                              default.DefaultPreferenceProvider())
-
-then we still get the root's default values, because we have not defined any
-in the higher default provider:
-
-  >>> settings.Folder.sortedBy
-  'size'
-
-But if we provide the new provider with a default value for `sortedBy`,
-
-  >>> defaultFolder1 = provider1.getDefaultPreferenceGroup('ZMISettings.Folder')
-  >>> defaultFolder1.sortedBy = 'creator'
-
-then it is used instead:
-
-  >>> settings.Folder.sortedBy
-  'creator'
-
-Of course, once the root site becomes our active site again
-
-  >>> zope.app.component.hooks.setSite(root)
-
-the default value of the root provider is used:
-
-  >>> settings.Folder.sortedBy
-  'size'
-
-Of course, all the defaults in the world are not relevant anymore as soon as
-the user actually provides a value:
-
-  >>> settings.Folder.sortedBy = 'name'
-  >>> settings.Folder.sortedBy
-  'name'
-
-Oh, and have I mentioned that entered values are always validated? So you
-cannot just assign any old value:
-
-  >>> settings.Folder.sortedBy = 'foo'
-  Traceback (most recent call last):
-  ...
-  ConstraintNotSatisfied: foo
-
-Finally, if the user deletes his/her explicit setting, we are back to the
-default value:
-
-  >>> del settings.Folder.sortedBy
-  >>> settings.Folder.sortedBy
-  'size'
-
-
-Creating Preference Groups Using ZCML
--------------------------------------
-
-If you are using the user preference system in Zope 3, you will not have to
-manually setup the preference groups as we did above (of course). We will use
-ZCML instead. First, we need to register the directives:
-
-  >>> from zope.configuration import xmlconfig
-  >>> import zope.app.preference
-  >>> context = xmlconfig.file('meta.zcml', zope.app.preference)
-
-Then the system sets up a root preference group:
-
-  >>> context = xmlconfig.string('''
-  ...     <configure
-  ...         xmlns="http://namespaces.zope.org/zope"
-  ...         i18n_domain="test">
-  ...
-  ...       <preferenceGroup
-  ...           id=""
-  ...           title="User Preferences" 
-  ...           />
-  ...
-  ...     </configure>''', context)
-
-Now we can use the preference system in its intended way. We access the folder
-settings as follows:
-
-  >>> import zope.component
-  >>> prefs = zope.component.getUtility(interfaces.IPreferenceGroup)
-  >>> prefs.ZMISettings.Folder.sortedBy
-  'size'
-
-Let's register the ZMI settings again under a new name via ZCML:
-
-  >>> context = xmlconfig.string('''
-  ...     <configure
-  ...         xmlns="http://namespaces.zope.org/zope"
-  ...         i18n_domain="test">
-  ...
-  ...       <preferenceGroup
-  ...           id="ZMISettings2"
-  ...           title="ZMI Settings NG"
-  ...           schema="zope.app.preference.README.IZMIUserSettings"
-  ...           category="true"
-  ...           />
-  ...
-  ...     </configure>''', context)
-
-  >>> prefs.ZMISettings2 #doctest:+ELLIPSIS
-  <zope.app.preference.preference.PreferenceGroup object at ...>
-
-  >>> prefs.ZMISettings2.__title__
-  u'ZMI Settings NG'
-
-  >>> IZMIUserSettings.providedBy(prefs.ZMISettings2)
-  True
-  >>> interfaces.IPreferenceCategory.providedBy(prefs.ZMISettings2)
-  True
-
-And the tree can built again by carefully constructing the id:
-
-  >>> context = xmlconfig.string('''
-  ...     <configure
-  ...         xmlns="http://namespaces.zope.org/zope"
-  ...         i18n_domain="test">
-  ...
-  ...       <preferenceGroup
-  ...           id="ZMISettings2.Folder"
-  ...           title="Folder Settings"
-  ...           schema="zope.app.preference.README.IFolderSettings"
-  ...           />
-  ...
-  ...     </configure>''', context)
-
-  >>> prefs.ZMISettings2 #doctest:+ELLIPSIS
-  <zope.app.preference.preference.PreferenceGroup object at ...>
-
-  >>> prefs.ZMISettings2.Folder.__title__
-  u'Folder Settings'
-
-  >>> IFolderSettings.providedBy(prefs.ZMISettings2.Folder)
-  True
-  >>> interfaces.IPreferenceCategory.providedBy(prefs.ZMISettings2.Folder)
-  False
-
-
-Simple Python-Level Access
---------------------------
-
-If a site is set, getting the user preferences is very simple:
-
-  >>> from zope.app.preference import UserPreferences
-  >>> prefs2 = UserPreferences()
-  >>> prefs2.ZMISettings.Folder.sortedBy
-  'size'
-
-This function is also commonly registered as an adapter,
-
-  >>> from zope.location.interfaces import ILocation
-  >>> ztapi.provideAdapter(ILocation, interfaces.IUserPreferences, 
-  ...                      UserPreferences)
-
-so that you can adapt any location to the user preferences:
-
-  >>> prefs3 = interfaces.IUserPreferences(folder1)
-  >>> prefs3.ZMISettings.Folder.sortedBy
-  'creator'
-
-
-Traversal
----------
-
-Okay, so all these objects are nice, but they do not make it any easier to
-access the preferences in page templates. Thus, a special traversal namespace
-has been created that makes it very simple to access the preferences via a
-traversal path. But before we can use the path expressions, we have to
-register all necessary traversal components and the special `preferences`
-namespace:
-
-  >>> import zope.traversing.interfaces
-  >>> ztapi.provideAdapter(None,
-  ...                      zope.traversing.interfaces.ITraversable,
-  ...                      preference.preferencesNamespace,
-  ...                      'preferences')
-
-We can now access the preferences as follows:
-
-  >>> from zope.traversing.api import traverse
-  >>> traverse(None, '++preferences++ZMISettings/skin')
-  'Basic'
-  >>> traverse(None, '++preferences++/ZMISettings/skin')
-  'Basic'
-
-
-Security
---------
-
-You might already wonder under which permissions the preferences are
-available. They are actually available publicly (`CheckerPublic`), but that
-is not a problem, since the available values are looked up specifically for
-the current user. And why should a user not have full access to his/her
-preferences? 
-
-Let's create a checker using the function that the security machinery is
-actually using:
-
-  >>> checker = preference.PreferenceGroupChecker(settings)
-  >>> checker.permission_id('skin')
-  Global(CheckerPublic,zope.security.checker)
-  >>> checker.setattr_permission_id('skin')
-  Global(CheckerPublic,zope.security.checker)
-
-The id, title, description, and schema are publicly available for access,
-but are not available for mutation at all:
-
-  >>> checker.permission_id('__id__')
-  Global(CheckerPublic,zope.security.checker)
-  >>> checker.setattr_permission_id('__id__') is None
-  True
-
-
-The only way security could be compromised is when one could override the
-annotations property. However, this property is not available for public
-consumption at all, including read access:
-
-  >>> checker.permission_id('annotation') is None
-  True
-  >>> checker.setattr_permission_id('annotation') is None
-  True

Copied: zope.app.preference/tags/3.5.0/src/zope/app/preference/README.txt (from rev 94791, zope.app.preference/trunk/src/zope/app/preference/README.txt)
===================================================================
--- zope.app.preference/tags/3.5.0/src/zope/app/preference/README.txt	                        (rev 0)
+++ zope.app.preference/tags/3.5.0/src/zope/app/preference/README.txt	2009-01-17 13:36:57 UTC (rev 94793)
@@ -0,0 +1,481 @@
+================
+User Preferences
+================
+
+Implementing user preferences is usually a painful task, since it requires a
+lot of custom coding and constantly changing preferences makes it hard to
+maintain the data and UI. The `preference` package
+
+  >>> from zope.app.preference import preference
+
+eases this pain by providing a generic user preferences framework that uses
+schemas to categorize and describe the preferences.
+
+We also have to do some additional setup beforehand:
+
+  >>> from zope.app.testing import setup
+
+  >>> import zope.app.component.hooks
+  >>> zope.app.component.hooks.setHooks()
+  >>> setup.setUpTraversal()
+  >>> setup.setUpSiteManagerLookup()
+
+
+Preference Groups
+------------------
+
+Preferences are grouped in preference groups and the preferences inside a
+group are specified via the preferences group schema:
+
+  >>> import zope.interface
+  >>> import zope.schema
+  >>> class IZMIUserSettings(zope.interface.Interface):
+  ...     """Basic User Preferences"""
+  ...
+  ...     email = zope.schema.TextLine(
+  ...         title=u"E-mail Address",
+  ...         description=u"E-mail Address used to send notifications")
+  ...
+  ...     skin = zope.schema.Choice(
+  ...         title=u"Skin",
+  ...         description=u"The skin that should be used for the ZMI.",
+  ...         values=['Rotterdam', 'ZopeTop', 'Basic'],
+  ...         default='Rotterdam')
+  ...
+  ...     showZopeLogo = zope.schema.Bool(
+  ...         title=u"Show Zope Logo",
+  ...         description=u"Specifies whether Zope logo should be displayed "
+  ...                     u"at the top of the screen.",
+  ...         default=True)
+
+Now we can instantiate the preference group. Each preference group must have an
+ID by which it can be accessed and optional title and description fields for UI
+purposes:
+
+  >>> settings = preference.PreferenceGroup(
+  ...     "ZMISettings",
+  ...     schema=IZMIUserSettings,
+  ...     title=u"ZMI User Settings",
+  ...     description=u"")
+
+Note that the preferences group provides the interface it is representing:
+
+  >>> IZMIUserSettings.providedBy(settings)
+  True
+
+and the id, schema and title of the group are directly available:
+
+  >>> settings.__id__
+  'ZMISettings'
+  >>> settings.__schema__
+  <InterfaceClass zope.app.preference.README.IZMIUserSettings>
+  >>> settings.__title__
+  u'ZMI User Settings'
+
+So let's ask the preference group for the `skin` setting:
+
+  >>> settings.skin #doctest:+ELLIPSIS
+  Traceback (most recent call last):
+  ...
+  NoInteraction
+
+
+So why did the lookup fail? Because we have not specified a principal yet, for
+which we want to lookup the preferences. To do that, we have to create a new
+interaction:
+
+  >>> class Principal:
+  ...     def __init__(self, id):
+  ...         self.id = id
+  >>> principal = Principal('zope.user')
+
+  >>> class Participation:
+  ...     interaction = None
+  ...     def __init__(self, principal):
+  ...         self.principal = principal
+
+  >>> participation = Participation(principal)
+
+  >>> import zope.security.management
+  >>> zope.security.management.newInteraction(participation)
+
+We also need an IAnnotations adapter for principals, so we can store the
+settings:
+
+  >>> from zope.annotation.interfaces import IAnnotations
+  >>> class PrincipalAnnotations(dict):
+  ...     zope.interface.implements(IAnnotations)
+  ...     data = {}
+  ...     def __new__(class_, principal, context):
+  ...         try:
+  ...             annotations = class_.data[principal.id]
+  ...         except KeyError:
+  ...             annotations = dict.__new__(class_)
+  ...             class_.data[principal.id] = annotations
+  ...         return annotations
+  ...     def __init__(self, principal, context):
+  ...         pass
+
+  >>> from zope.app.testing import ztapi
+  >>> ztapi.provideAdapter((Principal, zope.interface.Interface), IAnnotations,
+  ...                      PrincipalAnnotations)
+
+Let's now try to access the settings again:
+
+  >>> settings.skin
+  'Rotterdam'
+
+which is the default value, since we have not set it yet. We can now reassign
+the value:
+
+  >>> settings.skin = 'Basic'
+  >>> settings.skin
+  'Basic'
+
+However, you cannot just enter any value, since it is validated before the
+assignment:
+
+  >>> settings.skin = 'MySkin'
+  Traceback (most recent call last):
+  ...
+  ConstraintNotSatisfied: MySkin  
+
+
+Preference Group Trees
+----------------------
+
+The preferences would not be very powerful, if you could create a full
+preferences. So let's create a sub-group for our ZMI user settings, where we
+can adjust the look and feel of the folder contents view:
+
+  >>> class IFolderSettings(zope.interface.Interface):
+  ...     """Basic User Preferences"""
+  ...
+  ...     shownFields = zope.schema.Set(
+  ...         title=u"Shown Fields",
+  ...         description=u"Fields shown in the table.",
+  ...         value_type=zope.schema.Choice(['name', 'size', 'creator']),
+  ...         default=set(['name', 'size']))
+  ...
+  ...     sortedBy = zope.schema.Choice(
+  ...         title=u"Sorted By",
+  ...         description=u"Data field to sort by.",
+  ...         values=['name', 'size', 'creator'],
+  ...         default='name')
+
+  >>> folderSettings = preference.PreferenceGroup(
+  ...     "ZMISettings.Folder",
+  ...     schema=IFolderSettings,
+  ...     title=u"Folder Content View Settings")
+
+Note that the id was chosen so that the parent id is the prefix of the child's
+id. Our new preference sub-group should now be available as an attribute or an
+item on the parent group ...
+
+  >>> settings.Folder
+  Traceback (most recent call last):
+  ...
+  AttributeError: 'Folder' is not a preference or sub-group.
+
+... but not before we register the groups as utilities:
+
+  >>> from zope.app.preference import interfaces
+  >>> from zope.app.testing import ztapi
+
+  >>> ztapi.provideUtility(interfaces.IPreferenceGroup, settings,
+  ...                      name='ZMISettings')
+  >>> ztapi.provideUtility(interfaces.IPreferenceGroup, folderSettings,
+  ...                      name='ZMISettings.Folder')
+
+If we now try to lookup the sub-group again, we should be successful:
+
+  >>> settings.Folder #doctest:+ELLIPSIS
+  <zope.app.preference.preference.PreferenceGroup object at ...>
+
+  >>> settings['Folder'] #doctest:+ELLIPSIS
+  <zope.app.preference.preference.PreferenceGroup object at ...>
+
+While the registry of the preference groups is flat, the careful naming of the
+ids allows us to have a tree of preferences. Note that this pattern is very
+similar to the way modules are handled in Python; they are stored in a flat
+dictionary in ``sys.modules``, but due to the naming they appear to be in a
+namespace tree.
+
+While we are at it, there are also preference categories that can be compared
+to Python packages. They basically are just a higher level grouping concept
+that is used by the UI to better organize the preferences. A preference group
+can be converted to a category by simply providing an additional interface:
+
+  >>> zope.interface.alsoProvides(settings, interfaces.IPreferenceCategory)
+
+  >>> interfaces.IPreferenceCategory.providedBy(settings)
+  True
+
+
+Default Preferences
+-------------------
+
+It sometimes desirable to define default settings on a site-by-site basis,
+instead of just using the default value from the schema. The preferences
+package provides a module
+ 
+  >>> from zope.app.preference import default
+
+that implements a default preferences provider that can be added as a unnamed
+utility for each site. So the first step is to create a site:
+  
+  >>> root = setup.buildSampleFolderTree()
+  >>> rsm = setup.createSiteManager(root, True)
+
+Now we can register the default preference provider with the root site:
+
+  >>> provider = setup.addUtility(rsm, '', 
+  ...                             interfaces.IDefaultPreferenceProvider, 
+  ...                             default.DefaultPreferenceProvider())
+
+So before we set an explicit default value for a preference, the schema field
+default is used:
+
+  >>> settings.Folder.sortedBy
+  'name'
+
+But if we now set a new default value with the provider,
+
+  >>> defaultFolder = provider.getDefaultPreferenceGroup('ZMISettings.Folder')
+  >>> defaultFolder.sortedBy = 'size'
+
+then the default of the setting changes:
+  
+  >>> settings.Folder.sortedBy
+  'size'
+
+The default preference providers also implicitly acquire default values from
+parent sites. So if we make `folder1` a site and set it as the active site
+
+  >>> folder1 = root['folder1']
+  >>> sm1 = setup.createSiteManager(folder1, True)
+
+and add a default provider there,
+
+  >>> provider1 = setup.addUtility(sm1, '', 
+  ...                              interfaces.IDefaultPreferenceProvider, 
+  ...                              default.DefaultPreferenceProvider())
+
+then we still get the root's default values, because we have not defined any
+in the higher default provider:
+
+  >>> settings.Folder.sortedBy
+  'size'
+
+But if we provide the new provider with a default value for `sortedBy`,
+
+  >>> defaultFolder1 = provider1.getDefaultPreferenceGroup('ZMISettings.Folder')
+  >>> defaultFolder1.sortedBy = 'creator'
+
+then it is used instead:
+
+  >>> settings.Folder.sortedBy
+  'creator'
+
+Of course, once the root site becomes our active site again
+
+  >>> zope.app.component.hooks.setSite(root)
+
+the default value of the root provider is used:
+
+  >>> settings.Folder.sortedBy
+  'size'
+
+Of course, all the defaults in the world are not relevant anymore as soon as
+the user actually provides a value:
+
+  >>> settings.Folder.sortedBy = 'name'
+  >>> settings.Folder.sortedBy
+  'name'
+
+Oh, and have I mentioned that entered values are always validated? So you
+cannot just assign any old value:
+
+  >>> settings.Folder.sortedBy = 'foo'
+  Traceback (most recent call last):
+  ...
+  ConstraintNotSatisfied: foo
+
+Finally, if the user deletes his/her explicit setting, we are back to the
+default value:
+
+  >>> del settings.Folder.sortedBy
+  >>> settings.Folder.sortedBy
+  'size'
+
+
+Creating Preference Groups Using ZCML
+-------------------------------------
+
+If you are using the user preference system in Zope 3, you will not have to
+manually setup the preference groups as we did above (of course). We will use
+ZCML instead. First, we need to register the directives:
+
+  >>> from zope.configuration import xmlconfig
+  >>> import zope.app.preference
+  >>> context = xmlconfig.file('meta.zcml', zope.app.preference)
+
+Then the system sets up a root preference group:
+
+  >>> context = xmlconfig.string('''
+  ...     <configure
+  ...         xmlns="http://namespaces.zope.org/zope"
+  ...         i18n_domain="test">
+  ...
+  ...       <preferenceGroup
+  ...           id=""
+  ...           title="User Preferences" 
+  ...           />
+  ...
+  ...     </configure>''', context)
+
+Now we can use the preference system in its intended way. We access the folder
+settings as follows:
+
+  >>> import zope.component
+  >>> prefs = zope.component.getUtility(interfaces.IPreferenceGroup)
+  >>> prefs.ZMISettings.Folder.sortedBy
+  'size'
+
+Let's register the ZMI settings again under a new name via ZCML:
+
+  >>> context = xmlconfig.string('''
+  ...     <configure
+  ...         xmlns="http://namespaces.zope.org/zope"
+  ...         i18n_domain="test">
+  ...
+  ...       <preferenceGroup
+  ...           id="ZMISettings2"
+  ...           title="ZMI Settings NG"
+  ...           schema="zope.app.preference.README.IZMIUserSettings"
+  ...           category="true"
+  ...           />
+  ...
+  ...     </configure>''', context)
+
+  >>> prefs.ZMISettings2 #doctest:+ELLIPSIS
+  <zope.app.preference.preference.PreferenceGroup object at ...>
+
+  >>> prefs.ZMISettings2.__title__
+  u'ZMI Settings NG'
+
+  >>> IZMIUserSettings.providedBy(prefs.ZMISettings2)
+  True
+  >>> interfaces.IPreferenceCategory.providedBy(prefs.ZMISettings2)
+  True
+
+And the tree can built again by carefully constructing the id:
+
+  >>> context = xmlconfig.string('''
+  ...     <configure
+  ...         xmlns="http://namespaces.zope.org/zope"
+  ...         i18n_domain="test">
+  ...
+  ...       <preferenceGroup
+  ...           id="ZMISettings2.Folder"
+  ...           title="Folder Settings"
+  ...           schema="zope.app.preference.README.IFolderSettings"
+  ...           />
+  ...
+  ...     </configure>''', context)
+
+  >>> prefs.ZMISettings2 #doctest:+ELLIPSIS
+  <zope.app.preference.preference.PreferenceGroup object at ...>
+
+  >>> prefs.ZMISettings2.Folder.__title__
+  u'Folder Settings'
+
+  >>> IFolderSettings.providedBy(prefs.ZMISettings2.Folder)
+  True
+  >>> interfaces.IPreferenceCategory.providedBy(prefs.ZMISettings2.Folder)
+  False
+
+
+Simple Python-Level Access
+--------------------------
+
+If a site is set, getting the user preferences is very simple:
+
+  >>> from zope.app.preference import UserPreferences
+  >>> prefs2 = UserPreferences()
+  >>> prefs2.ZMISettings.Folder.sortedBy
+  'size'
+
+This function is also commonly registered as an adapter,
+
+  >>> from zope.location.interfaces import ILocation
+  >>> ztapi.provideAdapter(ILocation, interfaces.IUserPreferences, 
+  ...                      UserPreferences)
+
+so that you can adapt any location to the user preferences:
+
+  >>> prefs3 = interfaces.IUserPreferences(folder1)
+  >>> prefs3.ZMISettings.Folder.sortedBy
+  'creator'
+
+
+Traversal
+---------
+
+Okay, so all these objects are nice, but they do not make it any easier to
+access the preferences in page templates. Thus, a special traversal namespace
+has been created that makes it very simple to access the preferences via a
+traversal path. But before we can use the path expressions, we have to
+register all necessary traversal components and the special `preferences`
+namespace:
+
+  >>> import zope.traversing.interfaces
+  >>> ztapi.provideAdapter(None,
+  ...                      zope.traversing.interfaces.ITraversable,
+  ...                      preference.preferencesNamespace,
+  ...                      'preferences')
+
+We can now access the preferences as follows:
+
+  >>> from zope.traversing.api import traverse
+  >>> traverse(None, '++preferences++ZMISettings/skin')
+  'Basic'
+  >>> traverse(None, '++preferences++/ZMISettings/skin')
+  'Basic'
+
+
+Security
+--------
+
+You might already wonder under which permissions the preferences are
+available. They are actually available publicly (`CheckerPublic`), but that
+is not a problem, since the available values are looked up specifically for
+the current user. And why should a user not have full access to his/her
+preferences? 
+
+Let's create a checker using the function that the security machinery is
+actually using:
+
+  >>> checker = preference.PreferenceGroupChecker(settings)
+  >>> checker.permission_id('skin')
+  Global(CheckerPublic,zope.security.checker)
+  >>> checker.setattr_permission_id('skin')
+  Global(CheckerPublic,zope.security.checker)
+
+The id, title, description, and schema are publicly available for access,
+but are not available for mutation at all:
+
+  >>> checker.permission_id('__id__')
+  Global(CheckerPublic,zope.security.checker)
+  >>> checker.setattr_permission_id('__id__') is None
+  True
+
+
+The only way security could be compromised is when one could override the
+annotations property. However, this property is not available for public
+consumption at all, including read access:
+
+  >>> checker.permission_id('annotation') is None
+  True
+  >>> checker.setattr_permission_id('annotation') is None
+  True

Deleted: zope.app.preference/tags/3.5.0/src/zope/app/preference/SETUP.cfg
===================================================================
--- zope.app.preference/trunk/src/zope/app/preference/SETUP.cfg	2009-01-17 13:10:51 UTC (rev 94790)
+++ zope.app.preference/tags/3.5.0/src/zope/app/preference/SETUP.cfg	2009-01-17 13:36:57 UTC (rev 94793)
@@ -1,5 +0,0 @@
-# Tell zpkg how to install the ZCML slugs.
-
-<data-files zopeskel/etc/package-includes>
-  preference-*.zcml
-</data-files>

Deleted: zope.app.preference/tags/3.5.0/src/zope/app/preference/preference-configure.zcml
===================================================================
--- zope.app.preference/trunk/src/zope/app/preference/preference-configure.zcml	2009-01-17 13:10:51 UTC (rev 94790)
+++ zope.app.preference/tags/3.5.0/src/zope/app/preference/preference-configure.zcml	2009-01-17 13:36:57 UTC (rev 94793)
@@ -1 +0,0 @@
-<include package="zope.app.preference" />

Deleted: zope.app.preference/tags/3.5.0/src/zope/app/preference/preference-meta.zcml
===================================================================
--- zope.app.preference/trunk/src/zope/app/preference/preference-meta.zcml	2009-01-17 13:10:51 UTC (rev 94790)
+++ zope.app.preference/tags/3.5.0/src/zope/app/preference/preference-meta.zcml	2009-01-17 13:36:57 UTC (rev 94793)
@@ -1 +0,0 @@
-<include package="zope.app.preference" file="meta.zcml" />



More information about the Checkins mailing list