[Checkins] SVN: z3c.pagelet/ Added z3c.pagelet implementation
Roger Ineichen
roger at projekt01.ch
Wed Jan 17 20:03:34 EST 2007
Log message for revision 72087:
Added z3c.pagelet implementation
Changed:
A z3c.pagelet/branches/
A z3c.pagelet/tags/
A z3c.pagelet/trunk/
A z3c.pagelet/trunk/src/
A z3c.pagelet/trunk/src/z3c/
A z3c.pagelet/trunk/src/z3c/__init__.py
A z3c.pagelet/trunk/src/z3c/pagelet/
A z3c.pagelet/trunk/src/z3c/pagelet/README.txt
A z3c.pagelet/trunk/src/z3c/pagelet/SETUP.cfg
A z3c.pagelet/trunk/src/z3c/pagelet/__init__.py
A z3c.pagelet/trunk/src/z3c/pagelet/browser.py
A z3c.pagelet/trunk/src/z3c/pagelet/configure.zcml
A z3c.pagelet/trunk/src/z3c/pagelet/form.pt
A z3c.pagelet/trunk/src/z3c/pagelet/interfaces.py
A z3c.pagelet/trunk/src/z3c/pagelet/meta.zcml
A z3c.pagelet/trunk/src/z3c/pagelet/provider.py
A z3c.pagelet/trunk/src/z3c/pagelet/tests.py
A z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-configure.zcml
A z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-meta.zcml
A z3c.pagelet/trunk/src/z3c/pagelet/zcml.py
A z3c.pagelet/trunk/src/z3c/pagelet/zcml.txt
-=-
Added: z3c.pagelet/trunk/src/z3c/__init__.py
===================================================================
--- z3c.pagelet/trunk/src/z3c/__init__.py 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/__init__.py 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""
+$Id$
+"""
Property changes on: z3c.pagelet/trunk/src/z3c/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/README.txt
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/README.txt 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/README.txt 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,357 @@
+======
+README
+======
+
+This package provides a very flexible base implementation for write view like
+components which can be higly customized later in custom project. This is
+needed if you have to write reusable components like needed in a framework.
+
+What does this mean?
+
+We separate the python view code from the template implementation. And we also
+separate the template in at least two different templates like the content
+template and a layout template.
+
+This package uses the z3c.template and offers a implementaton for this
+template patterns. Additionaly this package offers a ``pagelet`` directive
+wich can be used for register pagelets.
+
+Pagelets are views which can be called and support the update and render
+pattern.
+
+
+How do they work
+----------------
+
+A pagelet returns the rendered content without layout in the render method and
+returns the layout code if we call them. See also z3c.template which shows
+how the tempalte work. This samples will only show how the base implementation
+located in the z3c.pagelet.browser module get used.
+
+
+BrowserPagelet
+--------------
+
+The base implementation called BrowserPagelet offers built in __call__ and
+render methods which provide the different template lookup. Take a look at the
+BrowserPage class located in z3c.pagelet.browser and you can see that render
+method returns a IPageTemplate and the __call__ method a ILayoutTemplate
+defined in the z3c.layout package.
+
+ # some test stuff
+ >>> import os, tempfile
+ >>> temp_dir = tempfile.mkdtemp()
+
+ >>> import zope.interface
+ >>> import zope.component
+ >>> from z3c.pagelet import interfaces
+ >>> from z3c.pagelet import browser
+
+We start with define a page template rendering the pagelet content.
+
+ >>> contentTemplate = os.path.join(temp_dir, 'contentTemplate.pt')
+ >>> open(contentTemplate, 'w').write('''
+ ... <div class="content">
+ ... my template content
+ ... </div>
+ ... ''')
+
+And we also define a layout template rendering the layout for a pagelet.
+This template will call the render method from a pagelet:
+
+ >>> layoutTemplate = os.path.join(temp_dir, 'layoutTemplate.pt')
+ >>> open(layoutTemplate, 'w').write('''
+ ... <html>
+ ... <body>
+ ... <div class="layout" tal:content="structure view/render">
+ ... here comes the content
+ ... </div>
+ ... </body>
+ ... </html>
+ ... ''')
+
+Let's now register the template for the view and request. We use the
+TemplateFactory directly from the z3c.template package. This is commonly done
+using the ZCML directive called ``z3c:pagelet``. Note that we do use a the
+generic Interface as the view base interface for register the pagelet. This
+allows us to register a more specific template in the next sample:
+
+ >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+ >>> from zope.pagetemplate.interfaces import IPageTemplate
+ >>> from z3c.template.template import TemplateFactory
+ >>> factory = TemplateFactory(contentTemplate, 'text/html')
+ >>> zope.component.provideAdapter(factory,
+ ... (zope.interface.Interface, IDefaultBrowserLayer), IPageTemplate)
+
+And register the layout template useing the ``Interface`` as registration base:
+
+ >>> from z3c.template.interfaces import ILayoutTemplate
+ >>> factory = TemplateFactory(layoutTemplate, 'text/html')
+ >>> zope.component.provideAdapter(factory,
+ ... (zope.interface.Interface, IDefaultBrowserLayer), ILayoutTemplate)
+
+Now define a view marker interface. Such a marker interface is used for let
+use register our templates:
+
+ >>> class IMyView(zope.interface.Interface):
+ ... pass
+
+And we define a view class inherited from BrowserPagelet and implementing the
+view marker interface:
+
+ >>> class MyView(browser.BrowserPagelet):
+ ... zope.interface.implements(IMyView)
+
+Now test the view providing the view and check the output:
+
+ >>> from zope.publisher.browser import TestRequest
+ >>> request = TestRequest()
+ >>> myView = MyView(root, request)
+ >>> print myView()
+ <html>
+ <body>
+ <div class="layout">
+ <div class="content">
+ my template content
+ </div>
+ </div>
+ </body>
+ </html>
+
+You can see the render method generates only the content:
+
+ >>> print myView.render()
+ <div class="content">
+ my template content
+ </div>
+
+
+PageletRenderer
+---------------
+
+There is also a standard pattern for calling the render method on pagelet.
+Using the pagelet renderer which is a IContentProvider makes it possible to
+reuse existing laoyut template without the pagelet. if you like to reuse a
+ayout template without a pagelet you simply have to provide another content
+provider. It's flexible isn't it? As next let's show a sample using the
+pagelet renderer.
+
+We define a new layout template using the content provider called ```pagelet``
+
+
+ >>> providerLayout = os.path.join(temp_dir, 'providerLayout.pt')
+ >>> open(providerLayout, 'w').write('''
+ ... <html>
+ ... <body>
+ ... <div class="layout" tal:content="structure provider:pagelet">
+ ... here comes the content
+ ... </div>
+ ... </body>
+ ... </html>
+ ... ''')
+
+and register them. Now we use the specific interface defined inthe view:
+
+ >>> factory = TemplateFactory(providerLayout, 'text/html')
+ >>> zope.component.provideAdapter(factory,
+ ... (zope.interface.Interface, IDefaultBrowserLayer), ILayoutTemplate)
+
+Now let's call the view:
+
+ >>> print myView()
+ Traceback (most recent call last):
+ ...
+ ContentProviderLookupError: pagelet
+
+That's right, we need to register the content provider ``pagelet`` before we
+can use them.
+
+ >>> from zope.contentprovider.interfaces import IContentProvider
+ >>> from z3c.pagelet import provider
+ >>> zope.component.provideAdapter(provider.PageletRenderer,
+ ... provides=IContentProvider, name='pagelet')
+
+Now let's call the view again:
+
+ >>> print myView()
+ <html>
+ <body>
+ <div class="layout">
+ <div class="content">
+ my template content
+ </div>
+ </div>
+ </body>
+ </html>
+
+
+Add, Edit and Display forms (formlib)
+------------------------------------
+
+What whould the pagelet be without formlib base implementations? We offer base
+implementations for add, edit and display forms based on the formlib
+
+For the next tests we provide a generic form template like used in formlib.
+this template is registered within this package as default for the formlib
+based mixin classes:
+
+ >>> from z3c import pagelet
+ >>> baseDir = os.path.split(pagelet.__file__)[0]
+ >>> formTemplate = os.path.join(baseDir, 'form.pt')
+ >>> factory = TemplateFactory(formTemplate, 'text/html')
+ >>> zope.component.provideAdapter(factory,
+ ... (interfaces.IPageletForm, IDefaultBrowserLayer), IPageTemplate)
+
+And we define a new interface includig text attribute:
+
+ >>> import zope.schema
+ >>> class IDocument(zope.interface.Interface):
+ ... """A document."""
+ ... text = zope.schema.TextLine(title=u'Text', description=u'Text attr.')
+
+Also define a content object whcih implements the interface:
+
+ >>> class Document(object):
+ ... zope.interface.implements(IDocument)
+ ... text = None
+ >>> document = Document()
+
+PageletAddForm
+~~~~~~~~~~~~~~
+
+Now let's define a add from base on the PageletAddForm class:
+
+ >>> from zope.formlib import form
+ >>> class MyAddForm(browser.PageletAddForm):
+ ... form_fields = form.Fields(IDocument)
+ ... def createAndAdd(self, data):
+ ... title = data.get('title', u'')
+ ... doc = Document()
+ ... doc.title = title
+ ... root['document'] = doc
+ ... return doc
+
+Now render the form:
+
+ >>> addForm = MyAddForm(root, request)
+ >>> print addForm()
+ <html>
+ <body>
+ <div class="layout">
+ <form action="http://127.0.0.1" method="post"
+ enctype="multipart/form-data" class="edit-form"
+ id="zc.page.browser_form">
+ <table class="form-fields">
+ <tr>
+ <td class="label">
+ <label for="form.text">
+ <span class="required">*</span><span>Text</span>
+ </label>
+ </td>
+ <td class="field">
+ <div class="form-fields-help"
+ id="field-help-for-form.text">Text attr.</div>
+ <div class="widget"><input class="textType" id="form.text"
+ name="form.text" size="20" type="text" value="" /></div>
+ </td>
+ </tr>
+ </table>
+ <div class="form-controls">
+ <input type="submit" id="form.actions.add" name="form.actions.add"
+ value="Add" class="button" />
+ </div>
+ </form>
+ </div>
+ </body>
+ </html>
+
+
+PageletEditForm
+~~~~~~~~~~~~~~~
+
+Now let's define a edit from base on the PageletEditForm class...
+
+ >>> class MyEditForm(browser.PageletEditForm):
+ ... form_fields = form.Fields(IDocument)
+
+and render the form:
+
+ >>> document.text = u'foo'
+ >>> editForm = MyEditForm(document, request)
+ >>> print editForm()
+ <html>
+ <body>
+ <div class="layout">
+ <form action="http://127.0.0.1" method="post"
+ enctype="multipart/form-data" class="edit-form"
+ id="zc.page.browser_form">
+ <table class="form-fields">
+ <tr>
+ <td class="label">
+ <label for="form.text">
+ <span class="required">*</span><span>Text</span>
+ </label>
+ </td>
+ <td class="field">
+ <div class="form-fields-help"
+ id="field-help-for-form.text">Text attr.</div>
+ <div class="widget"><input class="textType" id="form.text"
+ name="form.text" size="20" type="text" value="foo"
+ /></div>
+ </td>
+ </tr>
+ </table>
+ <div class="form-controls">
+ <input type="submit" id="form.actions.apply"
+ name="form.actions.apply" value="Apply" class="button" />
+ </div>
+ </form>
+ </div>
+ </body>
+ </html>
+
+
+PageletSisplayForm
+~~~~~~~~~~~~~~~~~~
+
+Now let's define a display from base on the PageletDisplayForm class...
+
+ >>> class MyDisplayForm(browser.PageletDisplayForm):
+ ... form_fields = form.Fields(IDocument)
+
+and render the form:
+
+ >>> document.text = u'foo'
+ >>> displayForm = MyDisplayForm(document, request)
+ >>> print displayForm()
+ <html>
+ <body>
+ <div class="layout">
+ <form action="http://127.0.0.1" method="post"
+ enctype="multipart/form-data" class="edit-form"
+ id="zc.page.browser_form">
+ <table class="form-fields">
+ <tr>
+ <td class="label">
+ <label for="form.text">
+ <span>Text</span>
+ </label>
+ </td>
+ <td class="field">
+ <div class="form-fields-help"
+ id="field-help-for-form.text">Text attr.</div>
+ <div class="widget">foo</div>
+ </td>
+ </tr>
+ </table>
+ </form>
+ </div>
+ </body>
+ </html>
+
+
+Cleanup
+-------
+
+ >>> import shutil
+ >>> shutil.rmtree(temp_dir)
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/SETUP.cfg
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/SETUP.cfg 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/SETUP.cfg 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+ z3c.pagelet-*.zcml
+</data-files>
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/SETUP.cfg
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/__init__.py
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/__init__.py 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/__init__.py 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# 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.
+#
+##############################################################################
+"""
+$Id$
+"""
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/browser.py
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/browser.py 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/browser.py 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,117 @@
+##############################################################################
+#
+# Copyright (c) 2004 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 mixin classes
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import zope.interface
+import zope.component
+from zope.formlib import form
+from zope.pagetemplate.interfaces import IPageTemplate
+from zope.publisher import browser
+
+from z3c.template.interfaces import ILayoutTemplate
+from z3c.pagelet import interfaces
+
+
+# default pagelet base implementation
+class BrowserPagelet(browser.BrowserPage):
+ """Content generating pagelet with layout template support."""
+
+ zope.interface.implements(interfaces.IPagelet)
+
+ template = None
+ layout = None
+
+ def update(self):
+ pass
+
+ def render(self):
+ # render content template
+ if self.template is None:
+ template = zope.component.getMultiAdapter(
+ (self, self.request), IPageTemplate)
+ return template(self)
+ return self.template()
+
+ def __call__(self):
+ """Calls update and returns the layout template which calls render."""
+ self.update()
+ if self.layout is None:
+ layout = zope.component.getMultiAdapter((self, self.request),
+ ILayoutTemplate)
+ return layout(self)
+ return self.layout()
+
+
+# formlib based pagelet mixin classes
+class PageletForm(form.FormBase, BrowserPagelet):
+ """Fomr mixin for pagelet implementations."""
+
+ zope.interface.implements(interfaces.IPageletForm)
+
+ template = None
+ layout = None
+
+ __init__ = BrowserPagelet.__init__
+
+ __call__ = BrowserPagelet.__call__
+
+ def render(self):
+ # if the form has been updated, it will already have a result
+ if self.form_result is None:
+ if self.form_reset:
+ # we reset, in case data has changed in a way that
+ # causes the widgets to have different data
+ self.resetForm()
+ self.form_reset = False
+ if self.template is None:
+ template = zope.component.getMultiAdapter(
+ (self, self.request), IPageTemplate)
+ self.form_result = template(self)
+ else:
+ self.form_result = self.template()
+
+ return self.form_result
+
+
+class PageletAddForm(PageletForm, form.AddFormBase):
+ """Add form mixin for pagelet implementations."""
+
+ zope.interface.implements(interfaces.IPageletAddForm)
+
+ def render(self):
+ if self._finished_add:
+ self.request.response.redirect(self.nextURL())
+ return ""
+ # render content template
+ if self.template is None:
+ template = zope.component.getMultiAdapter(
+ (self, self.request), IPageTemplate)
+ return template(self)
+ return self.template()
+
+
+class PageletEditForm(PageletForm, form.EditFormBase):
+ """Edit form mixin for pagelet implementations."""
+
+ zope.interface.implements(interfaces.IPageletEditForm)
+
+
+class PageletDisplayForm(PageletForm, form.DisplayFormBase):
+ """Display fomr mixin for pagelet implementations."""
+
+ zope.interface.implements(interfaces.IPageletDisplayForm)
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/browser.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/configure.zcml
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/configure.zcml 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/configure.zcml 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,15 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ i18n_domain="z3c">
+
+ <!-- Pagelet renderer is used for calling the pagelets render method. -->
+ <adapter
+ name="pagelet"
+ for="zope.interface.Interface
+ zope.publisher.interfaces.browser.IBrowserRequest
+ .interfaces.IPagelet"
+ provides="zope.contentprovider.interfaces.IContentProvider"
+ factory=".provider.PageletRenderer"
+ />
+
+</configure>
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/form.pt
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/form.pt 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/form.pt 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,77 @@
+<metal:block define-macro="form">
+ <form action="." method="post" enctype="multipart/form-data"
+ metal:define-macro="master"
+ tal:attributes="action request/URL"
+ class="edit-form"
+ id="zc.page.browser_form">
+ <h1 metal:define-slot="heading"
+ i18n:translate=""
+ tal:condition="view/label"
+ tal:content="view/label">Do something</h1>
+ <div class="form-status"
+ tal:define="status view/status"
+ tal:condition="status">
+ <div class="summary" tal:content="view/status" i18n:translate="">
+ Form status summary
+ </div>
+ <ul class="errors" tal:condition="view/errors">
+ <li tal:repeat="error view/error_views">
+ <span tal:replace="structure error">Error Type</span>
+ </li>
+ </ul>
+ </div>
+ <div metal:define-slot="extra_info" tal:replace="nothing">
+ </div>
+ <table class="form-fields">
+ <tr class="row" metal:define-slot="extra_top" tal:replace="nothing">
+ <td class="label">
+ Extra top
+ </td>
+ <td class="label">
+ <input type="text" />
+ </td>
+ </tr>
+ <tbody metal:define-slot="formbody" tal:omit-tag="">
+ <tr tal:repeat="widget view/widgets">
+ <td class="label" metal:define-macro="labelcell">
+ <label tal:attributes="for widget/name">
+ <span class="required" tal:condition="widget/required"
+ >*</span><span i18n:translate=""
+ tal:content="widget/label">label</span>
+ </label>
+ </td>
+ <td class="field" tal:define="hint widget/hint"
+ metal:define-macro="widgetcell">
+ <div class="form-fields-help"
+ tal:condition="hint"
+ tal:content="hint"
+ tal:attributes="id string:field-help-for-${widget/name}"
+ i18n:translate="">
+ Title of this content object.
+ </div>
+ <div class="widget" tal:content="structure widget">
+ <input type="text" />
+ </div>
+ <div class="error"
+ tal:condition="widget/error">
+ <span tal:replace="structure widget/error">error</span>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ <tr class="row" metal:define-slot="extra_bottom" tal:replace="nothing">
+ <td class="label">
+ Extra bottom
+ </td>
+ <td class="label">
+ <input type="text" />
+ </td>
+ </tr>
+ </table>
+ <div class="form-controls" metal:define-slot="bottom_buttons"
+ tal:condition="view/availableActions">
+ <input tal:repeat="action view/actions"
+ tal:replace="structure action/render" />
+ </div>
+ </form>
+</metal:block>
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/form.pt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/interfaces.py
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/interfaces.py 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/interfaces.py 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,43 @@
+##############################################################################
+#
+# Copyright (c) 2005 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 zope.contentprovider.interfaces
+from zope.publisher.interfaces.browser import IBrowserPage
+
+
+class IPageletRenderer(zope.contentprovider.interfaces.IContentProvider):
+ """Renders a pagelet by calling it's render method."""
+
+
+class IPagelet(IBrowserPage):
+ """The pagelet."""
+
+
+class IPageletForm(IPagelet):
+ """Form mixin for pagelet implementation."""
+
+
+class IPageletAddForm(IPageletForm):
+ """Add form mixin for pagelet implementation."""
+
+
+class IPageletEditForm(IPageletForm):
+ """Edit form mixin for pagelet implementation."""
+
+
+class IPageletDisplayForm(IPageletForm):
+ """FDisplay frm mixin for pagelet implementation."""
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/interfaces.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/meta.zcml
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/meta.zcml 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/meta.zcml 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,16 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:meta="http://namespaces.zope.org/meta">
+
+ <meta:directives namespace="http://namespaces.zope.org/z3c">
+
+ <meta:directive
+ name="pagelet"
+ schema=".zcml.IPageletDirective"
+ handler=".zcml.pageletDirective"
+ />
+
+ </meta:directives>
+
+</configure>
+
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/meta.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/provider.py
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/provider.py 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/provider.py 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,43 @@
+##############################################################################
+#
+# Copyright (c) 2005 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 zope.interface
+import zope.component
+from zope.publisher.interfaces import browser
+
+from z3c.pagelet import interfaces
+
+
+class PageletRenderer(object):
+ """Render the adapted pagelet."""
+
+ zope.interface.implements(interfaces.IPageletRenderer)
+
+ zope.component.adapts(zope.interface.Interface, browser.IBrowserRequest,
+ interfaces.IPagelet)
+
+ def __init__(self, context, request, pagelet):
+ self.__updated = False
+ self.__parent__ = pagelet
+ self.context = context
+ self.request = request
+
+ def update(self):
+ pass
+
+ def render(self):
+ return self.__parent__.render()
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/provider.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/tests.py
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/tests.py 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/tests.py 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,87 @@
+##############################################################################
+#
+# Copyright (c) 2005 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$
+"""
+__docformat__ = "reStructuredText"
+
+import unittest
+
+import zope.component
+import zope.schema
+import zope.traversing.adapters
+import zope.app.form.interfaces
+import zope.app.form.browser
+import zope.app.form.browser.exception
+import zope.app.form.browser.interfaces
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.testing import doctest
+from zope.testing.doctestunit import DocFileSuite
+from zope.app.form.interfaces import IInputWidget
+from zope.app.testing import setup
+from zope.formlib import form
+
+
+def setUp(test):
+ root = setup.placefulSetUp(site=True)
+ test.globs['root'] = root
+
+ zope.component.provideAdapter(
+ zope.traversing.adapters.DefaultTraversable,
+ [None],
+ )
+
+ # register provider TALES
+ from zope.app.pagetemplate import metaconfigure
+ from zope.contentprovider import tales
+ metaconfigure.registerType('provider', tales.TALESProviderExpression)
+
+ # setup widgets
+ zope.component.provideAdapter(zope.app.form.browser.TextWidget,
+ [zope.schema.interfaces.ITextLine, IBrowserRequest],
+ IInputWidget)
+
+ zope.component.provideAdapter(
+ zope.app.form.browser.exception.WidgetInputErrorView,
+ [zope.app.form.interfaces.IWidgetInputError,
+ zope.publisher.interfaces.browser.IBrowserRequest,
+ ],
+ zope.app.form.browser.interfaces.IWidgetInputErrorView,
+ )
+ zope.component.provideAdapter(
+ zope.app.form.browser.UnicodeDisplayWidget,
+ [zope.schema.interfaces.ITextLine,
+ zope.publisher.interfaces.browser.IBrowserRequest,
+ ],
+ zope.app.form.interfaces.IDisplayWidget,
+ )
+ zope.component.provideAdapter(form.render_submit_button, name='render')
+
+def tearDown(test):
+ setup.placefulTearDown()
+
+
+def test_suite():
+ return unittest.TestSuite((
+ DocFileSuite('README.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ DocFileSuite('zcml.txt', setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,),
+ ))
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/tests.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-configure.zcml
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-configure.zcml 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-configure.zcml 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,6 @@
+<configure
+ xmlns:zcml="http://namespaces.zope.org/zcml">
+
+ <include package="z3c.pagelet" />
+
+</configure>
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-meta.zcml
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-meta.zcml 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-meta.zcml 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,6 @@
+<configure
+ xmlns:zcml="http://namespaces.zope.org/zcml">
+
+ <include package="z3c.pagelet" file="meta.zcml" />
+
+</configure>
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/z3c.pagelet-meta.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/zcml.py
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/zcml.py 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/zcml.py 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,116 @@
+##############################################################################
+#
+# Copyright (c) 2005 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$
+"""
+__docformat__ = "reStructuredText"
+
+import zope.interface
+import zope.component
+import zope.schema
+import zope.configuration.fields
+import zope.security.checker
+import zope.security.zcml
+from zope.configuration.exceptions import ConfigurationError
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+
+from zope.app.publisher.browser import viewmeta
+from zope.app.component import metadirectives
+
+from z3c.pagelet import interfaces
+from z3c.pagelet import browser
+
+
+class IPageletDirective(metadirectives.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.
+ """
+
+ name = zope.schema.TextLine(
+ title=u"The name of the pagelet.",
+ description=u"The name shows up in URLs/paths. For example 'foo'.",
+ required=True)
+
+ class_ = zope.configuration.fields.GlobalObject(
+ title=u"Class",
+ description=u"A class that provides attributes used by the pagelet.",
+ required=True,
+ )
+
+ permission = zope.security.zcml.Permission(
+ title=u"Permission",
+ description=u"The permission needed to use the pagelet.",
+ required=True
+ )
+
+ for_ = zope.configuration.fields.GlobalObject(
+ title=u"The interface or class this pagelet is for.",
+ required=False
+ )
+
+
+# Arbitrary keys and values are allowed to be passed to the pagelet.
+IPageletDirective.setTaggedValue('keyword_arguments', True)
+
+
+# pagelet directive
+def pageletDirective(
+ _context, class_, name, permission, for_=zope.interface.Interface,
+ layer=IDefaultBrowserLayer, allowed_interface=None,
+ allowed_attributes=None, **kwargs):
+
+ # Security map dictionary
+ required = {}
+
+ # Get the permission; mainly to correctly handle CheckerPublic.
+ permission = viewmeta._handle_permission(_context, permission)
+
+ # The class must be specified.
+ if not class_:
+ raise ConfigurationError("Must specify a class.")
+
+ # Build a new class that we can use different permission settings if we
+ # use the class more then once.
+ cdict = {}
+ cdict['__name__'] = name
+ cdict.update(kwargs)
+ new_class = type(class_.__name__, (class_, browser.BrowserPagelet), cdict)
+
+ # Set up permission mapping for various accessible attributes
+ viewmeta._handle_allowed_interface(
+ _context, allowed_interface, permission, required)
+ viewmeta._handle_allowed_attributes(
+ _context, allowed_attributes, permission, required)
+ viewmeta._handle_allowed_attributes(
+ _context, kwargs.keys(), permission, required)
+ viewmeta._handle_allowed_attributes(
+ _context, ('__call__', 'browserDefault', 'update', 'render',
+ 'publishTraverse'), permission, required)
+
+ # Register the interfaces.
+ viewmeta._handle_for(_context, for_)
+
+ # Create the security checker for the new class
+ zope.security.checker.defineChecker(new_class,
+ zope.security.checker.Checker(required))
+
+ # register pagelet
+ _context.action(
+ discriminator = ('pagelet', for_, layer, name),
+ callable = zope.component.zcml.handler,
+ args = ('registerAdapter',
+ new_class, (for_, layer), interfaces.IPagelet,
+ name, _context.info),)
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/zcml.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.pagelet/trunk/src/z3c/pagelet/zcml.txt
===================================================================
--- z3c.pagelet/trunk/src/z3c/pagelet/zcml.txt 2007-01-18 01:03:08 UTC (rev 72086)
+++ z3c.pagelet/trunk/src/z3c/pagelet/zcml.txt 2007-01-18 01:03:33 UTC (rev 72087)
@@ -0,0 +1,104 @@
+=================
+Pagelet directive
+=================
+
+Show how we can use the pagelet directive. Register the meta configuration for
+the directive.
+
+ >>> import sys
+ >>> from zope.configuration import xmlconfig
+ >>> import z3c.pagelet
+ >>> context = xmlconfig.file('meta.zcml', z3c.pagelet)
+
+We need also a custom pagelet class:
+
+ >>> from z3c.pagelet.browser import BrowserPagelet
+ >>> class MyPagelet(BrowserPagelet):
+ ... """Custom pagelet"""
+
+Make them available under the fake package ``custom``:
+
+ >>> sys.modules['custom'] = type(
+ ... 'Module', (),
+ ... {'MyPagelet': MyPagelet})()
+
+Register a pagelet within the directive with minimal attributes:
+
+ >>> context = xmlconfig.string("""
+ ... <configure
+ ... xmlns:z3c="http://namespaces.zope.org/z3c">
+ ... <z3c:pagelet
+ ... name="index.html"
+ ... class="custom.MyPagelet"
+ ... permission="zope.Public"
+ ... />
+ ... </configure>
+ ... """, context)
+
+Let's get the pagelet
+
+ >>> import zope.component
+ >>> from zope.publisher.browser import TestRequest
+ >>> pagelet = zope.component.queryMultiAdapter((object(), TestRequest()),
+ ... name='index.html')
+
+and check them:
+
+ >>> pagelet
+ <z3c.pagelet.zcml.MyPagelet object at ...>
+
+ >>> pagelet.context
+ <object object at ...>
+
+Register the pagelet with a different name and more attributes provided from
+the directive. We also use a custom attribute called label here. Let's define
+some more components...
+
+ >>> class SecondPagelet(BrowserPagelet):
+ ... label = u''
+
+ >>> import zope.interface
+ >>> class IContent(zope.interface.Interface):
+ ... """Content interface."""
+ >>> class Content(object):
+ ... zope.interface.implements(IContent)
+
+register the new classes in the custom module...
+
+ >>> sys.modules['custom'].IContent = IContent
+ >>> sys.modules['custom'].Content = Content
+ >>> sys.modules['custom'].SecondPagelet = SecondPagelet
+
+and use them in the directive:
+
+ >>> context = xmlconfig.string("""
+ ... <configure
+ ... xmlns:z3c="http://namespaces.zope.org/z3c">
+ ... <z3c:pagelet
+ ... name="custom.html"
+ ... class="custom.SecondPagelet"
+ ... for="custom.IContent"
+ ... permission="zope.Public"
+ ... label="my Label"
+ ... />
+ ... </configure>
+ ... """, context)
+
+Get the pagelet for the new content object
+
+ >>> import zope.component
+ >>> from zope.publisher.browser import TestRequest
+ >>> pagelet = zope.component.queryMultiAdapter((Content(), TestRequest()),
+ ... name='custom.html')
+
+and check them:
+
+ >>> pagelet
+ <z3c.pagelet.zcml.SecondPagelet object at ...>
+
+ >>> pagelet.label
+ u'my Label'
+
+Now we need to clean up the custom module.
+
+ >>> del sys.modules['custom']
Property changes on: z3c.pagelet/trunk/src/z3c/pagelet/zcml.txt
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Checkins
mailing list