[Checkins] SVN: z3ext.layout/tags/2.2.1/ release tag

Nikolay Kim fafhrd91 at gmail.com
Tue Aug 11 04:26:55 EDT 2009


Log message for revision 102645:
  release tag

Changed:
  A   z3ext.layout/tags/2.2.1/
  D   z3ext.layout/tags/2.2.1/CHANGES.txt
  A   z3ext.layout/tags/2.2.1/CHANGES.txt
  D   z3ext.layout/tags/2.2.1/bootstrap.py
  A   z3ext.layout/tags/2.2.1/bootstrap.py
  D   z3ext.layout/tags/2.2.1/setup.py
  A   z3ext.layout/tags/2.2.1/setup.py
  D   z3ext.layout/tags/2.2.1/src/z3ext/layout/interfaces.py
  A   z3ext.layout/tags/2.2.1/src/z3ext/layout/interfaces.py
  D   z3ext.layout/tags/2.2.1/src/z3ext/layout/layout.py
  A   z3ext.layout/tags/2.2.1/src/z3ext/layout/layout.py
  D   z3ext.layout/tags/2.2.1/src/z3ext/layout/pagelet.py
  A   z3ext.layout/tags/2.2.1/src/z3ext/layout/pagelet.py
  D   z3ext.layout/tags/2.2.1/src/z3ext/layout/tales.py
  A   z3ext.layout/tags/2.2.1/src/z3ext/layout/tales.py
  D   z3ext.layout/tags/2.2.1/src/z3ext/layout/tests.py
  A   z3ext.layout/tags/2.2.1/src/z3ext/layout/tests.py
  D   z3ext.layout/tags/2.2.1/src/z3ext/layout/zcml.py
  A   z3ext.layout/tags/2.2.1/src/z3ext/layout/zcml.py

-=-
Deleted: z3ext.layout/tags/2.2.1/CHANGES.txt
===================================================================
--- z3ext.layout/trunk/CHANGES.txt	2009-08-10 17:22:44 UTC (rev 102631)
+++ z3ext.layout/tags/2.2.1/CHANGES.txt	2009-08-11 08:26:54 UTC (rev 102645)
@@ -1,311 +0,0 @@
-=======
-CHANGES
-=======
-
-2.2.1 (Unreleased)
-------------------
-
-- Update styles
-
-
-2.2.0 (2009-07-14)
------------------
-
-- Use chameleon for pagelets and layouts
-
-- Added 'pagelet' chameleon expression
-
-- Added 'queryPagelet' helper function
-
-- Do not use metal in default layouts
-
-- Use '+' for named pagelet instead of ';'
-
-
-2.1.0 (2009-06-20)
-------------------
-
-- Allow use interface as type for z3ext:pagelet directive
-
-- Allow use named typed pagelets with '@@pagelet' view and 'pagelet:' tales
-
-- Added 'pageletObject' view, it doesn't call pagelet render method
-
-
-2.0.8 (2009-06-03)
-------------------
-
-- Fixed next layout calculation for root object
-
-
-2.0.7 (2009-04-15)
-------------------
-
-- Do not use z3c.autoinclude
-
-
-2.0.6 (2009-03-11)
-------------------
-
-- Fixed discriminator for z3ext:pagelet directive
-
-- Allow use 'layout' pagelet type as template for layout
-
-- Update styles
-
-
-2.0.5 (2009-01-26)
-------------------
-
-- Update styles
-
-
-2.0.4 (2009-01-22)
-------------------
-
-- Pass permission to class required attributes
-
-
-2.0.3 (2009-01-20)
-------------------
-
-- Use __parent__ for layout quering
-
-
-2.0.2 (2009-01-08)
-------------------
-
-- Register layout for (view, for, layer), instead of view and for separatly
-
-
-2.0.1 (2008-12-25)
-------------------
-
-- Pagelet should implement provided interfaces
-
-
-2.0.0 (2008-12-22)
-------------------
-
-- Pagelet without name is not allowed
-
-- Added 'type' attribute to 'z3ext:pagelet'
-
-- Added 'z3ext:pageletType' directive for registering new pagelet types
-
-- multiple params is allowed for 'for' attribute
-
-- Removed pagelet 'manager' attribute
-
-- 'pagelet' tales expression and 'pagelet' view checks additional context IPageletContext
-  if exists use it as adapter parameter
-
-
-1.7.3 (2008-12-18)
-------------------
-
-- Use IPagelet instead of IPageTemplate for pagelet rendering
-
-
-1.7.2 (2008-12-17)
-------------------
-
-- Update default styles
-
-
-1.7.1 (2008-12-15)
-------------------
-
-- Check if context provides interface in @@pagelet view and pagelet: tales expresion
-
-
-1.7.0 (2008-12-11)
-------------------
-
-- Added `manager` attribute to z3ext:pagelet directive
-  this allow use getMultiAdapter((content, request, manager1, manager2, ...), IPagelet)
-
-- Use 'provides' schema for converting kwargs in z3ext:pagelet directive
-
-
-1.6.0 (2008-11-27)
-------------------
-
-- Added 'uid' attribute to z3ext:layout directive.
-  Send ILayoutCreatedEvent event only if layout has uid
-
-
-1.5.9 (2008-11-24)
-------------------
-
-- Fixed python2.4 compatibility
-
-
-1.5.7 (2008-11-17)
-------------------
-
-- Update css styles
-
-
-1.5.6 (2008-11-06)
-------------------
-
-- Register nameless pagelet only if provided interface is not
-inherited from IBrowserPublisher
-
-
-1.5.5 (2008-11-05)
-------------------
-
-- Add IPagelet interface to pagelet provides
-
-
-1.5.4 (2008-10-30)
-------------------
-
-- Added 'pagelet' tales expression (same as @@pagelet)
-
-- Update css styles
-
-
-1.5.3 (2008-10-16)
-------------------
-
-- Update css styles
-
-
-1.5.2 (2008-10-15)
-------------------
-
-- Render IPagelet adapter for @@pagelet view
-
-
-1.5.1 (2008-10-14)
-------------------
-
-- Fixed missing NotFount in @@pagelet 
-
-- Log errors in @@pagelet
-
-- Default css styles
-
-
-1.5.0 (2008-10-06)
-------------------
-
-- Added @@pagelet browser view for fast access pagelets
-
-
-1.4.6 (2008-10-03)
-------------------
-
-- Fixed bug with multple nameless pagelet
-
-
-1.4.5 (2008-08-18)
-------------------
-
-- `name` attribute is optional for <z3ext:pagelet/> directive
-
-
-1.4.4 (2008-07-22)
-------------------
-
-- Fix IPagelet adapter for content
-
-
-1.4.3 (2008-05-22)
-------------------
-
-- Added LayoutNotFound exception
-
-
-1.4.2 (2008-05-14)
-------------------
-
-- Remove unused interfaces
-
-- Tests updated
-
-
-1.4.1 (2008-04-23)
-------------------
-
-- Use newer version of z3ext.autoinclude
-
-
-1.4 (2008-03-21)
-----------------
-
-- Added z3ext:pagelet directive
-
-- Code cleanup
-
-- Moved to svn.zope.org
-
-
-1.3.2 (2008-03-06)
-------------------
-
-- Removed context layouts
-
-
-1.3.1 (2008-02-21)
-------------------
-
-- Code cleanup
-
-- Remove code related to zope.formlib
-
-
-1.3.0 (2008-02-20)
-------------------
-
-- Removed code related to z3c.form
-
-
-1.2.1 (2008-02-18)
-------------------
-
-- Added 'redirect' method to IBrowserPagelet, this is usefull
-  when we need redirect during 'update' method and we don't 
-  need render pagelet at all.
-
-- Added adapter to IPagelet for (context, request),
-  this adapter gets browser:defaultView for context and if it IPagelet return it
-
-
-1.2.0 (2008-02-13)
-------------------
-
-- Remove all code related to persistent templates
-
-
-1.1.2 (2008-02-12)
-------------------
-
-- Added 'title' and 'description' fields layout directive
-
-- check ILayoutTemplateTAL for ISite
-
-
-1.1.0 (2008-02-08)
-------------------
-
-- Added compatibility with z3c.template layouts
-
-- Added ILayoutTemplateTAL interface, other packages
-  can define adapter to this interface and change layout template
-  TAL program (layout customization)
-
-
-1.0.1 (2008-02-02)
-------------------
-
-- Added required dependencies
-
-
-1.0.0 (2008-01-15)
-------------------
-
-- Initial release

