[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