Copied: z3ext.layout/tags/2.2.1/CHANGES.txt (from rev 102644, z3ext.layout/trunk/CHANGES.txt)
===================================================================
--- z3ext.layout/tags/2.2.1/CHANGES.txt	                        (rev 0)
+++ z3ext.layout/tags/2.2.1/CHANGES.txt	2009-08-11 08:26:54 UTC (rev 102645)
@@ -0,0 +1,313 @@
+=======
+CHANGES
+=======
+
+2.2.1 (2009-08-11)
+------------------
+
+- Update styles
+
+- Copyright changed to 'Zope Foundation and Contributors'
+
+
+2.2.0 (2009-07-14)
+-----------------
+
+- Use chameleon for pagelets and layouts
+
+- Added 'pagelet' chameleon expression
+
+- Added 'queryPagelet' helper function
+
+- Do not use metal in default layouts
+
+- Use '+' for named pagelet instead of ';'
+
+
+2.1.0 (2009-06-20)
+------------------
+
+- Allow use interface as type for z3ext:pagelet directive
+
+- Allow use named typed pagelets with '@@pagelet' view and 'pagelet:' tales
+
+- Added 'pageletObject' view, it doesn't call pagelet render method
+
+
+2.0.8 (2009-06-03)
+------------------
+
+- Fixed next layout calculation for root object
+
+
+2.0.7 (2009-04-15)
+------------------
+
+- Do not use z3c.autoinclude
+
+
+2.0.6 (2009-03-11)
+------------------
+
+- Fixed discriminator for z3ext:pagelet directive
+
+- Allow use 'layout' pagelet type as template for layout
+
+- Update styles
+
+
+2.0.5 (2009-01-26)
+------------------
+
+- Update styles
+
+
+2.0.4 (2009-01-22)
+------------------
+
+- Pass permission to class required attributes
+
+
+2.0.3 (2009-01-20)
+------------------
+
+- Use __parent__ for layout quering
+
+
+2.0.2 (2009-01-08)
+------------------
+
+- Register layout for (view, for, layer), instead of view and for separatly
+
+
+2.0.1 (2008-12-25)
+------------------
+
+- Pagelet should implement provided interfaces
+
+
+2.0.0 (2008-12-22)
+------------------
+
+- Pagelet without name is not allowed
+
+- Added 'type' attribute to 'z3ext:pagelet'
+
+- Added 'z3ext:pageletType' directive for registering new pagelet types
+
+- multiple params is allowed for 'for' attribute
+
+- Removed pagelet 'manager' attribute
+
+- 'pagelet' tales expression and 'pagelet' view checks additional context IPageletContext
+  if exists use it as adapter parameter
+
+
+1.7.3 (2008-12-18)
+------------------
+
+- Use IPagelet instead of IPageTemplate for pagelet rendering
+
+
+1.7.2 (2008-12-17)
+------------------
+
+- Update default styles
+
+
+1.7.1 (2008-12-15)
+------------------
+
+- Check if context provides interface in @@pagelet view and pagelet: tales expresion
+
+
+1.7.0 (2008-12-11)
+------------------
+
+- Added `manager` attribute to z3ext:pagelet directive
+  this allow use getMultiAdapter((content, request, manager1, manager2, ...), IPagelet)
+
+- Use 'provides' schema for converting kwargs in z3ext:pagelet directive
+
+
+1.6.0 (2008-11-27)
+------------------
+
+- Added 'uid' attribute to z3ext:layout directive.
+  Send ILayoutCreatedEvent event only if layout has uid
+
+
+1.5.9 (2008-11-24)
+------------------
+
+- Fixed python2.4 compatibility
+
+
+1.5.7 (2008-11-17)
+------------------
+
+- Update css styles
+
+
+1.5.6 (2008-11-06)
+------------------
+
+- Register nameless pagelet only if provided interface is not
+inherited from IBrowserPublisher
+
+
+1.5.5 (2008-11-05)
+------------------
+
+- Add IPagelet interface to pagelet provides
+
+
+1.5.4 (2008-10-30)
+------------------
+
+- Added 'pagelet' tales expression (same as @@pagelet)
+
+- Update css styles
+
+
+1.5.3 (2008-10-16)
+------------------
+
+- Update css styles
+
+
+1.5.2 (2008-10-15)
+------------------
+
+- Render IPagelet adapter for @@pagelet view
+
+
+1.5.1 (2008-10-14)
+------------------
+
+- Fixed missing NotFount in @@pagelet 
+
+- Log errors in @@pagelet
+
+- Default css styles
+
+
+1.5.0 (2008-10-06)
+------------------
+
+- Added @@pagelet browser view for fast access pagelets
+
+
+1.4.6 (2008-10-03)
+------------------
+
+- Fixed bug with multple nameless pagelet
+
+
+1.4.5 (2008-08-18)
+------------------
+
+- `name` attribute is optional for <z3ext:pagelet/> directive
+
+
+1.4.4 (2008-07-22)
+------------------
+
+- Fix IPagelet adapter for content
+
+
+1.4.3 (2008-05-22)
+------------------
+
+- Added LayoutNotFound exception
+
+
+1.4.2 (2008-05-14)
+------------------
+
+- Remove unused interfaces
+
+- Tests updated
+
+
+1.4.1 (2008-04-23)
+------------------
+
+- Use newer version of z3ext.autoinclude
+
+
+1.4 (2008-03-21)
+----------------
+
+- Added z3ext:pagelet directive
+
+- Code cleanup
+
+- Moved to svn.zope.org
+
+
+1.3.2 (2008-03-06)
+------------------
+
+- Removed context layouts
+
+
+1.3.1 (2008-02-21)
+------------------
+
+- Code cleanup
+
+- Remove code related to zope.formlib
+
+
+1.3.0 (2008-02-20)
+------------------
+
+- Removed code related to z3c.form
+
+
+1.2.1 (2008-02-18)
+------------------
+
+- Added 'redirect' method to IBrowserPagelet, this is usefull
+  when we need redirect during 'update' method and we don't 
+  need render pagelet at all.
+
+- Added adapter to IPagelet for (context, request),
+  this adapter gets browser:defaultView for context and if it IPagelet return it
+
+
+1.2.0 (2008-02-13)
+------------------
+
+- Remove all code related to persistent templates
+
+
+1.1.2 (2008-02-12)
+------------------
+
+- Added 'title' and 'description' fields layout directive
+
+- check ILayoutTemplateTAL for ISite
+
+
+1.1.0 (2008-02-08)
+------------------
+
+- Added compatibility with z3c.template layouts
+
+- Added ILayoutTemplateTAL interface, other packages
+  can define adapter to this interface and change layout template
+  TAL program (layout customization)
+
+
+1.0.1 (2008-02-02)
+------------------
+
+- Added required dependencies
+
+
+1.0.0 (2008-01-15)
+------------------
+
+- Initial release

Deleted: z3ext.layout/tags/2.2.1/bootstrap.py
===================================================================
--- z3ext.layout/trunk/bootstrap.py	2009-08-10 17:22:44 UTC (rev 102631)
+++ z3ext.layout/tags/2.2.1/bootstrap.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -1,52 +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.
-#
-##############################################################################
-"""Bootstrap a buildout-based project
-
-Simply run this script in a directory containing a buildout.cfg.
-The script accepts buildout command-line options, so you can
-use the -c option to specify an alternate configuration file.
-
-$Id$
-"""
-
-import os, shutil, sys, tempfile, urllib2
-
-tmpeggs = tempfile.mkdtemp()
-
-ez = {}
-exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
-                     ).read() in ez
-ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
-
-import pkg_resources
-
-cmd = 'from setuptools.command.easy_install import main; main()'
-if sys.platform == 'win32':
-    cmd = '"%s"' % cmd # work around spawn lamosity on windows
-
-ws = pkg_resources.working_set
-assert os.spawnle(
-    os.P_WAIT, sys.executable, sys.executable,
-    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
-    dict(os.environ,
-         PYTHONPATH=
-         ws.find(pkg_resources.Requirement.parse('setuptools')).location
-         ),
-    ) == 0
-
-ws.add_entry(tmpeggs)
-ws.require('zc.buildout')
-import zc.buildout.buildout
-zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
-shutil.rmtree(tmpeggs)

Copied: z3ext.layout/tags/2.2.1/bootstrap.py (from rev 102644, z3ext.layout/trunk/bootstrap.py)
===================================================================
--- z3ext.layout/tags/2.2.1/bootstrap.py	                        (rev 0)
+++ z3ext.layout/tags/2.2.1/bootstrap.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -0,0 +1,52 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Foundation 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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+ez = {}
+exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                     ).read() in ez
+ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+    cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, sys.executable,
+    '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)

Deleted: z3ext.layout/tags/2.2.1/setup.py
===================================================================
--- z3ext.layout/trunk/setup.py	2009-08-10 17:22:44 UTC (rev 102631)
+++ z3ext.layout/tags/2.2.1/setup.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -1,76 +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.
-#
-##############################################################################
-"""Setup for z3ext.layout package
-
-$Id$
-"""
-import sys, os
-from setuptools import setup, find_packages
-
-def read(*rnames):
-    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-
-version='2.2.1dev'
-
-
-setup(name='z3ext.layout',
-      version=version,
-      description="A package implementing advanced Page Template patterns.",
-      long_description=(
-          'Detailed Documentation\n' +
-          '======================\n'
-          + '\n\n' +
-          read('src', 'z3ext', 'layout', 'README.txt')
-          + '\n\n' +
-          read('CHANGES.txt')
-          ),
-      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'],
-      author='Nikolay Kim',
-      author_email='fafhrd91 at gmail.com',
-      url='http://z3ext.net/',
-      license='ZPL 2.1',
-      packages=find_packages('src'),
-      package_dir = {'':'src'},
-      namespace_packages=['z3ext'],
-      install_requires = ['setuptools',
-                          'zope.event',
-                          'zope.schema',
-                          'zope.component',
-                          'zope.interface',
-                          'zope.security',
-                          'zope.publisher',
-                          'zope.configuration',
-                          'zope.pagetemplate',
-                          'zope.tales',
-                          'zope.app.component',
-                          'zope.app.publisher',
-                          'zope.app.pagetemplate',
-                          'z3c.pt',
-                          ],
-      extras_require = dict(test=['zope.app.container',
-                                  'zope.app.testing',
-                                  'zope.testing',
-                                  ]),
-      include_package_data = True,
-      zip_safe = False
-      )

Copied: z3ext.layout/tags/2.2.1/setup.py (from rev 102644, z3ext.layout/trunk/setup.py)
===================================================================
--- z3ext.layout/tags/2.2.1/setup.py	                        (rev 0)
+++ z3ext.layout/tags/2.2.1/setup.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -0,0 +1,76 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation 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 z3ext.layout package
+
+$Id$
+"""
+import sys, os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+version='2.2.1'
+
+
+setup(name='z3ext.layout',
+      version=version,
+      description="A package implementing advanced Page Template patterns.",
+      long_description=(
+          'Detailed Documentation\n' +
+          '======================\n'
+          + '\n\n' +
+          read('src', 'z3ext', 'layout', 'README.txt')
+          + '\n\n' +
+          read('CHANGES.txt')
+          ),
+      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'],
+      author='Nikolay Kim',
+      author_email='fafhrd91 at gmail.com',
+      url='http://z3ext.net/',
+      license='ZPL 2.1',
+      packages=find_packages('src'),
+      package_dir = {'':'src'},
+      namespace_packages=['z3ext'],
+      install_requires = ['setuptools',
+                          'zope.event',
+                          'zope.schema',
+                          'zope.component',
+                          'zope.interface',
+                          'zope.security',
+                          'zope.publisher',
+                          'zope.configuration',
+                          'zope.pagetemplate',
+                          'zope.tales',
+                          'zope.app.component',
+                          'zope.app.publisher',
+                          'zope.app.pagetemplate',
+                          'z3c.pt',
+                          ],
+      extras_require = dict(test=['zope.app.container',
+                                  'zope.app.testing',
+                                  'zope.testing',
+                                  ]),
+      include_package_data = True,
+      zip_safe = False
+      )

Deleted: z3ext.layout/tags/2.2.1/src/z3ext/layout/interfaces.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/interfaces.py	2009-08-10 17:22:44 UTC (rev 102631)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/interfaces.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -1,100 +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.
-#
-##############################################################################
-""" z3ext.layout interfaces
-
-$Id$
-"""
-from zope import interface
-from zope.publisher.interfaces.browser import IBrowserPage
-
-
-class LayoutNotFound(LookupError):
-    """ Layout not found exception """
-
-
-class IPagelet(interface.Interface):
-    """ pagelet """
-
-    context = interface.Attribute('Context')
-
-    contexts = interface.Attribute('Additional contexts')
-
-    isRedirected = interface.Attribute('is redirected')
-
-    def redirect(url=''):
-        """Redirect URL, if `update` method needs redirect,
-        it should call `redirect` method, __call__ method should
-        check isRendered before render or layout."""
-
-    def update():
-        """Update the pagelet data."""
-
-    def render():
-        """Render the pagelet content w/o o-wrap."""
-
-    def updateAndRender():
-        """Update pagelet and render. Prefered way to render pagelet."""
-
-    def isAvailable():
-        """Is available"""
-
-
-class IPageletType(interface.interfaces.IInterface):
-    """ pagelet interface type """
-
-
-class IPageletContext(interface.Interface):
-    """ pagelet contexts """
-
-
-class ILayout(IBrowserPage):
-    """ layout """
-
-    title = interface.Attribute('Layout title')
-
-    description = interface.Attribute('Layout description')
-
-    template = interface.Attribute('Layout template')
-
-    def update():
-        """Update the layout data """
-
-    def render():
-        """Render the layout """
-
-
-class ILayoutView(interface.Interface):
-    """ layout view """
-
-
-class ILayoutTemplateFile(interface.Interface):
-    """ layout template file """
-
-
-class ILayoutCreatedEvent(interface.Interface):
-    """ notification about new layout """
-
-    uid = interface.Attribute('UID')
-
-    name = interface.Attribute('Name')
-
-    view = interface.Attribute('View')
-
-    context = interface.Attribute('Context')
-
-    layer = interface.Attribute('Layer')
-
-    layoutclass = interface.Attribute('Generated class for layout')
-
-    keywords = interface.Attribute('Keywords')

Copied: z3ext.layout/tags/2.2.1/src/z3ext/layout/interfaces.py (from rev 102644, z3ext.layout/trunk/src/z3ext/layout/interfaces.py)
===================================================================
--- z3ext.layout/tags/2.2.1/src/z3ext/layout/interfaces.py	                        (rev 0)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/interfaces.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -0,0 +1,100 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation 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.
+#
+##############################################################################
+""" z3ext.layout interfaces
+
+$Id$
+"""
+from zope import interface
+from zope.publisher.interfaces.browser import IBrowserPage
+
+
+class LayoutNotFound(LookupError):
+    """ Layout not found exception """
+
+
+class IPagelet(interface.Interface):
+    """ pagelet """
+
+    context = interface.Attribute('Context')
+
+    contexts = interface.Attribute('Additional contexts')
+
+    isRedirected = interface.Attribute('is redirected')
+
+    def redirect(url=''):
+        """Redirect URL, if `update` method needs redirect,
+        it should call `redirect` method, __call__ method should
+        check isRendered before render or layout."""
+
+    def update():
+        """Update the pagelet data."""
+
+    def render():
+        """Render the pagelet content w/o o-wrap."""
+
+    def updateAndRender():
+        """Update pagelet and render. Prefered way to render pagelet."""
+
+    def isAvailable():
+        """Is available"""
+
+
+class IPageletType(interface.interfaces.IInterface):
+    """ pagelet interface type """
+
+
+class IPageletContext(interface.Interface):
+    """ pagelet contexts """
+
+
+class ILayout(IBrowserPage):
+    """ layout """
+
+    title = interface.Attribute('Layout title')
+
+    description = interface.Attribute('Layout description')
+
+    template = interface.Attribute('Layout template')
+
+    def update():
+        """Update the layout data """
+
+    def render():
+        """Render the layout """
+
+
+class ILayoutView(interface.Interface):
+    """ layout view """
+
+
+class ILayoutTemplateFile(interface.Interface):
+    """ layout template file """
+
+
+class ILayoutCreatedEvent(interface.Interface):
+    """ notification about new layout """
+
+    uid = interface.Attribute('UID')
+
+    name = interface.Attribute('Name')
+
+    view = interface.Attribute('View')
+
+    context = interface.Attribute('Context')
+
+    layer = interface.Attribute('Layer')
+
+    layoutclass = interface.Attribute('Generated class for layout')
+
+    keywords = interface.Attribute('Keywords')

Deleted: z3ext.layout/tags/2.2.1/src/z3ext/layout/layout.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/layout.py	2009-08-10 17:22:44 UTC (rev 102631)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/layout.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -1,112 +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.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-from zope import interface
-from zope.publisher import browser
-from zope.component import getMultiAdapter
-from zope.traversing.api import getRoot
-
-from z3c.pt.pagetemplate import ViewPageTemplateFile
-
-from z3ext.layout.pagelet import queryLayout
-from z3ext.layout.interfaces import LayoutNotFound
-from z3ext.layout.interfaces import ILayout, ILayoutView, ILayoutTemplateFile
-
-
-class LayoutTemplateFile(ViewPageTemplateFile):
-    interface.implements(ILayoutTemplateFile)
-
-    def _pt_get_context(self, layout, request, kwargs):
-        view = layout.view
-
-        namespace = super(LayoutTemplateFile, self)._pt_get_context(
-            view, request, kwargs)
-
-        namespace['layout'] = layout
-        namespace['layoutcontext'] = layout.context
-        namespace['mainview'] = layout.mainview
-        namespace['maincontext'] = layout.maincontext
-        return namespace
-
-
-class Layout(browser.BrowserPage):
-    interface.implements(ILayout)
-
-    template = None
-    mainview = None
-    maincontext = None
-
-    def __init__(self, view, context, request):
-        self.view = view
-        self.context = context
-        self.request = request
-
-        self.__parent__ = view.__parent__
-
-    def update(self):
-        pass
-
-    def render(self):
-        if self.template is None:
-            view = getMultiAdapter((self, self.request), ILayoutView)
-            view.update()
-            return view.render()
-
-        return self.template(
-            self, context=self.view.context, request=self.request)
-
-    def __call__(self, layout=None, view=None, *args, **kw):
-        if view is None:
-            view = self.view
-        self.mainview = view
-        self.maincontext = view.context
-
-        layoutview = self.view
-        if layout is not None:
-            self.view = layout
-
-        self.update()
-
-        if self.layout is None:
-            return self.render()
-
-        if self.__name__ != self.layout:
-            layout = queryLayout(
-                view, self.request, view.__parent__, name=self.layout)
-            if layout is not None:
-                return layout(layout=self, view=view, *args, **kw)
-        else:
-            context = self.context
-            if layoutview.context is not context.__parent__:
-                context = context.__parent__
-            else:
-                context = getattr(context.__parent__, '__parent__', None)
-
-            if context is None:
-                context = getRoot(self.context)
-
-            layout = queryLayout(self, self.request, context, name=self.layout)
-            if layout is not None:
-                return layout(view=view, *args, **kw)
-
-        layout = queryLayout(
-            self.view, self.context, self.request, name=self.layout)
-
-        if layout is not None:
-            return layout(*args, **kw)
-
-        raise LayoutNotFound(self.layout)

Copied: z3ext.layout/tags/2.2.1/src/z3ext/layout/layout.py (from rev 102644, z3ext.layout/trunk/src/z3ext/layout/layout.py)
===================================================================
--- z3ext.layout/tags/2.2.1/src/z3ext/layout/layout.py	                        (rev 0)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/layout.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -0,0 +1,112 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+from zope import interface
+from zope.publisher import browser
+from zope.component import getMultiAdapter
+from zope.traversing.api import getRoot
+
+from z3c.pt.pagetemplate import ViewPageTemplateFile
+
+from z3ext.layout.pagelet import queryLayout
+from z3ext.layout.interfaces import LayoutNotFound
+from z3ext.layout.interfaces import ILayout, ILayoutView, ILayoutTemplateFile
+
+
+class LayoutTemplateFile(ViewPageTemplateFile):
+    interface.implements(ILayoutTemplateFile)
+
+    def _pt_get_context(self, layout, request, kwargs):
+        view = layout.view
+
+        namespace = super(LayoutTemplateFile, self)._pt_get_context(
+            view, request, kwargs)
+
+        namespace['layout'] = layout
+        namespace['layoutcontext'] = layout.context
+        namespace['mainview'] = layout.mainview
+        namespace['maincontext'] = layout.maincontext
+        return namespace
+
+
+class Layout(browser.BrowserPage):
+    interface.implements(ILayout)
+
+    template = None
+    mainview = None
+    maincontext = None
+
+    def __init__(self, view, context, request):
+        self.view = view
+        self.context = context
+        self.request = request
+
+        self.__parent__ = view.__parent__
+
+    def update(self):
+        pass
+
+    def render(self):
+        if self.template is None:
+            view = getMultiAdapter((self, self.request), ILayoutView)
+            view.update()
+            return view.render()
+
+        return self.template(
+            self, context=self.view.context, request=self.request)
+
+    def __call__(self, layout=None, view=None, *args, **kw):
+        if view is None:
+            view = self.view
+        self.mainview = view
+        self.maincontext = view.context
+
+        layoutview = self.view
+        if layout is not None:
+            self.view = layout
+
+        self.update()
+
+        if self.layout is None:
+            return self.render()
+
+        if self.__name__ != self.layout:
+            layout = queryLayout(
+                view, self.request, view.__parent__, name=self.layout)
+            if layout is not None:
+                return layout(layout=self, view=view, *args, **kw)
+        else:
+            context = self.context
+            if layoutview.context is not context.__parent__:
+                context = context.__parent__
+            else:
+                context = getattr(context.__parent__, '__parent__', None)
+
+            if context is None:
+                context = getRoot(self.context)
+
+            layout = queryLayout(self, self.request, context, name=self.layout)
+            if layout is not None:
+                return layout(view=view, *args, **kw)
+
+        layout = queryLayout(
+            self.view, self.context, self.request, name=self.layout)
+
+        if layout is not None:
+            return layout(*args, **kw)
+
+        raise LayoutNotFound(self.layout)

Deleted: z3ext.layout/tags/2.2.1/src/z3ext/layout/pagelet.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/pagelet.py	2009-08-10 17:22:44 UTC (rev 102631)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/pagelet.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -1,209 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 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.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-import logging, sys
-from zope import interface, component
-from zope.component import queryUtility, queryAdapter, queryMultiAdapter
-from zope.publisher.browser import BrowserPage
-from zope.publisher.interfaces import NotFound
-from zope.publisher.interfaces.browser import IBrowserPublisher
-from zope.tales.expressions import SimpleModuleImporter
-from zope.app.publisher.browser import queryDefaultViewName
-
-from interfaces import ILayout, IPagelet, IPageletType, IPageletContext
-
-
-def queryLayout(view, request, context=None, iface=ILayout, name=''):
-    if context is None:
-        context = view.context
-
-    while context is not None:
-        layout = queryMultiAdapter((view, context, request), iface, name)
-        if layout is not None:
-            return layout
-
-        context = getattr(context, '__parent__', None)
-
-    return None
-
-
-def queryPagelet(context, request, name, modules=SimpleModuleImporter()):
-    pageletName = u''
-
-    if name:
-        splited = name.split(u'+', 1)
-        if len(splited) > 1:
-            name, pageletName = splited
-
-        if name:
-            iface = queryUtility(IPageletType, name)
-        else:
-            iface = IPagelet
-
-        if iface is None:
-            try:
-                iface, iname = name.rsplit('.', 1)
-                iface = getattr(modules[iface], iname)
-            except:
-                raise KeyError(name)
-    else:
-        iface = IPagelet
-
-    if iface.providedBy(context):
-        return context
-
-    contexts = queryAdapter(context, IPageletContext, name)
-    if contexts is not None:
-        required = [context]
-        if type(contexts) in (list, tuple):
-            required.extend(contexts)
-        else:
-            required.append(contexts)
-        required.append(request)
-        return queryMultiAdapter(required, iface, pageletName)
-    else:
-        return queryMultiAdapter((context, request), iface, pageletName)
-
-
- at interface.implementer(IPagelet)
- at component.adapter(interface.Interface, interface.Interface)
-def queryDefaultView(context, request):
-    name = queryDefaultViewName(context, request, None)
-    if name:
-        view = queryMultiAdapter((context, request), name=name)
-        if IPagelet.providedBy(view):
-            return view
-
-
-class BrowserPagelet(BrowserPage):
-    interface.implements(IPagelet)
-
-    template = None
-    layoutname = u''
-    isRedirected = False
-
-    def __init__(self, context, *args):
-        request = args[-1]
-        super(BrowserPagelet, self).__init__(context, request)
-
-        args = args[:-1]
-        self.contexts = args
-
-        for idx in range(len(args)):
-            setattr(self, 'context%s'%idx, args[idx])
-
-        self.__parent__ = context
-
-    def update(self):
-        pass
-
-    def render(self):
-        if self.template is not None:
-            return self.template()
-        else:
-            template = queryMultiAdapter((self, self.request), IPagelet)
-            if template is not None:
-                template.update()
-                return template.render()
-            raise LookupError("Can't find IPagelet for this pagelet.")
-
-    def updateAndRender(self):
-        self.update()
-        if self.isRedirected or not self.isAvailable():
-            return u''
-
-        return self.render()
-
-    def isAvailable(self):
-        return True
-
-    def redirect(self, url=''):
-        if url:
-            self.request.response.redirect(url)
-
-        self.isRedirected = True
-
-    def __call__(self, *args, **kw):
-        self.update()
-
-        if self.isRedirected or self.request.response.getStatus() in (302, 303):
-            return u''
-
-        layout = queryLayout(
-            self, self.request, self.__parent__, name=self.layoutname)
-        if layout is None:
-            return self.render()
-        else:
-            return layout()
-
-
-class PageletPublisher(object):
-    interface.implements(IBrowserPublisher)
-    component.adapts(interface.Interface, interface.Interface)
-
-    render = True
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-
-    def publishTraverse(self, request, name):
-        try:
-            return self[name]
-        except KeyError:
-            pass
-
-        raise NotFound(self.context, name, request)
-
-    def __call__(self, name=''):
-        try:
-            return self[name]
-        except KeyError:
-            pass
-
-        return u''
-
-    def __getitem__(self, name):
-        view = queryPagelet(self.context, self.request, name)
-
-        if view is not None:
-            try:
-                return view.updateAndRender()
-            except Exception, err:
-                log = logging.getLogger('z3ext.layout')
-                log.exception(err)
-
-        raise KeyError(name)
-
-    def browserDefault(self, request):
-        return self.context, ('',)
-
-
-class PageletObjectPublisher(PageletPublisher):
-
-    def __getitem__(self, name):
-        view = queryPagelet(self.context, self.request, name)
-
-        if view is not None:
-            try:
-                view.update()
-                return view
-            except Exception, err:
-                log = logging.getLogger('z3ext.layout')
-                log.exception(err)
-
-        raise KeyError(name)

Copied: z3ext.layout/tags/2.2.1/src/z3ext/layout/pagelet.py (from rev 102644, z3ext.layout/trunk/src/z3ext/layout/pagelet.py)
===================================================================
--- z3ext.layout/tags/2.2.1/src/z3ext/layout/pagelet.py	                        (rev 0)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/pagelet.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -0,0 +1,209 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+import logging, sys
+from zope import interface, component
+from zope.component import queryUtility, queryAdapter, queryMultiAdapter
+from zope.publisher.browser import BrowserPage
+from zope.publisher.interfaces import NotFound
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.tales.expressions import SimpleModuleImporter
+from zope.app.publisher.browser import queryDefaultViewName
+
+from interfaces import ILayout, IPagelet, IPageletType, IPageletContext
+
+
+def queryLayout(view, request, context=None, iface=ILayout, name=''):
+    if context is None:
+        context = view.context
+
+    while context is not None:
+        layout = queryMultiAdapter((view, context, request), iface, name)
+        if layout is not None:
+            return layout
+
+        context = getattr(context, '__parent__', None)
+
+    return None
+
+
+def queryPagelet(context, request, name, modules=SimpleModuleImporter()):
+    pageletName = u''
+
+    if name:
+        splited = name.split(u'+', 1)
+        if len(splited) > 1:
+            name, pageletName = splited
+
+        if name:
+            iface = queryUtility(IPageletType, name)
+        else:
+            iface = IPagelet
+
+        if iface is None:
+            try:
+                iface, iname = name.rsplit('.', 1)
+                iface = getattr(modules[iface], iname)
+            except:
+                raise KeyError(name)
+    else:
+        iface = IPagelet
+
+    if iface.providedBy(context):
+        return context
+
+    contexts = queryAdapter(context, IPageletContext, name)
+    if contexts is not None:
+        required = [context]
+        if type(contexts) in (list, tuple):
+            required.extend(contexts)
+        else:
+            required.append(contexts)
+        required.append(request)
+        return queryMultiAdapter(required, iface, pageletName)
+    else:
+        return queryMultiAdapter((context, request), iface, pageletName)
+
+
+ at interface.implementer(IPagelet)
+ at component.adapter(interface.Interface, interface.Interface)
+def queryDefaultView(context, request):
+    name = queryDefaultViewName(context, request, None)
+    if name:
+        view = queryMultiAdapter((context, request), name=name)
+        if IPagelet.providedBy(view):
+            return view
+
+
+class BrowserPagelet(BrowserPage):
+    interface.implements(IPagelet)
+
+    template = None
+    layoutname = u''
+    isRedirected = False
+
+    def __init__(self, context, *args):
+        request = args[-1]
+        super(BrowserPagelet, self).__init__(context, request)
+
+        args = args[:-1]
+        self.contexts = args
+
+        for idx in range(len(args)):
+            setattr(self, 'context%s'%idx, args[idx])
+
+        self.__parent__ = context
+
+    def update(self):
+        pass
+
+    def render(self):
+        if self.template is not None:
+            return self.template()
+        else:
+            template = queryMultiAdapter((self, self.request), IPagelet)
+            if template is not None:
+                template.update()
+                return template.render()
+            raise LookupError("Can't find IPagelet for this pagelet.")
+
+    def updateAndRender(self):
+        self.update()
+        if self.isRedirected or not self.isAvailable():
+            return u''
+
+        return self.render()
+
+    def isAvailable(self):
+        return True
+
+    def redirect(self, url=''):
+        if url:
+            self.request.response.redirect(url)
+
+        self.isRedirected = True
+
+    def __call__(self, *args, **kw):
+        self.update()
+
+        if self.isRedirected or self.request.response.getStatus() in (302, 303):
+            return u''
+
+        layout = queryLayout(
+            self, self.request, self.__parent__, name=self.layoutname)
+        if layout is None:
+            return self.render()
+        else:
+            return layout()
+
+
+class PageletPublisher(object):
+    interface.implements(IBrowserPublisher)
+    component.adapts(interface.Interface, interface.Interface)
+
+    render = True
+
+    def __init__(self, context, request):
+        self.context = context
+        self.request = request
+
+    def publishTraverse(self, request, name):
+        try:
+            return self[name]
+        except KeyError:
+            pass
+
+        raise NotFound(self.context, name, request)
+
+    def __call__(self, name=''):
+        try:
+            return self[name]
+        except KeyError:
+            pass
+
+        return u''
+
+    def __getitem__(self, name):
+        view = queryPagelet(self.context, self.request, name)
+
+        if view is not None:
+            try:
+                return view.updateAndRender()
+            except Exception, err:
+                log = logging.getLogger('z3ext.layout')
+                log.exception(err)
+
+        raise KeyError(name)
+
+    def browserDefault(self, request):
+        return self.context, ('',)
+
+
+class PageletObjectPublisher(PageletPublisher):
+
+    def __getitem__(self, name):
+        view = queryPagelet(self.context, self.request, name)
+
+        if view is not None:
+            try:
+                view.update()
+                return view
+            except Exception, err:
+                log = logging.getLogger('z3ext.layout')
+                log.exception(err)
+
+        raise KeyError(name)

Deleted: z3ext.layout/tags/2.2.1/src/z3ext/layout/tales.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/tales.py	2009-08-10 17:22:44 UTC (rev 102631)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/tales.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -1,49 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 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.
-#
-##############################################################################
-""" 'pagelet' tales expression registrations
-
-$Id: tales.py 2720 2008-08-25 11:15:10Z fafhrd91 $
-"""
-import logging, sys
-from zope.tales.expressions import StringExpr, SimpleModuleImporter
-from zope.component import queryUtility, queryAdapter, queryMultiAdapter
-
-from pagelet import queryPagelet
-from interfaces import IPagelet, IPageletType, IPageletContext
-
-
-class PageletExpression(object):
-
-    def render(self, context, request, view, name):
-        try:
-            pagelet = queryPagelet(context, request, name)
-            if pagelet is not None:
-                return pagelet.updateAndRender()
-        except Exception, err:
-            log = logging.getLogger('z3ext.layout')
-            log.exception(err)
-
-        return u''
-
-
-class TALESPageletExpression(StringExpr, PageletExpression):
-
-    def __call__(self, econtext):
-        name = super(TALESPageletExpression, self).__call__(econtext)
-
-        context = econtext.vars['context']
-        request = econtext.vars['request']
-        view = econtext.vars['view']
-
-        return self.render(context, request, view, name)

Copied: z3ext.layout/tags/2.2.1/src/z3ext/layout/tales.py (from rev 102644, z3ext.layout/trunk/src/z3ext/layout/tales.py)
===================================================================
--- z3ext.layout/tags/2.2.1/src/z3ext/layout/tales.py	                        (rev 0)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/tales.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -0,0 +1,49 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation 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.
+#
+##############################################################################
+""" 'pagelet' tales expression registrations
+
+$Id: tales.py 2720 2008-08-25 11:15:10Z fafhrd91 $
+"""
+import logging, sys
+from zope.tales.expressions import StringExpr, SimpleModuleImporter
+from zope.component import queryUtility, queryAdapter, queryMultiAdapter
+
+from pagelet import queryPagelet
+from interfaces import IPagelet, IPageletType, IPageletContext
+
+
+class PageletExpression(object):
+
+    def render(self, context, request, view, name):
+        try:
+            pagelet = queryPagelet(context, request, name)
+            if pagelet is not None:
+                return pagelet.updateAndRender()
+        except Exception, err:
+            log = logging.getLogger('z3ext.layout')
+            log.exception(err)
+
+        return u''
+
+
+class TALESPageletExpression(StringExpr, PageletExpression):
+
+    def __call__(self, econtext):
+        name = super(TALESPageletExpression, self).__call__(econtext)
+
+        context = econtext.vars['context']
+        request = econtext.vars['request']
+        view = econtext.vars['view']
+
+        return self.render(context, request, view, name)

Deleted: z3ext.layout/tags/2.2.1/src/z3ext/layout/tests.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/tests.py	2009-08-10 17:22:44 UTC (rev 102631)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/tests.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -1,84 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 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.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-import unittest, doctest
-from zope import interface, component
-from zope.testing.doctestunit import DocFileSuite
-from zope.app.testing import setup
-from zope.app.container.sample import SampleContainer
-from z3c.pt import expressions
-
-from z3ext.layout import pagelet
-
-
-class IFolder1(interface.Interface):
-    pass
-
-class IFolder1_1(interface.Interface):
-    pass
-
-class IFolder1_1_1(interface.Interface):
-    pass
-
-class ITestPagelet(interface.Interface):
-    pass
-
-
-class Folder(SampleContainer):
-    pass
-
-
-class MyLayout(object):
-
-    title = u'My layout'
-
-
-def setUp(test):
-    root = setup.placefulSetUp(site=True)
-    root.__name__ = 'root'
-    test.globs['root'] = root
-    component.provideAdapter(pagelet.queryDefaultView)
-    component.provideAdapter(pagelet.PageletPublisher, name='pagelet')
-    component.provideAdapter(pagelet.PageletObjectPublisher,name='pageletObject')
-    component.provideUtility(expressions.path_translator, name='path')
-
-    setup.setUpTestAsModule(test, 'z3ext.layout.TESTS')
-
-
-def tearDown(test):
-    setup.placefulTearDown()
-    setup.tearDownTestAsModule(test)
-
-
-def test_suite():
-    return unittest.TestSuite((
-        doctest.DocFileSuite(
-            'README.txt',
-            setUp=setUp, tearDown=tearDown,
-            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-            ),
-        doctest.DocFileSuite(
-            'pagelet.txt',
-            setUp=setUp, tearDown=tearDown,
-            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-            ),
-        doctest.DocFileSuite(
-            'zcml.txt',
-            setUp=setUp, tearDown=tearDown,
-            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-            ),
-        ))

Copied: z3ext.layout/tags/2.2.1/src/z3ext/layout/tests.py (from rev 102644, z3ext.layout/trunk/src/z3ext/layout/tests.py)
===================================================================
--- z3ext.layout/tags/2.2.1/src/z3ext/layout/tests.py	                        (rev 0)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/tests.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -0,0 +1,84 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+import unittest, doctest
+from zope import interface, component
+from zope.testing.doctestunit import DocFileSuite
+from zope.app.testing import setup
+from zope.app.container.sample import SampleContainer
+from z3c.pt import expressions
+
+from z3ext.layout import pagelet
+
+
+class IFolder1(interface.Interface):
+    pass
+
+class IFolder1_1(interface.Interface):
+    pass
+
+class IFolder1_1_1(interface.Interface):
+    pass
+
+class ITestPagelet(interface.Interface):
+    pass
+
+
+class Folder(SampleContainer):
+    pass
+
+
+class MyLayout(object):
+
+    title = u'My layout'
+
+
+def setUp(test):
+    root = setup.placefulSetUp(site=True)
+    root.__name__ = 'root'
+    test.globs['root'] = root
+    component.provideAdapter(pagelet.queryDefaultView)
+    component.provideAdapter(pagelet.PageletPublisher, name='pagelet')
+    component.provideAdapter(pagelet.PageletObjectPublisher,name='pageletObject')
+    component.provideUtility(expressions.path_translator, name='path')
+
+    setup.setUpTestAsModule(test, 'z3ext.layout.TESTS')
+
+
+def tearDown(test):
+    setup.placefulTearDown()
+    setup.tearDownTestAsModule(test)
+
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocFileSuite(
+            'README.txt',
+            setUp=setUp, tearDown=tearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            ),
+        doctest.DocFileSuite(
+            'pagelet.txt',
+            setUp=setUp, tearDown=tearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            ),
+        doctest.DocFileSuite(
+            'zcml.txt',
+            setUp=setUp, tearDown=tearDown,
+            optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+            ),
+        ))

Deleted: z3ext.layout/tags/2.2.1/src/z3ext/layout/zcml.py
===================================================================
--- z3ext.layout/trunk/src/z3ext/layout/zcml.py	2009-08-10 17:22:44 UTC (rev 102631)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/zcml.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -1,480 +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.
-#
-##############################################################################
-"""
-
-$Id$
-"""
-import os.path
-from zope import schema, interface, event
-from zope.interface.verify import verifyClass
-from zope.schema.interfaces import IFromUnicode
-from zope.component import getUtility, queryUtility
-from zope.component.interface import provideInterface
-from zope.component.zcml import handler, adapter, utility
-from zope.security.zcml import Permission
-from zope.security.checker import defineChecker, Checker, CheckerPublic
-from zope.configuration.fields import Path,Tokens,GlobalObject,GlobalInterface
-from zope.configuration.exceptions import ConfigurationError
-from zope.publisher.interfaces import IPublishTraverse
-from zope.publisher.interfaces.browser import IBrowserPage
-from zope.publisher.interfaces.browser import IBrowserPublisher
-from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-from zope.app.component.metadirectives import IBasicViewInformation
-
-from z3c.pt.pagetemplate import ViewPageTemplateFile
-
-from interfaces import IPagelet, IPageletType
-from interfaces import ILayout, ILayoutCreatedEvent
-
-from pagelet import BrowserPagelet
-from layout import Layout, LayoutTemplateFile
-
-
-class IPageletTypeDirective(interface.Interface):
-    """A directive to register a new pagelet type."""
-
-    name = schema.TextLine(
-        title = u'Name',
-        description = u'Pagelet type name',
-        required = True)
-
-    interface = GlobalInterface(
-        title = u'Interface',
-        description = u'Interface that is used as pagelet type.',
-        required = True)
-
-
-class IPageletDirective(IBasicViewInformation):
-    """A directive to register a new pagelet.
-
-    The pagelet directive also supports an undefined set of keyword arguments
-    that are set as attributes on the pagelet after creation.
-    """
-
-    for_ = Tokens(
-        title = u"Context",
-        description = u"The content interface or class this pagelet is for.",
-        value_type = GlobalObject(missing_value=object()),
-        required = True)
-
-    name = schema.TextLine(
-        title = u"The name of the pagelet.",
-        description = u"The name shows up in URLs/paths. For example 'foo'.",
-        required = False)
-
-    type = Tokens(
-        title = u"Pagelet type.",
-        required = False,
-        value_type = schema.TextLine())
-
-    provides = Tokens(
-        title = u"The interface this pagelets provides.",
-        description = u"""A pagelet can provide an interface.  This would be used for views that support other views.""",
-        required = False,
-        value_type = GlobalInterface())
-
-    class_ = GlobalObject(
-        title=u"Class",
-        description=u"A class that provides attributes used by the pagelet.",
-        required=False,
-        )
-
-    template = Path(
-        title = u'Pagelet template.',
-        description = u"Refers to a file containing a page template (should "\
-                                    "end in extension ``.pt`` or ``.html``).",
-        required=False)
-
-    layout = schema.TextLine(
-        title = u'The name of the layout.',
-        description = u"The name is used to look up the layout.",
-        default=u'',
-        required=False)
-
-    layer = GlobalObject(
-        title = u'Layer',
-        description = u'The layer for which the template should be available',
-        required = False,
-        default = IDefaultBrowserLayer)
-
-
-# Arbitrary keys and values are allowed to be passed to the pagelet.
-IPageletDirective.setTaggedValue('keyword_arguments', True)
-
-
-class ILayoutDirective(interface.Interface):
-
-    uid = schema.TextLine(
-        title = u"Unique layout id",
-        default = u'',
-        required = False)
-
-    template = Path(
-        title=u'Layout template.',
-        description=u"Refers to a file containing a page template (should "
-                     "end in extension ``.pt`` or ``.html``).",
-        required=False,
-        )
-
-    name = schema.TextLine(
-        title=u"The name of the layout.",
-        description=u"The name is used to look up the layout.",
-        default=u'',
-        required=False)
-
-    layer = GlobalObject(
-        title = u'Layer',
-        description = u'The layer for which the template should be available',
-        required = False,
-        default=IDefaultBrowserLayer,
-        )
-
-    contentType = schema.BytesLine(
-        title = u'Content Type',
-        description=u'The content type identifies the type of data.',
-        default='text/html',
-        required=False,
-        )
-
-    provides = GlobalInterface(
-        title=u"Interface the layout provides",
-        description=u"This attribute specifies the interface the layout"
-                      " instance will provide.",
-        default=ILayout,
-        required=False,
-        )
-
-    for_ = GlobalObject(
-        title = u'Context',
-        description = u'The object for which the layout should be available',
-        default=interface.Interface,
-        required = False)
-
-    view = GlobalObject(
-        title = u'View',
-        description = u'The view for which the layout should be available',
-        default=interface.Interface,
-        required = False)
-
-    class_ = GlobalObject(
-        title=u"Class",
-        description=u"A class that provides attributes used by the layout.",
-        required=False,
-        )
-
-    layout = schema.TextLine(
-        title = u'Layout',
-        description = u'Custom layout name.',
-        required = False)
-
-    title = schema.TextLine(
-        title = u'Layout title',
-        required = False)
-
-    description = schema.TextLine(
-        title = u'Layout description',
-        required = False)
-
-# Arbitrary keys and values are allowed
-ILayoutDirective.setTaggedValue('keyword_arguments', True)
-
-
-def pageletTypeDirective(_context, name, interface):
-    if interface is not IPagelet and interface.isOrExtends(IPublishTraverse):
-        raise ConfigurationError("Can't use IPublishTraverse as base for pagelet type")
-
-    provideInterface(name, interface, IPageletType)
-
-
-def layoutDirective(
-    _context, uid='', template='', for_=None, view=None, name = u'',
-    layer = IDefaultBrowserLayer, provides = ILayout,
-    contentType='text/html', class_ = None, layout = '',
-    title='', description='', **kwargs):
-
-    if not layout:
-        layout = None
-    elif layout == '.':
-        layout = ''
-
-    # Make sure that the template exists
-    if template:
-        template = os.path.abspath(str(_context.path(template)))
-        if not os.path.isfile(template):
-            raise ConfigurationError("No such file", template)
-
-    # Check
-    if (for_ is None) and (view is None):
-        raise ConfigurationError("FOR or VIEW are required.")
-
-    # Build a new class that we can use different permission settings if we
-    # use the class more then once.
-    cdict = {}
-    cdict['__name__'] = name
-    cdict['layout'] = layout
-    cdict['title'] = title
-    cdict['description'] = description
-
-    if template:
-        cdict['template'] = LayoutTemplateFile(template,content_type=contentType)
-
-    cdict.update(kwargs)
-
-    class_name = 'Layout<%s>'%name
-
-    if class_ is None:
-        bases = (Layout,)
-    else:
-        bases = (class_, Layout)
-
-    newclass = type(str(class_name), bases, cdict)
-
-    # Set up permission mapping for various accessible attributes
-    required = {}
-
-    for iface in (provides, ILayout):
-        for iname in iface:
-            required[iname] = CheckerPublic
-
-    required = {'__call__': CheckerPublic,
-                'browserDefault': CheckerPublic,
-                'publishTraverse': CheckerPublic}
-
-    # provide the custom provides interface if not allready provided
-    if not provides.implementedBy(newclass):
-        interface.classImplements(newclass, provides)
-
-    # security checker
-    defineChecker(newclass, Checker(required))
-
-    # register the template
-    if name:
-        adapter(_context, (newclass,),
-                provides, (view, for_, layer), name=name)
-    else:
-        adapter(_context, (newclass,),
-                provides, (view, for_, layer))
-
-    # send ILayoutCreatedEvent event
-    if uid:
-        _context.action(
-            discriminator = ('z3ext.layout', uid),
-            callable = sendNotification,
-            args = (uid, name, view, for_, layer, newclass, kwargs),
-            order = 99999999)
-
-
-class LayoutCreatedEvent(object):
-    interface.implements(ILayoutCreatedEvent)
-
-    def __init__(self, uid, name, view,
-                 context, layer, layoutclass, keywords):
-        self.uid = uid
-        self.name = name
-        self.view = view
-        self.context = context
-        self.layer = layer
-        self.layoutclass = layoutclass
-        self.keywords = keywords
-
-
-def sendNotification(uid, name, view, context, layer, layoutclass, keywords):
-    event.notify(LayoutCreatedEvent(
-            uid, name, view, context, layer, layoutclass, keywords))
-
-
-Type = type
-
-# pagelet directive
-def pageletDirective(
-    _context, for_, name=u'', type=(),
-    class_=None, layer=IDefaultBrowserLayer, provides=[],
-    allowed_interface=[], allowed_attributes=[],
-    template=u'', layout=u'', permission='zope.Public', **kwargs):
-
-    # Check paeglet name
-    if not name and not type:
-        raise ConfigurationError("Can't create pagelet without name.")
-
-    # Add IPagelet to provides
-    provides = list(provides)
-    if IPagelet not in provides:
-        provides.append(IPagelet)
-
-    # Security map dictionary
-    required = {}
-
-    # Make sure that the template exists
-    if template:
-        template = os.path.abspath(str(_context.path(template)))
-        if not os.path.isfile(template):
-            raise ConfigurationError("No such file", template)
-        kwargs['template'] = ViewPageTemplateFile(template)
-
-    # Build a new class that we can use different permission settings if we
-    # use the class more then once.
-    cdict = {}
-    cdict.update(kwargs)
-    cdict['__name__'] = name
-    cdict['layoutname'] = layout
-
-    if class_ is not None:
-        if issubclass(class_, BrowserPagelet):
-            bases = (class_,)
-        else:
-            bases = (class_, BrowserPagelet)
-    else:
-        bases = (BrowserPagelet,)
-
-    new_class = Type('PageletClass from %s'%class_, bases, cdict)
-
-    # extend provides with type
-    tps = []
-    for tp in type:
-        iface = queryUtility(IPageletType, tp)
-        if iface is None:
-            try:
-                iface = _context.resolve(tp)
-            except Exception, err:
-                pass
-
-        if iface is not None:
-            provides.append(iface)
-
-    kwargs['type'] = type
-    kwargs['name'] = name
-    kwargs['permission'] = permission
-
-    # convert kwargs
-    for iface in provides:
-        for fname, field in schema.getFields(iface).items():
-            if fname in kwargs:
-                if not IFromUnicode.providedBy(field):
-                    raise ConfigurationError("Can't convert value", fname)
-
-                setattr(new_class, fname, field.fromUnicode(kwargs[fname]))
-            else:
-                if field.required and not hasattr(new_class, fname):
-                    raise ConfigurationError("Required field is missing", fname)
-
-                if not hasattr(new_class, fname):
-                    setattr(new_class, fname, field.default)
-
-    # add IPagelet to provides
-    if name:
-        inProvides = False
-        for iface in provides:
-            if IPagelet.isOrExtends(iface) and not IPageletType.providedBy(iface):
-                inProvides = True
-
-        if not inProvides:
-            provides.append(IPagelet)
-
-    # Handle CheckerPublic
-    if permission == 'zope.Public':
-        permission = CheckerPublic
-
-    # prepare allowed interfaces and attributes
-    allowed_interface.extend(provides)
-    allowed_interface.append(IBrowserPage)
-    allowed_attributes.extend(kwargs.keys())
-    allowed_attributes.extend(('__call__', 'browserDefault', 'publishTraverse'))
-
-    # Set up permission mapping for various accessible attributes
-    _handle_allowed_interface(
-        _context, allowed_interface, permission, required)
-    _handle_allowed_attributes(
-        _context, allowed_attributes, permission, required)
-
-    # Register the interfaces.
-    _handle_for(_context, for_)
-
-    # provide the custom provides interface if not allready provided
-    for iface in provides:
-        if not iface.implementedBy(new_class):
-            interface.classImplements(new_class, iface)
-
-        verifyClass(iface, new_class)
-
-    # Create the security checker for the new class
-    defineChecker(new_class, Checker(required))
-
-    # register pagelet
-    for_.append(layer)
-    if type:
-        _context.action(
-            discriminator = (
-                'z3ext.layout:registerPagelets',
-                tuple(type), tuple(for_), layer, name),
-            callable = registerTypedPagelets,
-            args = (for_, new_class, type, name, _context))
-    else:
-        _context.action(
-            discriminator = (
-                'z3ext.layout:registerPagelets', tuple(for_), layer, name),
-            callable = registerPagelets,
-            args = (for_, new_class, provides, name, _context.info))
-
-
-def registerPagelets(required, newClass, provides, name, info):
-    handler('registerAdapter', newClass, required, IPagelet, name, info)
-
-    for iface in provides:
-        if iface is IPagelet:
-            continue
-
-        if IPageletType.providedBy(iface):
-            handler('registerAdapter', newClass, required, iface, '', info)
-
-
-def registerTypedPagelets(required, newClass, type, name, _context):
-    for tp in type:
-        iface = queryUtility(IPageletType, tp)
-        if iface is None:
-            try:
-                iface = _context.resolve(tp)
-            except Exception, err:
-                pass
-
-        handler('registerAdapter', newClass, required, iface,name,_context.info)
-
-
-def _handle_allowed_interface(
-    _context, allowed_interface, permission, required):
-    # Allow access for all names defined by named interfaces
-    if allowed_interface:
-        for i in allowed_interface:
-            _context.action(
-                discriminator = None,
-                callable = provideInterface,
-                args = (None, i))
-
-            for name in i:
-                required[name] = permission
-
-def _handle_allowed_attributes(
-    _context, allowed_attributes, permission, required):
-
-    # Allow access for all named attributes
-    if allowed_attributes:
-        for name in allowed_attributes:
-            required[name] = permission
-
-def _handle_for(_context, for_):
-    for iface in for_:
-        if iface is not None:
-            _context.action(
-                discriminator = None,
-                callable = provideInterface,
-                args = ('', iface))

Copied: z3ext.layout/tags/2.2.1/src/z3ext/layout/zcml.py (from rev 102644, z3ext.layout/trunk/src/z3ext/layout/zcml.py)
===================================================================
--- z3ext.layout/tags/2.2.1/src/z3ext/layout/zcml.py	                        (rev 0)
+++ z3ext.layout/tags/2.2.1/src/z3ext/layout/zcml.py	2009-08-11 08:26:54 UTC (rev 102645)
@@ -0,0 +1,480 @@
+##############################################################################
+#
+# Copyright (c) 2009 Zope Foundation 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.
+#
+##############################################################################
+"""
+
+$Id$
+"""
+import os.path
+from zope import schema, interface, event
+from zope.interface.verify import verifyClass
+from zope.schema.interfaces import IFromUnicode
+from zope.component import getUtility, queryUtility
+from zope.component.interface import provideInterface
+from zope.component.zcml import handler, adapter, utility
+from zope.security.zcml import Permission
+from zope.security.checker import defineChecker, Checker, CheckerPublic
+from zope.configuration.fields import Path,Tokens,GlobalObject,GlobalInterface
+from zope.configuration.exceptions import ConfigurationError
+from zope.publisher.interfaces import IPublishTraverse
+from zope.publisher.interfaces.browser import IBrowserPage
+from zope.publisher.interfaces.browser import IBrowserPublisher
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.app.component.metadirectives import IBasicViewInformation
+
+from z3c.pt.pagetemplate import ViewPageTemplateFile
+
+from interfaces import IPagelet, IPageletType
+from interfaces import ILayout, ILayoutCreatedEvent
+
+from pagelet import BrowserPagelet
+from layout import Layout, LayoutTemplateFile
+
+
+class IPageletTypeDirective(interface.Interface):
+    """A directive to register a new pagelet type."""
+
+    name = schema.TextLine(
+        title = u'Name',
+        description = u'Pagelet type name',
+        required = True)
+
+    interface = GlobalInterface(
+        title = u'Interface',
+        description = u'Interface that is used as pagelet type.',
+        required = True)
+
+
+class IPageletDirective(IBasicViewInformation):
+    """A directive to register a new pagelet.
+
+    The pagelet directive also supports an undefined set of keyword arguments
+    that are set as attributes on the pagelet after creation.
+    """
+
+    for_ = Tokens(
+        title = u"Context",
+        description = u"The content interface or class this pagelet is for.",
+        value_type = GlobalObject(missing_value=object()),
+        required = True)
+
+    name = schema.TextLine(
+        title = u"The name of the pagelet.",
+        description = u"The name shows up in URLs/paths. For example 'foo'.",
+        required = False)
+
+    type = Tokens(
+        title = u"Pagelet type.",
+        required = False,
+        value_type = schema.TextLine())
+
+    provides = Tokens(
+        title = u"The interface this pagelets provides.",
+        description = u"""A pagelet can provide an interface.  This would be used for views that support other views.""",
+        required = False,
+        value_type = GlobalInterface())
+
+    class_ = GlobalObject(
+        title=u"Class",
+        description=u"A class that provides attributes used by the pagelet.",
+        required=False,
+        )
+
+    template = Path(
+        title = u'Pagelet template.',
+        description = u"Refers to a file containing a page template (should "\
+                                    "end in extension ``.pt`` or ``.html``).",
+        required=False)
+
+    layout = schema.TextLine(
+        title = u'The name of the layout.',
+        description = u"The name is used to look up the layout.",
+        default=u'',
+        required=False)
+
+    layer = GlobalObject(
+        title = u'Layer',
+        description = u'The layer for which the template should be available',
+        required = False,
+        default = IDefaultBrowserLayer)
+
+
+# Arbitrary keys and values are allowed to be passed to the pagelet.
+IPageletDirective.setTaggedValue('keyword_arguments', True)
+
+
+class ILayoutDirective(interface.Interface):
+
+    uid = schema.TextLine(
+        title = u"Unique layout id",
+        default = u'',
+        required = False)
+
+    template = Path(
+        title=u'Layout template.',
+        description=u"Refers to a file containing a page template (should "
+                     "end in extension ``.pt`` or ``.html``).",
+        required=False,
+        )
+
+    name = schema.TextLine(
+        title=u"The name of the layout.",
+        description=u"The name is used to look up the layout.",
+        default=u'',
+        required=False)
+
+    layer = GlobalObject(
+        title = u'Layer',
+        description = u'The layer for which the template should be available',
+        required = False,
+        default=IDefaultBrowserLayer,
+        )
+
+    contentType = schema.BytesLine(
+        title = u'Content Type',
+        description=u'The content type identifies the type of data.',
+        default='text/html',
+        required=False,
+        )
+
+    provides = GlobalInterface(
+        title=u"Interface the layout provides",
+        description=u"This attribute specifies the interface the layout"
+                      " instance will provide.",
+        default=ILayout,
+        required=False,
+        )
+
+    for_ = GlobalObject(
+        title = u'Context',
+        description = u'The object for which the layout should be available',
+        default=interface.Interface,
+        required = False)
+
+    view = GlobalObject(
+        title = u'View',
+        description = u'The view for which the layout should be available',
+        default=interface.Interface,
+        required = False)
+
+    class_ = GlobalObject(
+        title=u"Class",
+        description=u"A class that provides attributes used by the layout.",
+        required=False,
+        )
+
+    layout = schema.TextLine(
+        title = u'Layout',
+        description = u'Custom layout name.',
+        required = False)
+
+    title = schema.TextLine(
+        title = u'Layout title',
+        required = False)
+
+    description = schema.TextLine(
+        title = u'Layout description',
+        required = False)
+
+# Arbitrary keys and values are allowed
+ILayoutDirective.setTaggedValue('keyword_arguments', True)
+
+
+def pageletTypeDirective(_context, name, interface):
+    if interface is not IPagelet and interface.isOrExtends(IPublishTraverse):
+        raise ConfigurationError("Can't use IPublishTraverse as base for pagelet type")
+
+    provideInterface(name, interface, IPageletType)
+
+
+def layoutDirective(
+    _context, uid='', template='', for_=None, view=None, name = u'',
+    layer = IDefaultBrowserLayer, provides = ILayout,
+    contentType='text/html', class_ = None, layout = '',
+    title='', description='', **kwargs):
+
+    if not layout:
+        layout = None
+    elif layout == '.':
+        layout = ''
+
+    # Make sure that the template exists
+    if template:
+        template = os.path.abspath(str(_context.path(template)))
+        if not os.path.isfile(template):
+            raise ConfigurationError("No such file", template)
+
+    # Check
+    if (for_ is None) and (view is None):
+        raise ConfigurationError("FOR or VIEW are required.")
+
+    # Build a new class that we can use different permission settings if we
+    # use the class more then once.
+    cdict = {}
+    cdict['__name__'] = name
+    cdict['layout'] = layout
+    cdict['title'] = title
+    cdict['description'] = description
+
+    if template:
+        cdict['template'] = LayoutTemplateFile(template,content_type=contentType)
+
+    cdict.update(kwargs)
+
+    class_name = 'Layout<%s>'%name
+
+    if class_ is None:
+        bases = (Layout,)
+    else:
+        bases = (class_, Layout)
+
+    newclass = type(str(class_name), bases, cdict)
+
+    # Set up permission mapping for various accessible attributes
+    required = {}
+
+    for iface in (provides, ILayout):
+        for iname in iface:
+            required[iname] = CheckerPublic
+
+    required = {'__call__': CheckerPublic,
+                'browserDefault': CheckerPublic,
+                'publishTraverse': CheckerPublic}
+
+    # provide the custom provides interface if not allready provided
+    if not provides.implementedBy(newclass):
+        interface.classImplements(newclass, provides)
+
+    # security checker
+    defineChecker(newclass, Checker(required))
+
+    # register the template
+    if name:
+        adapter(_context, (newclass,),
+                provides, (view, for_, layer), name=name)
+    else:
+        adapter(_context, (newclass,),
+                provides, (view, for_, layer))
+
+    # send ILayoutCreatedEvent event
+    if uid:
+        _context.action(
+            discriminator = ('z3ext.layout', uid),
+            callable = sendNotification,
+            args = (uid, name, view, for_, layer, newclass, kwargs),
+            order = 99999999)
+
+
+class LayoutCreatedEvent(object):
+    interface.implements(ILayoutCreatedEvent)
+
+    def __init__(self, uid, name, view,
+                 context, layer, layoutclass, keywords):
+        self.uid = uid
+        self.name = name
+        self.view = view
+        self.context = context
+        self.layer = layer
+        self.layoutclass = layoutclass
+        self.keywords = keywords
+
+
+def sendNotification(uid, name, view, context, layer, layoutclass, keywords):
+    event.notify(LayoutCreatedEvent(
+            uid, name, view, context, layer, layoutclass, keywords))
+
+
+Type = type
+
+# pagelet directive
+def pageletDirective(
+    _context, for_, name=u'', type=(),
+    class_=None, layer=IDefaultBrowserLayer, provides=[],
+    allowed_interface=[], allowed_attributes=[],
+    template=u'', layout=u'', permission='zope.Public', **kwargs):
+
+    # Check paeglet name
+    if not name and not type:
+        raise ConfigurationError("Can't create pagelet without name.")
+
+    # Add IPagelet to provides
+    provides = list(provides)
+    if IPagelet not in provides:
+        provides.append(IPagelet)
+
+    # Security map dictionary
+    required = {}
+
+    # Make sure that the template exists
+    if template:
+        template = os.path.abspath(str(_context.path(template)))
+        if not os.path.isfile(template):
+            raise ConfigurationError("No such file", template)
+        kwargs['template'] = ViewPageTemplateFile(template)
+
+    # Build a new class that we can use different permission settings if we
+    # use the class more then once.
+    cdict = {}
+    cdict.update(kwargs)
+    cdict['__name__'] = name
+    cdict['layoutname'] = layout
+
+    if class_ is not None:
+        if issubclass(class_, BrowserPagelet):
+            bases = (class_,)
+        else:
+            bases = (class_, BrowserPagelet)
+    else:
+        bases = (BrowserPagelet,)
+
+    new_class = Type('PageletClass from %s'%class_, bases, cdict)
+
+    # extend provides with type
+    tps = []
+    for tp in type:
+        iface = queryUtility(IPageletType, tp)
+        if iface is None:
+            try:
+                iface = _context.resolve(tp)
+            except Exception, err:
+                pass
+
+        if iface is not None:
+            provides.append(iface)
+
+    kwargs['type'] = type
+    kwargs['name'] = name
+    kwargs['permission'] = permission
+
+    # convert kwargs
+    for iface in provides:
+        for fname, field in schema.getFields(iface).items():
+            if fname in kwargs:
+                if not IFromUnicode.providedBy(field):
+                    raise ConfigurationError("Can't convert value", fname)
+
+                setattr(new_class, fname, field.fromUnicode(kwargs[fname]))
+            else:
+                if field.required and not hasattr(new_class, fname):
+                    raise ConfigurationError("Required field is missing", fname)
+
+                if not hasattr(new_class, fname):
+                    setattr(new_class, fname, field.default)
+
+    # add IPagelet to provides
+    if name:
+        inProvides = False
+        for iface in provides:
+            if IPagelet.isOrExtends(iface) and not IPageletType.providedBy(iface):
+                inProvides = True
+
+        if not inProvides:
+            provides.append(IPagelet)
+
+    # Handle CheckerPublic
+    if permission == 'zope.Public':
+        permission = CheckerPublic
+
+    # prepare allowed interfaces and attributes
+    allowed_interface.extend(provides)
+    allowed_interface.append(IBrowserPage)
+    allowed_attributes.extend(kwargs.keys())
+    allowed_attributes.extend(('__call__', 'browserDefault', 'publishTraverse'))
+
+    # Set up permission mapping for various accessible attributes
+    _handle_allowed_interface(
+        _context, allowed_interface, permission, required)
+    _handle_allowed_attributes(
+        _context, allowed_attributes, permission, required)
+
+    # Register the interfaces.
+    _handle_for(_context, for_)
+
+    # provide the custom provides interface if not allready provided
+    for iface in provides:
+        if not iface.implementedBy(new_class):
+            interface.classImplements(new_class, iface)
+
+        verifyClass(iface, new_class)
+
+    # Create the security checker for the new class
+    defineChecker(new_class, Checker(required))
+
+    # register pagelet
+    for_.append(layer)
+    if type:
+        _context.action(
+            discriminator = (
+                'z3ext.layout:registerPagelets',
+                tuple(type), tuple(for_), layer, name),
+            callable = registerTypedPagelets,
+            args = (for_, new_class, type, name, _context))
+    else:
+        _context.action(
+            discriminator = (
+                'z3ext.layout:registerPagelets', tuple(for_), layer, name),
+            callable = registerPagelets,
+            args = (for_, new_class, provides, name, _context.info))
+
+
+def registerPagelets(required, newClass, provides, name, info):
+    handler('registerAdapter', newClass, required, IPagelet, name, info)
+
+    for iface in provides:
+        if iface is IPagelet:
+            continue
+
+        if IPageletType.providedBy(iface):
+            handler('registerAdapter', newClass, required, iface, '', info)
+
+
+def registerTypedPagelets(required, newClass, type, name, _context):
+    for tp in type:
+        iface = queryUtility(IPageletType, tp)
+        if iface is None:
+            try:
+                iface = _context.resolve(tp)
+            except Exception, err:
+                pass
+
+        handler('registerAdapter', newClass, required, iface,name,_context.info)
+
+
+def _handle_allowed_interface(
+    _context, allowed_interface, permission, required):
+    # Allow access for all names defined by named interfaces
+    if allowed_interface:
+        for i in allowed_interface:
+            _context.action(
+                discriminator = None,
+                callable = provideInterface,
+                args = (None, i))
+
+            for name in i:
+                required[name] = permission
+
+def _handle_allowed_attributes(
+    _context, allowed_attributes, permission, required):
+
+    # Allow access for all named attributes
+    if allowed_attributes:
+        for name in allowed_attributes:
+            required[name] = permission
+
+def _handle_for(_context, for_):
+    for iface in for_:
+        if iface is not None:
+            _context.action(
+                discriminator = None,
+                callable = provideInterface,
+                args = ('', iface))



More information about the Checkins mailing list