[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/ Reinterpretation of the pagelet code. Now pagelet's are really just a

Stephan Richter srichter at cosmos.phy.tufts.edu
Fri Sep 16 16:44:54 EDT 2005


Log message for revision 38498:
  Reinterpretation of the pagelet code. Now pagelet's are really just a 
  special kind of page/view that are also qualified (read adapted) by the 
  view and slot they are part of in adition to the context and the request, 
  common for views.
  
  I had to temporarly remove some packages that depended on pagelets. They 
  need some interpretation too, and we will do this on a branch.
  
  

Changed:
  D   Zope3/trunk/src/zope/app/boston/
  D   Zope3/trunk/src/zope/app/demo/pagelet/
  D   Zope3/trunk/src/zope/app/demo/pageletchooser/
  U   Zope3/trunk/src/zope/app/pagelet/README.txt
  D   Zope3/trunk/src/zope/app/pagelet/collector.py
  U   Zope3/trunk/src/zope/app/pagelet/configure.zcml
  A   Zope3/trunk/src/zope/app/pagelet/directives.txt
  D   Zope3/trunk/src/zope/app/pagelet/exceptions.py
  U   Zope3/trunk/src/zope/app/pagelet/interfaces.py
  U   Zope3/trunk/src/zope/app/pagelet/meta.zcml
  U   Zope3/trunk/src/zope/app/pagelet/metaconfigure.py
  U   Zope3/trunk/src/zope/app/pagelet/metadirectives.py
  A   Zope3/trunk/src/zope/app/pagelet/pagelet.py
  U   Zope3/trunk/src/zope/app/pagelet/tales.py
  U   Zope3/trunk/src/zope/app/pagelet/tests/__init__.py
  D   Zope3/trunk/src/zope/app/pagelet/tests/pagelets.zcml
  D   Zope3/trunk/src/zope/app/pagelet/tests/test_directives.py
  A   Zope3/trunk/src/zope/app/pagelet/tests/test_doc.py
  A   Zope3/trunk/src/zope/app/pagelet/tests/test_pagelet.pt
  D   Zope3/trunk/src/zope/app/pagelet/tests/test_pagelet.py
  D   Zope3/trunk/src/zope/app/pagelet/tests/testfiles/
  D   Zope3/trunk/src/zope/app/pageletchooser/
  D   Zope3/trunk/src/zope/app/skintools/

-=-
Modified: Zope3/trunk/src/zope/app/pagelet/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/README.txt	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/README.txt	2005-09-16 20:44:54 UTC (rev 38498)
@@ -2,8 +2,17 @@
 Pagelets
 ========
 
-Definition
+This package provides a framework to develop componentized Web GUI
+applications. Instead of describing the content of a page using a single
+template or static system of templates and METAL macros, regions (called
+slots) can be defined and are filled dynamically with content based on the
+setup of the application.
+
+The Design
 ----------
+
+UML Diagram
+~~~~~~~~~~~
                       _________
                      |         |
                      | Context |
@@ -38,192 +47,304 @@
         | Pagelet |               | Portlet |
         |_________|               |_________|
 
-A view instance is associated with one context. A context may be viewed
-with none ore more views.
+Natively, Zope 3 allows us to associate one or more views to a given
+object. Those views are either registered for the provided interfaces of the
+object or the object itself. In a view, usually a template, one can define
+zero or more view slots. Upon rendering time, those view slots are populated
+with the viewlets that have been assigned to the slot.
 
-The distinction between Pagelet and Portlet is still fuzzy. Pagelets and
-portlets are designed to be parts of a view. In that meaning pagelets
-and portlets are equal. They are specialized viewlets. A view is composed
-of viewlets which are related to a specific slot of that view.
 
-But what is the difference between them? The reconstructed interpretation
-of Zope's common sense is the following::
+The Difference betwen a Pagelet and a Portlet
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    A pagelet of a view displays the underlying context.
-    A portlet of a view displays data from different contexts.
+Let's start with the properties the two share. Pagelets and portlets are
+designed to be parts of a view; they are specialized viewlets. In the Zope
+world the difference is commonly seen as follows:
 
-    Examples: The metadata pagelet displays the metadata of
-    the underlying context. The metadata portlet displays for
-    example the metadata of all its children.
+  * A pagelet of a view displays the underlying context.
 
-    A calendar pagelet displays the calendar data of a content
-    object that implements an own calendar. A calendar portlet
-    displays global calendar data on different objects that may
-    come from an utility for example.
+  * A portlet of a view displays data from different contexts.
 
+For example, the metadata pagelet displays the metadata of the underlying
+context. A metadata portlet, on the other hand, could display the metadata of
+all of the context's children (assuming the context is a container). In a
+second example, a calendar pagelet displays the calendar data of a content
+object that implements its own calendar, while a calendar portlet displays
+global calendar data on different objects that may come from an utility.
 
-In view of the component architecture this differentiation does not make
-sense anymore, because the adaption mechanism hides such criteria
-(implementation decisions and details) transparently inside an adapter.
+The above definitions need to be altered slightly when talking in terms of
+Zope 3, since the adaption mechanism used for looking up views hides the data
+retrieval from the user. Thus, let's slightly reword the definitions:
 
-That is the reason, why we try to provide a new definition::
+  * A pagelet of a view operates on the underlying context.
 
-    A pagelet of a view operates of the underlying context.
-    A portlet of a view operates of the underlying or a
-    different context.
+  * A portlet of a view operates on the underlying or on a different context.
 
-    Examples: The metadata pagelet displays the metadata.
-    Therefore it adapts the underlying context to IMetadata.
-    The metadata portlet displays metadata too, but it adapts
-    a context independently to the underlying view context.
+Rephrasing our examples, we have: The metadata pagelet displays the metadata
+of the view context by adapting it to ``IMetadata``. The portlet, on the other
+hand, adapts to a context independent of the underlying view context.
 
-    Hence several pagelets of the same type composed inside
-    one view must display always the similar content where
-    several portlets of the same type composed inside a view
-    can present different contents.
+Therefore, a set of pagelets of the same type inside a particular views must
+always display similar content, while a set of portlets of the same type can
+provide a wide range of contents from very different parts of the site.
 
 
 Usage
 -----
-This pagelet implementation supports pagelets and portlets in respect of
-the first definition, but it only supports pagelets in respect of the
-second definition.
 
-In the following text we us pagelet in the sense of the latter.
+This pagelet implementation supports pagelets of the first and second
+definition, but portlets only of the first. In the following text we use the
+term "pagelet" as defined in the second definition.
 
-Pagelets are responsible for a piece of content in a view. They can be
-used to render additionally provided information into a pagetemplate.
+Pagelets are responsible for a piece of content in a view. They can be used to
+provide additionally information about an object that is not fully relevant
+for the view's functionality, but provides useful information and/or links to
+the user. Pagelets are small, view-like components that are identified by the
+following set of interfaces they are registered for:
 
-Pagelets are small, view-like components that can registered to
-skin layers(request)-, contenttype-, view- and slot-interfaces.
+  * Layer: The layer in which the pagelet will be used.
 
-Inside a pagetemplate of a view, the registered pagelets can be called by
-the tal:pagelets command. The return value is a list of macros where each
-macro correspondents to a registered pagelet. The pagelet engine always uses
-the macro from the pagelet which has the same name like the pagelet itself.
-This macros can be used to invoke the pagelets:
+  * Content Type: The interface the context of the the view must provide. This
+    is the ``for`` attribute of the view and pagelet directive.
 
+  * View: The interface the view must provide. By default this is
+    ``IBrowserView`` and the default is commonly not changed.
+
+  * Slot: The instance of the slot in which this pagelet can be placed.
+
+Inside a pagetemplate the pagelets of a particular slot can be retrieved using
+the ``pagelets`` TALES namespace. The return value is a sequence of pagelet
+objects that can simply be called. The pagelets are selected by the four
+above-mentioned parameters and sorted by the weight of the pagelets::
+
   <div class="row">
-    <tal:repeat="pagelets pagelets:zope.app.demo.pagelet.interfaces.IDemoSlot">
-      <tal:block metal:use-macro="pagelets" />
+    <tal:repeat="pagelet pagelets:path.to.Slot">
+      <tal:block replace="structure pagelet" />
     </tal:repeat>
   </div>
 
-Such a macro may process static content or invoke the context- or
-view-namespace for dynamic contents::
 
-  <div class="row">
-    <h4>content:</h4>
-    <span tal:content="view/title">title</span>
-  </div>
+An Example
+----------
 
-The latter is not recommended, because it glues view and pagelet together.
-That means a pagelet depends on a specific view- or context implementation.
+Before we even start demonstrating the template, we need to register the
+`pagelets` TALES namespace:
 
-In respect of modularization we provide an additional tal:pagedata
-command. This command allows to look up adapters providing an interface
-derived form IPageletData::
+  >>> from zope.app.pagetemplate import metaconfigure
+  >>> from zope.app.pagelet import tales
+  >>> metaconfigure.registerType('pagelets', tales.TALESPageletsExpression)
 
-  <div class="row">
-    <tal:define="data pagedata:zope.app.demo.pagelet.interfaces.IDemoPageData">
-      <h4>content:</h4>
-      <span tal:content="data/title">title</span>
-    </tal:define>
-  </div>
+The first task will be to create a slot that we can use in a pagetemplate. A
+slot is simply an interface that simply needs to provide ``IPageletSlot``. The
+interface is then registered as a utility providing the interface.
 
-This is a restricted adapter invocation. It should prevent uncontrolled
-adapter invocation inside pagetemplates, because that would glue view
-layer and programming layer in not appreciable manner.
+  >>> import zope.interface
+  >>> class IDemoSlot(zope.interface.Interface):
+  ...     '''A slot for demonstration purposes.'''
 
+  >>> from zope.app.pagelet import interfaces
+  >>> zope.interface.directlyProvides(IDemoSlot, interfaces.IPageletSlot)
 
-Let's show how to use pagelets
-==============================
+  >>> import zope.component
+  >>> zope.component.provideUtility(IDemoSlot, interfaces.IPageletSlot,
+  ...                               'DemoSlot')
 
-Imports:
+The argument to the slot class is commonly used for documentations. Next we
+can create pagelets for this Now we can create a page template that uses this
+slot object to define a slot in the template:
 
-  >>> import zope.component
-  >>> from zope.app import zapi
-  >>> from zope.interface import Interface
-  >>> from zope.security.checker import defineChecker
-  >>> from zope.publisher.browser import TestRequest
-  >>> from zope.publisher.interfaces.browser import IBrowserRequest
-  >>> from zope.component.interfaces import IView
-  >>> from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+  >>> import os, tempfile
+  >>> temp_dir = tempfile.mkdtemp()
+
+  >>> zpt_filename = os.path.join(temp_dir, 'template.pt')
+  >>> open(zpt_filename, 'w').write('''
+  ... <html>
+  ...   <body>
+  ...     <h1>Pagelet Demo</h1>
+  ...     <div class="left-column">
+  ...       <div class="column-item"
+  ...            tal:repeat="pagelet pagelets:DemoSlot">
+  ...         <tal:block replace="structure pagelet" />
+  ...       </div>
+  ...     </div>
+  ...   </body>
+  ... </html>
+  ... ''')
+
+Now that the template is created, we register the template as a browser page
+view:
+
+  >>> from zope.app.pagetemplate.simpleviewclass import SimpleViewClass
+  >>> DemoPage = SimpleViewClass(zpt_filename, name='demo.html')
+
+  >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+  >>> zope.component.provideAdapter(
+  ...     DemoPage,
+  ...     (zope.interface.Interface, IDefaultBrowserLayer),
+  ...     zope.interface.Interface,
+  ...     name='demo.html')
+
+In the following step we will create a couple of pagelets that are used in the
+demo page. Pagelets are really views, except that they additionally adapt
+their view and slot. The first pagelet is a minimalistic implementation:
+
   >>> from zope.app.publisher.browser import BrowserView
-  >>> from zope.app.pagelet.interfaces import IPagelet
-  >>> from zope.app.pagelet.interfaces import IPageletSlot
-  >>> from zope.app.pagelet.interfaces import IMacrosCollector
-  >>> from zope.app.pagelet.tales import TALESPageletsExpression
-  >>> from zope.app.pagelet.collector import MacrosCollector
-  >>> from zope.app.pagelet.tests import TestPagelet
-  >>> from zope.app.pagelet.tests import TestContext
-  >>> from zope.app.pagelet.tests import testChecker
+  >>> class Pagelet1(BrowserView):
+  ...     weight = 0
+  ...
+  ...     def __init__(self, context, request, view, slot):
+  ...         super(Pagelet1, self).__init__(context, request)
+  ...
+  ...     def __call__(self):
+  ...         return u'<h3>Pagelet 1 Content</h3>'
 
-Setup:
+  >>> from zope.security.checker import NamesChecker, defineChecker
+  >>> pageletChecker = NamesChecker(('__call__', 'weight'))
+  >>> defineChecker(Pagelet1, pageletChecker)
 
-  >>> gsm = zapi.getGlobalSiteManager()
+  >>> from zope.interface import Interface, providedBy
+  >>> from zope.app.publisher.interfaces.browser import IBrowserView
+  >>> zope.component.provideAdapter(
+  ...     Pagelet1,
+  ...     (Interface, IDefaultBrowserLayer, IBrowserView, IDemoSlot),
+  ...     interfaces.IPagelet,
+  ...     name='pagelet1')
 
-Register slot interface:
+Let's now register a more typical pagelet. We first create a template:
 
-  >>> from zope.app.component.interface import provideInterface
-  >>> provideInterface('', IPageletSlot, None)
+  >>> plt_filename = os.path.join(temp_dir, 'pagelet2.pt')
+  >>> open(plt_filename, 'w').write('''
+  ...         <div class="box">
+  ...           <tal:block replace="pagelet/title" />
+  ...         </div>
+  ... ''')
 
-Register TALES pagelet expression:
+  >>> class Pagelet2Base(object):
+  ...     def title(self):
+  ...         return 'Pagelet 2 Content'
 
-  >>> from zope.app.pagetemplate.metaconfigure import registerType
-  >>> registerType('pagelets', TALESPageletsExpression)
+As you can see, the pagelet Python class is known as ``pagelet``, while the
+view class is still available as ``view``. Next we build and register the
+pagelet using a special helper function:
 
-Define a pagelet in a ZCML directive pagelet like:
+  >>> from zope.app.pagelet import pagelet
+  >>> Pagelet2 = pagelet.SimplePageletClass(
+  ...     plt_filename, bases=(Pagelet2Base,), name='pagelet2', weight=1)
 
-<zope:pagelet
-  name="demopagelet"
-  layer="zope.publisher.interfaces.browser.IBrowserRequest"
-  slot="zope.app.pagelet.interfaces.IPageletSlot"
-  template="path_to/pagelet.pt"
-  for="*"
-  permission="zope.View"
-  weight="0"
-  />
+  >>> defineChecker(Pagelet2, pageletChecker)
 
-Setup a test pagelet:
+  >>> zope.component.provideAdapter(
+  ...     Pagelet2,
+  ...     (Interface, IDefaultBrowserLayer, IBrowserView, IDemoSlot),
+  ...     interfaces.IPagelet,
+  ...     name='pagelet2')
 
-  >>> name = 'testpagelet'
-  >>> pagelet_factory = TestPagelet
-  >>> defineChecker(pagelet_factory, testChecker)
-  >>> gsm.provideAdapter(
-  ...        (Interface, IBrowserRequest, IView, IPageletSlot)
-  ...        , IPagelet, name, pagelet_factory)
+Now all the setup is completed. Let's create a content object:
 
-Register pagelet collector as a adapter:
+  >>> class Content(object):
+  ...     zope.interface.implements(zope.interface.Interface)
 
-  >>> collector_factory = MacrosCollector
-  >>> gsm.provideAdapter(
-  ...        (Interface, IBrowserRequest, IView, IPageletSlot)
-  ...        , IMacrosCollector, '', collector_factory)
+  >>> content = Content()
 
-Setup a simply browser view with a 'index_pagelets.pt' template:
+and finally, we look up the view and render it:
 
-  >>> ob = TestContext()
+  >>> from zope.publisher.browser import TestRequest
   >>> request = TestRequest()
-  >>> view = BrowserView(ob, request)
 
-Setup a view page template called 'index':
+  >>> view = zope.component.getMultiAdapter((content, request),
+  ...                                       name='demo.html')
+  >>> print view().strip()
+  <html>
+    <body>
+      <h1>Pagelet Demo</h1>
+      <div class="left-column">
+        <div class="column-item">
+          <h3>Pagelet 1 Content</h3>
+        </div>
+        <div class="column-item">
+  <BLANKLINE>
+          <div class="box">
+            Pagelet 2 Content
+          </div>
+  <BLANKLINE>
+        </div>
+      </div>
+    </body>
+  </html>
 
-  >>> from zope.app.pagelet.tests import testfiles
-  >>> import os.path
-  >>> path = os.path.dirname(testfiles.__file__)
-  >>> index = ViewPageTemplateFile('index_pagelets.pt', path)
+Note that if we turn the weight around,
 
-Call the 'index' (view) on the browser view instance the sample pagelet
-'index_pagelets.pt' calls pagelets registered for the slot
-'zope.app.pagelet.interfaces.IPageletSlot'. We registred the
-'test_pagelet' for this slot in the TestPagelet class. For more info
-take a look at the index_pagelets.pt' file in the tests/testfiles folder:
+  >>> Pagelet1.weight = 1
+  >>> Pagelet2._weight = 0
 
-  >>> html = index(view, request)
+the order of the left column in the page template shoudl change:
 
-Test if the pagelet content is in the html output:
+  >>> print view().strip()
+  <html>
+    <body>
+      <h1>Pagelet Demo</h1>
+      <div class="left-column">
+        <div class="column-item">
+  <BLANKLINE>
+          <div class="box">
+            Pagelet 2 Content
+          </div>
+  <BLANKLINE>
+        </div>
+        <div class="column-item">
+          <h3>Pagelet 1 Content</h3>
+        </div>
+      </div>
+    </body>
+  </html>
 
-  >>> import string
-  >>> string.count(html, 'testpagelet macro content')
-  1
+
+Looking up a pagelet by name
+----------------------------
+
+In some cases you want to be able to look up a particular pagelet for a slot,
+given a context and a view. For this use case, you can simply use a second
+TALES namespace called ``pagelet`` that selects the pagelet using the
+expression ``<path to slot>/<pagelet name>``.
+
+  >>> metaconfigure.registerType('pagelet', tales.TALESPageletExpression)
+
+Since everything else is already setup, we can simply register a new view:
+
+  >>> zpt_filename2 = os.path.join(temp_dir, 'template2.pt')
+  >>> open(zpt_filename2, 'w').write('''
+  ... <html>
+  ...   <body>
+  ...     <h1>Pagelet Demo</h1>
+  ...     <div class="left-column">
+  ...       <div class="column-item">
+  ...         <tal:block replace="structure pagelet:DemoSlot/pagelet1" />
+  ...       </div>
+  ...     </div>
+  ...   </body>
+  ... </html>
+  ... ''')
+
+  >>> DemoPage2 = SimpleViewClass(zpt_filename2, name='demo2.html')
+  >>> zope.component.provideAdapter(
+  ...     DemoPage2,
+  ...     (zope.interface.Interface, IDefaultBrowserLayer),
+  ...     zope.interface.Interface,
+  ...     name='demo2.html')
+
+  >>> view = zope.component.getMultiAdapter((content, request),
+  ...                                       name='demo2.html')
+  >>> print view().strip()
+  <html>
+    <body>
+      <h1>Pagelet Demo</h1>
+      <div class="left-column">
+        <div class="column-item">
+          <h3>Pagelet 1 Content</h3>
+        </div>
+      </div>
+    </body>
+  </html>
+
+Note that this namespace returns the rendered pagelet and not the pagelet
+view, like the ``pagelets`` TALES namespace.

Deleted: Zope3/trunk/src/zope/app/pagelet/collector.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/collector.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/collector.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -1,200 +0,0 @@
-##############################################################################
-#
-# 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 collectors
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-from zope.interface import implements
-from zope.security import canAccess
-from zope.security.interfaces import Unauthorized
-
-from zope.app import zapi
-
-from zope.app.pagelet.interfaces import IPagelet
-from zope.app.pagelet.interfaces import IMacrosCollector
-from zope.app.pagelet.interfaces import IMacroCollector
-
-
-
-class MacrosCollector(object):
-    """Replaceable sample implementation of IMacrosCollector.
-
-    Collects pagelets from the site manager.
-    Pagelet adapters are registred on context, request, view and slot
-    interfaces. Use your own IMacrosCollector implementation for
-    to support a layout manager.
-
-    Imports:
-
-        >>> from zope.interface import Interface
-        >>> from zope.security.checker import defineChecker
-        >>> from zope.publisher.browser import TestRequest
-        >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-        >>> from zope.component.interfaces import IView
-        >>> from zope.app.publisher.browser import BrowserView
-        >>> from zope.app.pagelet.interfaces import IPagelet
-        >>> from zope.app.pagelet.interfaces import IPageletSlot
-        >>> from zope.app.pagelet.tests import TestPagelet
-        >>> from zope.app.pagelet.tests import TestContext
-        >>> from zope.app.pagelet.tests import TestSlot
-        >>> from zope.app.pagelet.tests import testChecker
-
-    Setup pagelet:
-
-        >>> name = 'testpagelet'
-        >>> factory = TestPagelet
-
-    Register the pagelet class as a factory on the site manager:
-
-        >>> from zope.app.testing import placelesssetup, ztapi
-        >>> placelesssetup.setUp()
-        >>> defineChecker(factory, testChecker)
-        >>> gsm = zapi.getGlobalSiteManager()
-        >>> gsm.provideAdapter(
-        ...        (Interface, IDefaultBrowserLayer, IView, IPageletSlot)
-        ...        , IPagelet, name, factory)
-
-    Setup macros collector:
-
-        >>> ob = TestContext()
-        >>> request = TestRequest()
-        >>> view = BrowserView(ob, request)
-        >>> slot = TestSlot()
-        >>> collector = MacrosCollector(ob, request, view, slot)
-
-    Get macros form the collector
-
-        >>> macros = collector.macros()
-
-    Test if we have the string form the test_pagelet in the macro:
-
-        >>> rawtextOffset = macros[0][5][1][0]
-        >>> rawtextOffset
-        u'testpagelet macro content</div>'
-
-      >>> placelesssetup.tearDown()
-
-    """
-
-    implements(IMacrosCollector)
-
-    def __init__ (self, context, request, view, slot):
-        self.context = context
-        self.request = request
-        self.view = view
-        self.slot = slot
-
-    def macros(self):
-        macros = []
-
-        # collect pagelets
-        objects = self.context, self.request, self.view, self.slot
-        pagelets = zapi.getAdapters(objects, IPagelet)
-        pagelets.sort(lambda x, y: x[1].weight - y[1].weight)
-
-        for name, pagelet in pagelets:
-            # append pagelet macros if the permission is correct pagelets
-            # are now locatable and can invoke local authentication utilities
-            if canAccess(pagelet, '__getitem__'):
-                macros.append(pagelet[name])
-
-        return macros
-
-
-
-class MacroCollector(object):
-    """Replaceable sample implementation of IMacroCollector.
-
-    Collect a single pagelet from the site manager and returns 
-    a macro by name.
-    Pagelet adapters are registred on context, request, view and slot
-    interfaces. Use your own IMacroCollector implementation for
-    to support a layout manager which can return a macro dependent
-    on additional rules.
-
-    Imports:
-
-        >>> from zope.interface import Interface
-        >>> from zope.security.checker import defineChecker
-        >>> from zope.publisher.browser import TestRequest
-        >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-        >>> from zope.component.interfaces import IView
-        >>> from zope.app.publisher.browser import BrowserView
-        >>> from zope.app.pagelet.interfaces import IPagelet
-        >>> from zope.app.pagelet.interfaces import IPageletSlot
-        >>> from zope.app.pagelet.tests import TestPagelet
-        >>> from zope.app.pagelet.tests import TestContext
-        >>> from zope.app.pagelet.tests import TestSlot
-        >>> from zope.app.pagelet.tests import testChecker
-
-    Setup pagelet:
-
-        >>> name = 'testpagelet'
-        >>> factory = TestPagelet
-
-    Register the pagelet class as a factory on the site manager:
-
-        >>> from zope.app.testing import placelesssetup, ztapi
-        >>> placelesssetup.setUp()
-        >>> defineChecker(factory, testChecker)
-        >>> gsm = zapi.getGlobalSiteManager()
-        >>> gsm.provideAdapter(
-        ...        (Interface, IDefaultBrowserLayer, IView, IPageletSlot)
-        ...        , IPagelet, name, factory)
-
-    Setup macros collector:
-
-        >>> ob = TestContext()
-        >>> request = TestRequest()
-        >>> view = BrowserView(ob, request)
-        >>> slot = TestSlot()
-        >>> collector = MacroCollector(ob, request, view, slot)
-
-    Get the macro form the collector
-
-        >>> macro = collector.__getitem__('testpagelet')
-
-    Test if we have the string form the test_pagelet.pt file in the macro:
-
-        >>> rawtextOffset = macro[5][1][0]
-        >>> rawtextOffset
-        u'testpagelet macro content</div>'
-
-      >>> placelesssetup.tearDown()
-
-    """
-
-    implements(IMacroCollector)
-
-    def __init__ (self, context, request, view, slot):
-        self.context = context
-        self.request = request
-        self.view = view
-        self.slot = slot
-
-    def __getitem__(self, key):
-        macros = []
-
-        # collect a single pagelet which is a pagelet
-        objects = self.context, self.request, self.view, self.slot
-        pagelet = zapi.getMultiAdapter(objects, IPagelet, key)
-
-        # rasie Unauthorized exception if we don't have the permission for 
-        # calling the pagelet's macro code. Pagelets are locatable.
-        if canAccess(pagelet, '__getitem__'):
-            return pagelet[key]
-        else:
-            raise Unauthorized(key)

Modified: Zope3/trunk/src/zope/app/pagelet/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/configure.zcml	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/configure.zcml	2005-09-16 20:44:54 UTC (rev 38498)
@@ -4,46 +4,16 @@
     i18n_domain="zope"
     >
 
-  <!-- tal:pagelets expression --> 
   <interface interface=".interfaces.ITALESPageletsExpression" />
-  <interface interface=".interfaces.IMacrosCollector" />
-
-  <adapter
-      for="zope.interface.Interface
-           zope.publisher.interfaces.browser.IBrowserRequest
-           zope.component.interfaces.IView
-           .interfaces.IPageletSlot"
-      factory=".collector.MacrosCollector"
-      provides=".interfaces.IMacrosCollector" />
-
   <tales:expressiontype
       name="pagelets"
       handler=".tales.TALESPageletsExpression"
       />
 
-  <!-- tal:pagelet expression --> 
   <interface interface=".interfaces.ITALESPageletExpression" />
-  <interface interface=".interfaces.IMacroCollector" />
-
-  <adapter
-      for="zope.interface.Interface
-           zope.publisher.interfaces.browser.IBrowserRequest
-           zope.component.interfaces.IView
-           .interfaces.IPageletSlot"
-      factory=".collector.MacroCollector"
-      provides=".interfaces.IMacroCollector" />
-
   <tales:expressiontype
       name="pagelet"
       handler=".tales.TALESPageletExpression"
       />
 
-  <!-- tal:pagedata expression --> 
-  <interface interface=".interfaces.ITALESPageDataExpression" />
-
-  <tales:expressiontype
-      name="pagedata"
-      handler=".tales.TALESPageDataExpression"
-      />
-
 </configure>
\ No newline at end of file

Added: Zope3/trunk/src/zope/app/pagelet/directives.txt
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/directives.txt	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/directives.txt	2005-09-16 20:44:54 UTC (rev 38498)
@@ -0,0 +1,187 @@
+=========================
+The ``pagelet`` Directive
+=========================
+
+The pagelet directive allows you to quickly register a new paglet without much
+hassle, like it was shown in the `README.txt` file. Here is a sample
+directive::
+
+  >>> from zope.configuration import xmlconfig
+  >>> context = xmlconfig.string('''
+  ... <configure i18n_domain="zope">
+  ...   <include package="zope.app.pagelet" file="meta.zcml" />
+  ... </configure>
+  ... ''')
+
+  >>> context = xmlconfig.string('''
+  ... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope"
+  ...            package="zope.app.pagelet.tests">
+  ...   <pagelet
+  ...       name="testpagelet"
+  ...       for="*"
+  ...       slot=".test_doc.ITestSlot"
+  ...       template="test_pagelet.pt"
+  ...       permission="zope.Public"
+  ...       />
+  ... </configure>
+  ... ''', context=context)
+
+As you can see, the directive looks very similar to the page directive and you
+are right. The pagelet directive does not permit you to specify a `menu` and
+`title`, since it is not sensible to have a menu item for a pagelet. However,
+it does support two more qualifying attributes, `view` and `slot`. While view
+is nearly never specified (very common default), the `slot` attribute *must*
+be specified. An optional `weight` attribute (not shown above) allows you to
+change the position of a particular pagelet relative to the others. The
+default value is zero.
+
+If we now look into the adapter registry, we will find the pagelet:
+
+  >>> class Content(object):
+  ...     pass
+  >>> content = Content()
+
+  >>> from zope.publisher.browser import TestRequest
+  >>> request = TestRequest()
+
+  >>> from zope.app.publisher.browser import BrowserView
+  >>> view = BrowserView(content, request)
+
+  >>> import zope.interface
+  >>> from zope.app.pagelet.tests.test_doc import ITestSlot
+  >>> class Slot(object):
+  ...     pass
+  >>> slot = Slot()
+  >>> zope.interface.directlyProvides(slot, ITestSlot)
+
+  >>> import zope.component
+  >>> from zope.app.pagelet.interfaces import IPagelet
+  >>> pagelet = zope.component.getMultiAdapter(
+  ...     (content, request, view, slot), IPagelet, name='testpagelet')
+  >>> pagelet()
+  u'<div>testpagelet macro content</div>\n'
+
+Let's now ensure that we can also specify a pagelet class:
+
+  >>> context = xmlconfig.string('''
+  ... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope"
+  ...            package="zope.app.pagelet.tests">
+  ...   <pagelet
+  ...       name="testpagelet2"
+  ...       for="*"
+  ...       slot=".test_doc.ITestSlot"
+  ...       template="test_pagelet.pt"
+  ...       class=".test_doc.TestPagelet"
+  ...       permission="zope.Public"
+  ...       />
+  ... </configure>
+  ... ''', context=context)
+
+  >>> pagelet = zope.component.getMultiAdapter(
+  ...     (content, request, view, slot), IPagelet, name='testpagelet2')
+  >>> pagelet()
+  u'<div>testpagelet macro content</div>\n'
+
+Okay, so the template-driven cases wrok. But just specifying a class should
+also work:
+
+  >>> context = xmlconfig.string('''
+  ... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope"
+  ...            package="zope.app.pagelet.tests">
+  ...   <pagelet
+  ...       name="testpagelet3"
+  ...       for="*"
+  ...       slot=".test_doc.ITestSlot"
+  ...       class=".test_doc.TestPagelet2"
+  ...       permission="zope.Public"
+  ...       />
+  ... </configure>
+  ... ''', context=context)
+
+  >>> pagelet = zope.component.getMultiAdapter(
+  ...     (content, request, view, slot), IPagelet, name='testpagelet3')
+  >>> pagelet()
+  u'called'
+
+It should also be possible to specify an alternative attribute of the class to
+be rendered upon calling the pagelet:
+
+  >>> context = xmlconfig.string('''
+  ... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope"
+  ...            package="zope.app.pagelet.tests">
+  ...   <pagelet
+  ...       name="testpagelet4"
+  ...       for="*"
+  ...       slot=".test_doc.ITestSlot"
+  ...       class=".test_doc.TestPagelet"
+  ...       attribute="doSomething"
+  ...       permission="zope.Public"
+  ...       />
+  ... </configure>
+  ... ''', context=context)
+
+  >>> pagelet = zope.component.getMultiAdapter(
+  ...     (content, request, view, slot), IPagelet, name='testpagelet4')
+  >>> pagelet()
+  u'something'
+
+
+Error Scenarios
+---------------
+
+Neither the class or template have been specified:
+
+  >>> context = xmlconfig.string('''
+  ... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope"
+  ...            package="zope.app.pagelet.tests">
+  ...   <pagelet
+  ...       name="testpagelet"
+  ...       slot=".test_doc.ITestSlot"
+  ...       permission="zope.Public"
+  ...       />
+  ... </configure>
+  ... ''', context=context)
+  Traceback (most recent call last):
+  ...
+  ZopeXMLConfigurationError: File "<string>", line 4.2-8.8
+      ConfigurationError: Must specify a class or template
+
+The specified attribute is not ``__call__``, but also a template has been
+specified:
+
+  >>> context = xmlconfig.string('''
+  ... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope"
+  ...            package="zope.app.pagelet.tests">
+  ...   <pagelet
+  ...       name="testpagelet"
+  ...       slot=".test_doc.ITestSlot"
+  ...       template="test_pagelet.pt"
+  ...       attribute="faux"
+  ...       permission="zope.Public"
+  ...       />
+  ... </configure>
+  ... ''', context=context)
+  Traceback (most recent call last):
+  ...
+  ZopeXMLConfigurationError: File "<string>", line 4.2-10.8
+      ConfigurationError: Attribute and template cannot be used together.
+
+Now, we are not specifying a template, but a class that does not have the
+specified attribute:
+
+  >>> context = xmlconfig.string('''
+  ... <configure xmlns="http://namespaces.zope.org/browser" i18n_domain="zope"
+  ...            package="zope.app.pagelet.tests">
+  ...   <pagelet
+  ...       name="testpagelet"
+  ...       slot=".test_doc.ITestSlot"
+  ...       class=".test_doc.TestPagelet"
+  ...       attribute="faux"
+  ...       permission="zope.Public"
+  ...       />
+  ... </configure>
+  ... ''', context=context)
+  Traceback (most recent call last):
+  ...
+  ZopeXMLConfigurationError: File "<string>", line 4.2-10.8
+    ConfigurationError: The provided class doesn't have the specified attribute


Property changes on: Zope3/trunk/src/zope/app/pagelet/directives.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Deleted: Zope3/trunk/src/zope/app/pagelet/exceptions.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/exceptions.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/exceptions.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -1,38 +0,0 @@
-##############################################################################
-#
-# 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 exceptions
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-from zope.component import ComponentLookupError
-
-from zope.app.i18n import ZopeMessageIDFactory as _
-
-
-
-
-class PageletSlotInterfaceLookupError(ComponentLookupError):
-    """IPageletSlot slot interface not found."""
-
-PageletError_slot_interface_not_found = _(
-    u'Pagelet slot interface not found.')
-
-
-class PageletSlotInterfaceNotProvidedException(Exception):
-    """IPageletSlot interface not provided."""
-
-PageletError_slot_interface_not_provided = _(
-    u'IPageletSlot interface not provided.')

Modified: Zope3/trunk/src/zope/app/pagelet/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/interfaces.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/interfaces.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -17,44 +17,51 @@
 """
 __docformat__ = 'restructuredtext'
 
-from zope.tales.interfaces import ITALESExpression
-
-from zope.interface import Interface
+from zope.component import ComponentLookupError
 from zope.interface import Attribute
+from zope.interface import Interface
+from zope.interface.interfaces import IInterface
 from zope.schema import Int
+from zope.tales.interfaces import ITALESExpression
 
 from zope.app.i18n import ZopeMessageIDFactory as _
 from zope.app.location import ILocation
-        
+from zope.app.publisher.interfaces.browser import IBrowserView
 
 
-class IPageletSlot(Interface):
+class PageletSlotLookupError(ComponentLookupError):
+    """Pagelet slot object not found."""
+
+
+class IPageletSlot(IInterface):
     """Marker interface for pagelet slots.
-    
-    The pagelet slot is used as a part ot the key for to register and 
+
+    The pagelet slot is used as a part ot the key for to register and
     collect pagelets.
     """
 
 
-
-class IPagelet(ILocation):
+class IPagelet(IBrowserView):
     """Interface for custom pagelet adapters.
-    
-    Pagelets can be used in a page template as a piece of content
-    rendered with it's own python view class. Yes with pagelets
-    you can use more then one views in a pageltemplate. This
-    let's pagelets act as portlets. The pagelet view can support
-    content independent information where you can access in every
-    page template on which the pagelet is registered.
-    
+
+    Pagelets can be used in a page template as a piece of content rendered
+    with it's own python view class. Yes with pagelets you can use more then
+    one views in a pageltemplate. This let's pagelets act as portlets. The
+    pagelet view can support content independent information where you can
+    access in every page template on which the pagelet is registered.
+
     The meta directive set the 'weight' attribute to the class attribute
-    '_weight'. If you whould like to use the settings from the meta 
-    directive point the attribute 'weight' to this default attribute.
-    
-    If you use a 'template', the meta directive sets the 'template' to 
-    the class attribute '_template'.
+    '_weight'. If you whould like to use the settings from the meta directive
+    point the attribute 'weight' to this default attribute.
+
+    If you use a 'template', the meta directive sets the 'template' to the
+    class attribute '_template'.
     """
 
+    view = Attribute('The view the pagelet is used in.')
+
+    slot = Attribute('The slot in which the pagelet is placed.')
+
     weight = Int(
         title=_(u'weight'),
         description=_(u"""
@@ -63,127 +70,31 @@
         required=False,
         default=0)
 
-    def __getitem__(name):
-        """Returns the macro code of the template by the given name."""
 
+class ITALESPageletsExpression(ITALESExpression):
+    """TAL namespace for getting a list of pagelets.
 
+    To call pagelets in a view use the the following syntax in a page
+    template::
 
-class IPageData(Interface):
-    """Base interface for custom page data adapters."""
+      <tal:block repeat="pagelet pagelets:path.to.my.ISlot">
+        <tal:block replace="structure pagelet" />
+      </tal:block>
 
-
-
-
-class IMacrosCollector(Interface):
-    """Lookup pagelets from the TALES directive 'pagelets:'.
-    
-    A adpater providing this interface is called in:
-    pagelet.tales.TALESPageletsExpression via the TALES expression 
-    called tal:pagelets.
-    
-    If you like to use a layout manager for managing pagelets, implement
-    your own pagelet collector which calls a layout manager.
-    
-    Remember: you can register your own pagelet collector on 
-    layers, because there is a request in the adapter registration
-    tuple. (Request provides the layer interface)
+    where ``path.to.my.ISlot`` is a slot object that provides
+    ``pagelet.interfaces.IPageletSlot``.
     """
-    
-    def macros():
-        """Returns macros related to the context, request, view and slot.
-        
-        The pagelets are registered as adapters on a tuple like:
-        
-        (context, request, view, slot)
-        
-        where the attributes are:
-        
-        context -- the content object
-        request -- the browser request providing a layer interface
-        view -- the context view, normaly a browser page or view
-        slot -- a slot wrapper instance providing the slot interface 
-        """
 
 
-
-class IMacroCollector(Interface):
-    """Lookup a single pagelet from the TALES directive 'pagelet:'
-    
-    by the given interface.
-    
-    A adpater providing this interface is called in:
-    pagelet.tales.TALESPageletsExpression via the TALES expression 
-    called tal:pagelet.
-    
-    """
-    
-    def __getitem__(key):
-        """Returns a single pagelet macro registered by the given name.
-        
-        The pagelets are registered as adapters on a tuple like:
-        
-        (context, request, view, slot)
-        
-        where the attributes are:
-        
-        context -- the content object
-        request -- the browser request providing a layer interface
-        view -- the context view, normaly a browser page or view
-        slot -- a slot wrapper instance providing the slot interface 
-        """
-
-
-
-class ITALESPageletsExpression(ITALESExpression):
-    """Tal namespace for getting a list of macros form a IMacrosCollector.
-    
-    For to call pagelets in a view use the the following syntax in 
-    a page template:
-    <metal:block 
-     tal:repeat="pagelet pagelets:zope.app.demo.pagelet.interfaces.IDemoSlot">
-        <tal:block metal:use-macro="pagelet" />
-	</metal:block>
-    where 'zope.app.pagelet.demo.interfaces.IDemoSlot' is a slot interface 
-    wich implements pagelet.interfaces.IPageletSlot.
-    """
-
-    pagelets = Attribute("pagelets",
-                _(u"Pagelets registered for context, request, view and slot."))
-
-
-
 class ITALESPageletExpression(ITALESExpression):
-    """Tal namespace for getting a IMacroCollector adapter.
-    
-    For to call pagelets in a view use the the following syntax in 
-    a page template:
-    <div class="row" 
-         tal:define="collector global ...
-                     ... pagelets:zope.app.pagelet.demo.interfaces.IDemoSlot">
-      <tal:block metal:use-macro="collector/testpagelet" />
-    </div>
-    where 'zope.app.pagelet.demo.interfaces.IDemoSlot' is a slot interface wich
-    implements pagelet.interfaces.IPageletSlot.
-    """
+    """TAL namespace for getting a single pagelet.
 
-    pagelet = Attribute("pagelet",
-                _(u"Pagelet registered for context, request, view and slot."))
+    To call a named pagelet in a view use the the following syntax in a page
+    template::
 
+      <tal:block replace="structure pagelet:path.to.my.ISlot/name" />
 
-
-class ITALESPageDataExpression(ITALESExpression):
-    """Tal namespace for set the view namespace in MacrosCollector.
-    
-    For calling a page data adapter in a page template use the 
-    following syntax:
-    <metal:block 
-        tal:define="data pagedata:x.y.interfaces.IDemoPageData" />
-    where 'x.y.interfaces.IDemoPageData' is a portlet interface wich
-    implements pagelet.interfaces.IPageData.
+    where ``path.to.my.ISlot`` is a slot object that provides
+    ``pagelet.interfaces.IPageletSlot`` and ``name`` is the name of the page
+    template .
     """
-
-    pagedata = Attribute("pagedata",
-            _(u"Page data adapter registered for context, request and view."))
-
-    def __call__():
-        """Returns the page data adapter."""

Modified: Zope3/trunk/src/zope/app/pagelet/meta.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/meta.zcml	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/meta.zcml	2005-09-16 20:44:54 UTC (rev 38498)
@@ -1,5 +1,4 @@
 <configure
-    xmlns="http://namespaces.zope.org/zope"
     xmlns:meta="http://namespaces.zope.org/meta">
 
   <meta:directives namespace="http://namespaces.zope.org/browser">

Modified: Zope3/trunk/src/zope/app/pagelet/metaconfigure.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/metaconfigure.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/metaconfigure.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -18,136 +18,106 @@
 __docformat__ = 'restructuredtext'
 
 import os
-import sys
 
-from zope.interface import Interface
-from zope.interface import implements
-
-from zope.security.checker import defineChecker
-from zope.security.checker import CheckerPublic, Checker
-
 from zope.configuration.exceptions import ConfigurationError
-
+from zope.interface import Interface, classImplements
 from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.security.checker import defineChecker, Checker
 
-from zope.app import zapi
-from zope.app.component.metaconfigure import handler
 from zope.app.component.interface import provideInterface
-from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
-from zope.component.interfaces import IView
+from zope.app.component import metaconfigure
+from zope.app.publisher.browser import viewmeta
+from zope.app.publisher.interfaces.browser import IBrowserView
 
-from zope.app.pagelet.interfaces import IPageletSlot
-from zope.app.pagelet.interfaces import IPagelet
+from zope.app.pagelet.interfaces import IPageletSlot, IPagelet
+from zope.app.pagelet.pagelet import SimplePageletClass
+from zope.app.pagelet.pagelet import SimpleAttributePagelet
 
 
+def pagelet(_context, name, permission,
+            slot, for_=Interface, layer=IDefaultBrowserLayer, view=IBrowserView,
+            class_=None, template=None, attribute='__call__', weight=0,
+            allowed_interface=None, allowed_attributes=None):
 
-def checkInterface(iface, baseIface):
-    if not iface.isOrExtends(baseIface):
-        raise ConfigurationError(
-            "slot has to implement pagelet.interfaces.IPageletSlot")
+    required = {}
 
+    # Get the permission; mainly to correctly handle CheckerPublic.
+    permission = viewmeta._handle_permission(_context, permission)
 
-def PageletClass(template, weight=0, bases=()):
+    # Either the class or template must be specified.
+    if not (class_ or template):
+        raise ConfigurationError("Must specify a class or template")
 
-    frame = sys._getframe(1).f_globals
-    
-    class_ = type("PageletClass from %s" % template, bases,
-                  {'_template':ViewPageTemplateFile(template, frame)
-                  ,'_weight':weight})
+    # Make sure that all the non-default attribute specifications are correct.
+    if attribute != '__call__':
+        if template:
+            raise ConfigurationError(
+                "Attribute and template cannot be used together.")
 
-    return class_
+        # Note: The previous logic forbids this condition to evere occur.
+        if not class_:
+            raise ConfigurationError(
+                "A class must be provided if attribute is used")
 
+    # Make sure that the template exists and that all low-level API methods
+    # have the right permission.
+    if template:
+        template = os.path.abspath(str(_context.path(template)))
+        if not os.path.isfile(template):
+            raise ConfigurationError("No such file", template)
+        required['__getitem__'] = permission
 
+    # Make sure the has the right form, if specified.
+    if class_:
+        if attribute != '__call__':
+            if not hasattr(class_, attribute):
+                raise ConfigurationError(
+                    "The provided class doesn't have the specified attribute "
+                    )
+        if template:
+            # Create a new class for the pagelet template and class.
+            new_class = SimplePageletClass(
+                template, bases=(class_, ), weight=weight)
+        else:
+            if not hasattr(class_, 'browserDefault'):
+                cdict = {
+                    'browserDefault':
+                    lambda self, request: (getattr(self, attribute), ())
+                    }
+            else:
+                cdict = {}
 
-class simplepagelet(object):
-    """Pagelet adapter class used in meta directive as a mixin class."""
+            cdict['__name__'] = name
+            cdict['__page_attribute__'] = attribute
+            new_class = type(class_.__name__,
+                             (class_, SimpleAttributePagelet), cdict)
 
-    implements(IPagelet)
+        if hasattr(class_, '__implements__'):
+            classImplements(new_class, IBrowserPublisher)
 
-    _weight = 0
+    else:
+        # Create a new class for the pagelet template alone.
+        new_class = SimplePageletClass(template, name=name, weight=weight)
 
-    def __init__(self, context, request, view, ignored):
-        self.context = context
-        self.request = request
-        self.view = view
-        self.__parent__ = context
+    for attr_name in (attribute, 'browserDefault', '__call__',
+                      'publishTraverse', 'weight'):
+        required[attr_name] = permission
 
-    def __getitem__(self, name):
-        """Get the zpt code defined in 'define-macro' by name."""
-        return self._template.macros[name]
+    viewmeta._handle_allowed_interface(
+        _context, allowed_interface, permission, required)
+    viewmeta._handle_allowed_attributes(
+        _context, allowed_interface, permission, required)
 
-    def _getWeight (self):
-        """The weight of the pagelet."""
-        return self._weight
+    viewmeta._handle_for(_context, for_)
+    metaconfigure.interface(_context, view)
+    metaconfigure.interface(_context, slot, IPageletSlot)
 
-    weight = property(_getWeight)
-
-
-
-def pagelet(_context, name, slot, permission, for_=Interface,
-            layer=IDefaultBrowserLayer, view=IView, weight=0, template=None):
-
-    required = {}
-
-    # set permission checker
-    permission = _handle_permission(permission)
-
-    if not name:
-        raise ConfigurationError("Must specify name.")
-
-    if not slot:
-        raise ConfigurationError("Must specify a slot interface.")
-
-    if not template:
-        raise ConfigurationError("Must specify a template.")
-
-    template = os.path.abspath(str(_context.path(template)))
-    if not os.path.isfile(template):
-        raise ConfigurationError("No such file", template)
-
-    new_class = PageletClass(template, weight, bases=(simplepagelet, ))
-
-    # set permissions
-    for n in ('__getitem__', 'weight'):
-        required[n] = permission
-
-    #register interface
-    _handle_iface(_context, for_)
-    _handle_iface(_context, view)
-    _handle_iface(_context, slot)
-
-    # check slot interface
-    _handle_check_interface(_context, slot, IPageletSlot)
-
-    # define checker
     defineChecker(new_class, Checker(required))
 
     # register pagelet
     _context.action(
         discriminator = ('pagelet', for_, layer, view, slot, name),
-        callable = handler,
+        callable = metaconfigure.handler,
         args = ('provideAdapter',
-                (for_, layer, view, slot), IPagelet, name, new_class
-                , _context.info),)
-
-
-def _handle_iface(_context, iface):
-    if iface is not None:
-        _context.action(
-            discriminator = None,
-            callable = provideInterface,
-            args = ('', iface)
-            )
-
-def _handle_check_interface(_context, iface, baseIface):
-    if iface is not None and baseIface is not None:
-        _context.action(
-            discriminator = None,
-            callable = checkInterface,
-            args = (iface, baseIface)
-            )
-
-def _handle_permission(permission):
-    if permission == 'zope.Public':
-        permission = CheckerPublic
-    return permission
+                (for_, layer, view, slot), IPagelet, name, new_class,
+                 _context.info),)

Modified: Zope3/trunk/src/zope/app/pagelet/metadirectives.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/metadirectives.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/metadirectives.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -17,70 +17,34 @@
 """
 __docformat__ = 'restructuredtext'
 
-from zope.interface import Interface
-
-from zope.schema import TextLine
+from zope.configuration.fields import GlobalInterface
 from zope.schema import Int
 
-from zope.app.security.fields import Permission
-from zope.app.component.fields import LayerField
+from zope.app.publisher.browser import metadirectives
 
-from zope.configuration.fields import GlobalObject, GlobalInterface
 
+class IPageletDirective(metadirectives.IPagesDirective,
+                        metadirectives.IViewPageSubdirective):
+    """A directive to register a new pagelet.
 
+    Pagelet registrations are very similar to page registrations, except that
+    they are additionally qualified by the slot and view they are used for. An
+    additional `weight` attribute is specified that is intended to coarsly
+    control the order of the pagelets.
+    """
 
-class IPageletDirective(Interface):
-    """TODO: write documentation."""
-
-    name = TextLine(
-        title=u"The name of the pagelet.",
-        description=u"The name of the pagelet has to be unique",
-        required=True
-        )
-
     slot = GlobalInterface(
         title=u"slot",
         description=u"The slot interface this pagelet is for.",
-        required=True
-        )
+        required=True)
 
-    permission = Permission(
-        title=u"Permission",
-        description=u"The permission needed to use the pagelet.",
-        required=True
-        )
-
-    for_ = GlobalInterface(
-        title=u"for",
-        description=u"The interface this pagelet is for (default IInterface)",
-        required=False
-        )
-
-    layer = LayerField(
-        title=u"The layer the pagelet should be found in",
-        description=u"""
-            For information on layers, see the documentation for the skin
-            directive. Defaults to "default".""",
-        required=False
-        )
-
     view = GlobalInterface(
         title=u"view",
-        description=u"""
-            The interface of the view this pagelet is for. (default IView)""",
-        required=False
-        )
+        description=u"The interface of the view this pagelet is for. "
+                    u"(default IBrowserView)""",
+        required=False)
 
     weight = Int(
         title=u"weight",
         description=u"Integer key for sorting pagelets in the same slot.",
-        required=False
-        )
-
-    template = TextLine(
-        title=u"Page template.",
-        description=u"""
-            Refers to a file containing a page template (must end in
-            extension '.pt').""",
-        required=False
-        )
+        required=False)

Added: Zope3/trunk/src/zope/app/pagelet/pagelet.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/pagelet.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/pagelet.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -0,0 +1,90 @@
+##############################################################################
+#
+# 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 implementation
+
+$Id: metaconfigure.py 38437 2005-09-10 01:59:07Z rogerineichen $
+"""
+__docformat__ = 'restructuredtext'
+
+import sys
+import zope.interface
+from zope.app.pagetemplate.simpleviewclass import simple
+from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
+from zope.app.publisher.browser import BrowserView
+
+from zope.app.pagelet import interfaces
+
+
+class PageletPageTemplateFile(ViewPageTemplateFile):
+
+    def pt_getContext(self, instance, request, **_kw):
+        namespace = super(PageletPageTemplateFile, self).pt_getContext(
+            instance, request, **_kw)
+        namespace['view'] = instance.view
+        namespace['pagelet'] = instance
+        return namespace
+
+
+class SimplePagelet(BrowserView):
+    """Pagelet adapter class used in meta directive as a mixin class."""
+
+    zope.interface.implements(interfaces.IPagelet)
+
+    _weight = 0
+
+    def __init__(self, context, request, view, slot):
+        super(SimplePagelet, self).__init__(context, request)
+        self.view = view
+        self.slot = slot
+
+    def _getWeight (self):
+        """The weight of the pagelet."""
+        return self._weight
+
+    # See zope.app.pagelet.interfaces.IPagelet
+    weight = property(_getWeight)
+
+
+class SimpleAttributePagelet(SimplePagelet):
+
+    def publishTraverse(self, request, name):
+        raise NotFound(self, name, request)
+
+    def __call__(self, *args, **kw):
+        # If a class doesn't provide it's own call, then get the attribute
+        # given by the browser default.
+
+        attr = self.__page_attribute__
+        if attr == '__call__':
+            raise AttributeError("__call__")
+
+        meth = getattr(self, attr)
+        return meth(*args, **kw)
+
+
+def SimplePageletClass(template, offering=None, bases=(), name=u'', weight=0):
+    # Get the current frame
+    if offering is None:
+        offering = sys._getframe(1).f_globals
+
+    # Create the base class hierarchy
+    bases += (SimplePagelet, simple)
+
+    # Generate a derived view class.
+    class_ = type("SimplePageletClass from %s" % template, bases,
+                  {'index' : PageletPageTemplateFile(template, offering),
+                   '_weight' : weight,
+                   '__name__' : name})
+
+    return class_


Property changes on: Zope3/trunk/src/zope/app/pagelet/pagelet.py
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/app/pagelet/tales.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/tales.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/tales.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -16,401 +16,100 @@
 $Id$
 """
 __docformat__ = 'restructuredtext'
+import sys
 
-from zope.interface import implements
-from zope.interface import directlyProvides
+from zope.component.interfaces import ComponentLookupError
+from zope.interface import implements, directlyProvides
+from zope.security import canAccess
+from zope.security.interfaces import Unauthorized
 
 from zope.tales.expressions import StringExpr
 
 from zope.app import zapi
-from zope.app.component.interface import queryInterface
 
-from zope.app.pagelet.exceptions import PageletSlotInterfaceLookupError
-from zope.app.pagelet.exceptions import \
-    PageletSlotInterfaceNotProvidedException
-from zope.app.pagelet.exceptions import PageletError_slot_interface_not_found
-from zope.app.pagelet.exceptions import \
-    PageletError_slot_interface_not_provided
-from zope.app.pagelet.interfaces import ITALESPageletsExpression
 from zope.app.pagelet.interfaces import ITALESPageletExpression
-from zope.app.pagelet.interfaces import ITALESPageDataExpression
+from zope.app.pagelet.interfaces import ITALESPageletsExpression
 from zope.app.pagelet.interfaces import IPageletSlot
 from zope.app.pagelet.interfaces import IPagelet
-from zope.app.pagelet.interfaces import IPageData
-from zope.app.pagelet.interfaces import IMacrosCollector
-from zope.app.pagelet.interfaces import IMacroCollector
+from zope.app.pagelet.interfaces import PageletSlotLookupError
 
 
+def getSlot(str):
+    """Get a slot from the string.
 
-class Wrapper:
-    """Dummy class for to provide a interface."""
+    This function will create the dummy slot implementation as well.
+    """
+    slot = zapi.queryUtility(IPageletSlot, name=str)
+    if slot is None:
+        raise PageletSlotLookupError(
+            _('Pagelet slot interface not found.'), str)
 
+    # Create a dummy slot instance for adapter lookup. This is not ultra
+    # clean but puts the burden of filtering by slot on the adapter
+    # registry.
+    class DummySlot(object):
+        implements(slot)
+    return DummySlot()
 
 
 class TALESPageletsExpression(StringExpr):
-    """Collect pagelets via a tal namespace called tal:pagelets.
+    """Collect pagelets via a TAL namespace called `pagelets`."""
 
-    Imports:
-
-        >>> from zope.interface import Interface
-        >>> from zope.security.checker import defineChecker
-        >>> from zope.publisher.browser import TestRequest
-        >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-        >>> from zope.component.interfaces import IView
-        >>> from zope.app.publisher.browser import BrowserView
-        >>> from zope.app.pagelet.interfaces import IPagelet
-        >>> from zope.app.pagelet.interfaces import IPageletSlot
-        >>> from zope.app.pagelet.tests import TestPagelet
-        >>> from zope.app.pagelet.tests import TestContext
-        >>> from zope.app.pagelet.tests import testChecker
-
-    Register pagelet:
-
-        >>> from zope.app.testing import setup, ztapi
-        >>> setup.placefulSetUp()
-        >>> name = 'testpagelet'
-        >>> pagelet_factory = TestPagelet
-        >>> defineChecker(pagelet_factory, testChecker)
-        >>> gsm = zapi.getGlobalSiteManager()
-        >>> gsm.provideAdapter(
-        ...        (Interface, IDefaultBrowserLayer, IView, IPageletSlot)
-        ...        , IPagelet, name, pagelet_factory)
-
-    Register slot interface:
-
-        >>> from zope.app.component.interface import provideInterface
-        >>> provideInterface('', IPageletSlot, None)
-
-    Register pagelets collector as a adapter:
-
-        >>> from zope.app.pagelet.collector import MacrosCollector
-        >>> collector_factory = MacrosCollector
-        >>> gsm.provideAdapter(
-        ...        (Interface, IDefaultBrowserLayer, IView, IPageletSlot)
-        ...        , IMacrosCollector, '', collector_factory)
-
-    Register pagelets expression:
-
-        >>> from zope.app.pagetemplate.metaconfigure import registerType
-        >>> registerType('pagelets', TALESPageletsExpression)
-
-    Setup a simply browser view called 'index' with a 'index_pagelets.pt' template:
-
-        >>> from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
-        >>> ob = TestContext()
-        >>> request = TestRequest()
-        >>> view = BrowserView(ob, request)
-        >>> index = ViewPageTemplateFile('tests/testfiles/index_pagelets.pt')
-
-    Call the 'index' (view) on the browser view instance:
-
-        >>> html = index(view, request)
-
-    Test if the pagelet content is in the html output:
-
-        >>> import string
-        >>> string.count(html, 'testpagelet macro content')
-        1
-
-    Test PageletSlotInterfaceLookupError:
-
-        >>> no_slot_iface_index = ViewPageTemplateFile(
-        ...     'tests/testfiles/index_pagelets_iface_error.pt')
-
-        >>> try:
-        ...     html = no_slot_iface_index(view, request)
-        ... except PageletSlotInterfaceLookupError, e:
-        ...     print e
-        (u'Pagelet slot interface not found.', u'zope.interface.Interface')
-
-    Register zope.app.interface as a utility and try again:
-
-        >>> gsm = zapi.getGlobalSiteManager()
-        >>> provideInterface('', Interface, None)
-        >>> try:
-        ...     html = no_slot_iface_index(view, request)
-        ... except PageletSlotInterfaceNotProvidedException, e:
-        ...     print e
-        (u'IPageletSlot interface not provided.', u'zope.interface.Interface')
-
-        >>> setup.placefulTearDown()
-
-    """
-
     implements(ITALESPageletsExpression)
 
     def __call__(self, econtext):
-        macros = []
-        expr = self._s
         context = econtext.vars['context']
         request = econtext.vars['request']
         view = econtext.vars['view']
 
-        # get interface from key
-        slotiface = queryInterface(expr)
+        # get the slot from the expression
+        slot = getSlot(self._s)
 
-        # check slot
-        if slotiface is None:
-            raise PageletSlotInterfaceLookupError(
-                    PageletError_slot_interface_not_found, expr)
+        # Find the pagelets
+        pagelets = zapi.getAdapters((context, request, view, slot), IPagelet)
+        pagelets = [pagelet for name, pagelet in pagelets
+                    if canAccess(pagelet, '__call__')]
+        pagelets.sort(lambda x, y: cmp(x.weight, y.weight))
 
-        # check interface
-        if not slotiface.isOrExtends(IPageletSlot):
-            raise PageletSlotInterfaceNotProvidedException(
-                    PageletError_slot_interface_not_provided, expr)
+        return pagelets
 
-        slot = Wrapper()
-        directlyProvides(slot, slotiface)
 
-        collector = zapi.getMultiAdapter((context, request, view, slot)
-                                        , IMacrosCollector)
-
-        macros = collector.macros()
-
-        return macros
-
-
-
 class TALESPageletExpression(StringExpr):
-    """Collects a single pagelet via a tal namespace called tal:pagelet.
+    """Collects a single pagelet via a TAL namespace called pagelet."""
 
-    Imports:
-
-        >>> import zope.component
-        >>> from zope.interface import Interface
-        >>> from zope.security.checker import defineChecker
-        >>> from zope.publisher.browser import TestRequest
-        >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-        >>> from zope.component.interfaces import IView
-        >>> from zope.app.publisher.browser import BrowserView
-        >>> from zope.app.pagelet.interfaces import IPagelet
-        >>> from zope.app.pagelet.interfaces import IPageletSlot
-        >>> from zope.app.pagelet.tests import TestPagelet
-        >>> from zope.app.pagelet.tests import TestContext
-        >>> from zope.app.pagelet.tests import testChecker
-
-    Register pagelet:
-
-        >>> from zope.app.testing import setup, ztapi
-        >>> setup.placefulSetUp()
-        >>> name = 'testpagelet'
-        >>> pagelet_factory = TestPagelet
-        >>> defineChecker(pagelet_factory, testChecker)
-        >>> gsm = zapi.getGlobalSiteManager()
-        >>> gsm.provideAdapter(
-        ...        (Interface, IDefaultBrowserLayer, IView, IPageletSlot)
-        ...        , IPagelet, name, pagelet_factory)
-
-    Register slot interface:
-
-        >>> from zope.app.component.interface import provideInterface
-        >>> provideInterface('', IPageletSlot, None)
-
-    Register pagelets collector as a adapter:
-
-        >>> from zope.app.pagelet.collector import MacroCollector
-        >>> collector_factory = MacroCollector
-        >>> gsm.provideAdapter(
-        ...        (Interface, IDefaultBrowserLayer, IView, IPageletSlot)
-        ...        , IMacroCollector, '', collector_factory)
-
-    Register pagelets expression:
-
-        >>> from zope.app.pagetemplate.metaconfigure import registerType
-        >>> registerType('pagelet', TALESPageletExpression)
-
-    Setup a simply browser view called 'index' with a 'index_pagelet.pt' template:
-
-        >>> from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
-        >>> ob = TestContext()
-        >>> request = TestRequest()
-        >>> view = BrowserView(ob, request)
-        >>> index = ViewPageTemplateFile('tests/testfiles/index_pagelet.pt')
-
-    Call the 'index' (view) on the browser view instance:
-
-        >>> html = index(view, request)
-
-    Test if the pagelet content is in the html output:
-
-        >>> import string
-        >>> string.count(html, 'testpagelet macro content')
-        1
-
-    Test PageletSlotInterfaceLookupError:
-
-        >>> no_slot_iface_index = ViewPageTemplateFile(
-        ...     'tests/testfiles/index_pagelet_iface_error.pt')
-
-        >>> try:
-        ...     html = no_slot_iface_index(view, request)
-        ... except PageletSlotInterfaceLookupError, e:
-        ...     print e
-        (u'Pagelet slot interface not found.', u'zope.interface.Interface')
-
-    Register zope.app.interface as a utility and try again:
-
-        >>> provideInterface('', Interface, None)
-        >>> try:
-        ...     html = no_slot_iface_index(view, request)
-        ... except PageletSlotInterfaceNotProvidedException, e:
-        ...     print e
-        (u'IPageletSlot interface not provided.', u'zope.interface.Interface')
-
-        >>> setup.placefulTearDown()
-
-    """
-
     implements(ITALESPageletExpression)
 
     def __init__(self, name, expr, engine):
-        self._s = expr
         if not '/' in expr:
-            error_msg = "use iface/pageletname for defining the pagelet."
-            raise KeyError(error_msg)
+            raise KeyError('Use `iface/pageletname` for defining the pagelet.')
+
         parts = expr.split('/')
         if len(parts) > 2:
-            error_msg = "Do not use more then one / for defining iface/key"
-            raise KeyError(error_msg)
+            raise KeyError("Do not use more then one / for defining iface/key.")
 
         # get interface from key
         self._iface = parts[0]
         self._name = parts[1]
 
     def __call__(self, econtext):
-        macros = []
-        iface = self._iface
-        name = self._name
         context = econtext.vars['context']
         request = econtext.vars['request']
         view = econtext.vars['view']
 
-        # get interface from key
-        slotiface = queryInterface(iface)
+        # get the slot from the expression
+        slot = getSlot(self._iface)
 
-        # check slot
-        if slotiface == None:
-            raise PageletSlotInterfaceLookupError(
-                    PageletError_slot_interface_not_found, iface)
+        # Find the pagelets
+        pagelet = zapi.queryMultiAdapter(
+            (context, request, view, slot), IPagelet, name=self._name)
 
-        # check interface
-        if not slotiface.isOrExtends(IPageletSlot):
-            raise PageletSlotInterfaceNotProvidedException(
-                    PageletError_slot_interface_not_provided, iface)
+        if pagelet is None:
+            raise ComponentLookupError(
+                'No pagelet with name `%s` found.' %self._name)
 
-        slot = Wrapper()
-        directlyProvides(slot, slotiface)
+        if not canAccess(pagelet, '__call__'):
+            raise Unauthorized(
+                'You are not authorized to access the pagelet '
+                'called `%s`.' %self._name)
 
-        collector = zapi.getMultiAdapter((context, request, view, slot)
-                                        , IMacroCollector)
-
-        return collector.__getitem__(name)
-
-
-
-class TALESPageDataExpression(StringExpr):
-    """Collect page data adapters via a tal namespace called tal:pagedata.
-
-    Imports:
-
-        >>> import zope.component
-        >>> from zope.interface import Interface
-        >>> from zope.security.checker import defineChecker
-        >>> from zope.publisher.browser import TestRequest
-        >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
-        >>> from zope.component.interfaces import IView
-        >>> from zope.app.publisher.browser import BrowserView
-        >>> from zope.app.pagelet.interfaces import IPageletSlot
-        >>> from zope.app.pagelet.tests import TestContext
-        >>> from zope.app.pagelet.tests import TestClass
-        >>> from zope.app.pagelet.tests import testChecker
-
-    Register pagedata class:
-
-        >>> from zope.app.testing import setup, ztapi
-        >>> setup.placefulSetUp()
-        >>> factory = TestClass
-        >>> defineChecker(factory, testChecker)
-        >>> gsm = zapi.getGlobalSiteManager()
-        >>> gsm.provideAdapter(
-        ...        (Interface, IDefaultBrowserLayer, IView)
-        ...        , IPageData, '', factory)
-
-    Register slot interface:
-
-        >>> from zope.app.component.interface import provideInterface
-        >>> provideInterface('', IPageData, None)
-
-    Register pagelets collector as a adapter:
-
-        >>> from zope.app.pagelet.collector import MacroCollector
-        >>> collector_factory = MacroCollector
-        >>> gsm.provideAdapter(
-        ...        (Interface, IDefaultBrowserLayer, IView, IPageletSlot)
-        ...        , IMacroCollector, '', collector_factory)
-
-    Register pagedata expression:
-
-        >>> from zope.app.pagetemplate.metaconfigure import registerType
-        >>> registerType('pagedata', TALESPageDataExpression)
-
-    Setup a simply browser view called 'index' with a 'index_pagedata.pt' template:
-
-        >>> from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
-        >>> ob = TestContext()
-        >>> request = TestRequest()
-        >>> view = BrowserView(ob, request)
-        >>> index = ViewPageTemplateFile('tests/testfiles/index_pagedata.pt')
-
-    Call the 'index' (view) on the browser view instance:
-
-        >>> html = index(view, request)
-
-    Test if the pagelet content is in the html output:
-
-        >>> import string
-        >>> string.count(html, 'A demo string.')
-        1
-
-    """
-
-    implements(ITALESPageDataExpression)
-
-    def __init__(self, name, expr, engine):
-        if '/' in expr:
-            # named adapter
-            parts = expr.split('/')
-            self._iface = parts[0]
-            self._name = parts[1]
-
-        else:
-            # unnamed adapter
-            self._iface = expr
-            self._name = ''
-
-    def __call__(self, econtext):
-        macros = []
-        iface = self._iface
-        name = self._name
-        context = econtext.vars['context']
-        request = econtext.vars['request']
-        view = econtext.vars['view']
-
-        # get interface from key
-        iface = queryInterface(iface)
-
-        # check slot
-        if iface == None:
-            raise PageletSlotInterfaceLookupError(
-                    PageletError_slot_interface_not_found, iface)
-
-        # check interface
-        if not iface.isOrExtends(IPageData):
-            raise PageletSlotInterfaceNotProvidedException(
-                    PageletError_slot_interface_not_provided, iface)
-
-        # get a page data adapter registred on context, request, view
-        pagedata = zapi.getMultiAdapter((context, request, view)
-                                       , iface, name)
-
-        return pagedata
+        return pagelet()

Modified: Zope3/trunk/src/zope/app/pagelet/tests/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/tests/__init__.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/tests/__init__.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -1,86 +1 @@
-##############################################################################
-#
-# 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 tests
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import sys
-from zope.interface import Interface, implements
-
-from zope.security.checker import NamesChecker
-
-from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
-
-from zope.app.pagelet.interfaces import IPageletSlot
-from zope.app.pagelet.interfaces import IPagelet
-from zope.app.pagelet.interfaces import IPageData
-
-
-
-class ITestSlot(IPageletSlot):
-    """Pagelet test slot."""
-
-
-class TestSlot(object):
-    """Test pagelet slot"""
-
-    implements(ITestSlot)
-
-
-class TestPagelet(object):
-    """Test pagelet"""
-
-    implements(IPagelet)
-
-    frame = sys._getframe(1).f_globals
-    _template = ViewPageTemplateFile('testfiles/test_pagelet.pt', frame)
-    _weight = 0
-
-    def __init__(self, context, request, view, ignored):
-        self.context = context
-        self.request = request
-        self.view = view
-
-    def __getitem__(self, name):
-        """Get the macro by name."""
-        return self._template.macros[name]
-
-    def _getWeight (self):
-        """The weight of the pagelet."""
-        return self._weight
-
-    weight = property(_getWeight)
-
-
-class TestContext(object):
-    """Test context"""
-
-    implements(Interface)
-
-
-class TestClass(object):
-    """Test class"""
-
-    implements(IPageData)
- 
-    def __init__(self, context, request, view):
-        pass
-        
-    def getString(self):
-        return "A demo string."
-
-
-testChecker = NamesChecker(['__getitem__', '__call__', 'weight'])
+# Make a package.

Deleted: Zope3/trunk/src/zope/app/pagelet/tests/pagelets.zcml
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/tests/pagelets.zcml	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/tests/pagelets.zcml	2005-09-16 20:44:54 UTC (rev 38498)
@@ -1,28 +0,0 @@
-<zope:configure 
-    xmlns:zope="http://namespaces.zope.org/zope"
-    xmlns="http://namespaces.zope.org/browser"
-    xmlns:meta="http://namespaces.zope.org/meta"
-    i18n_domain="zope"
-    >
-
-  <meta:directives namespace="http://namespaces.zope.org/browser">
-
-    <meta:directive
-        name="pagelet"
-        schema="zope.app.pagelet.metadirectives.IPageletDirective"
-        handler="zope.app.pagelet.metaconfigure.pagelet"
-        />
-
-  </meta:directives>
-
-  <pagelet
-      name="testpagelet"
-      layer="zope.publisher.interfaces.browser.IBrowserRequest"
-      slot="zope.app.pagelet.tests.ITestSlot"
-      template="testfiles/test_pagelet.pt"
-      for="*"
-      permission="zope.Public"
-      />
-
-</zope:configure>
-

Deleted: Zope3/trunk/src/zope/app/pagelet/tests/test_directives.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/tests/test_directives.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/tests/test_directives.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -1,73 +0,0 @@
-##############################################################################
-#
-# 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 tests
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import unittest
-
-from zope.configuration import xmlconfig
-
-from zope.publisher.browser import TestRequest
-
-from zope.interface import directlyProvides
-
-from zope.security.proxy import removeSecurityProxy
-
-from zope.component.tests.placelesssetup import PlacelessSetup
-from zope.component.interfaces import IView
-
-from zope.app import zapi
-from zope.app.servicenames import Adapters
-from zope.app.component.interface import queryInterface
-
-from zope.app.pagelet.interfaces import IPagelet
-from zope.app.pagelet import tests
-
-
-
-class Wrapper:
-    """Dummy class for to provide some interface."""
-
-
-class PageletDirectiveTest(PlacelessSetup, unittest.TestCase):
-    """Pagelet directive test."""
-
-    def setUp (self):
-        PlacelessSetup.setUp(self)
-        self.context = xmlconfig.file("pagelets.zcml", tests)
-
-    def test_pagelets (self):
-        key = 'zope.app.pagelet.tests.ITestSlot'
-        slot = queryInterface(key)
-        context = removeSecurityProxy(self.context)
-        slotwrapper = Wrapper()
-        viewwrapper = Wrapper()
-        directlyProvides(slotwrapper, slot)
-        directlyProvides(viewwrapper, IView)
-        objects = context, TestRequest(), viewwrapper, slotwrapper
-        views = zapi.getAdapters(objects, IPagelet)
-        self.assertEqual(len(views), 1)
-        self.assertEqual(views[0][0], u'testpagelet')
-
-        
-def test_suite():
-    return unittest.TestSuite((
-        unittest.makeSuite(PageletDirectiveTest),
-        ))
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')

Copied: Zope3/trunk/src/zope/app/pagelet/tests/test_doc.py (from rev 38449, Zope3/trunk/src/zope/app/pagelet/tests/test_pagelet.py)
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/tests/test_pagelet.py	2005-09-12 12:46:09 UTC (rev 38449)
+++ Zope3/trunk/src/zope/app/pagelet/tests/test_doc.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -0,0 +1,61 @@
+##############################################################################
+#
+# 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 tests
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import unittest
+import zope.interface
+from zope.testing import doctest
+from zope.testing.doctestunit import DocTestSuite, DocFileSuite
+from zope.app.testing import setup
+
+from zope.app.pagelet import interfaces
+
+
+class TestPagelet(object):
+
+    def doSomething(self):
+        return u'something'
+
+
+class TestPagelet2(object):
+
+    def __call__(self):
+        return u'called'
+
+
+class ITestSlot(zope.interface.Interface):
+    '''A slot for testing purposes.'''
+zope.interface.directlyProvides(ITestSlot, interfaces.IPageletSlot)
+
+
+def test_suite():
+    return unittest.TestSuite((
+        DocTestSuite('zope.app.pagelet.tales'),
+        DocFileSuite('../README.txt',
+                     setUp=setup.placefulSetUp,
+                     tearDown=setup.placefulTearDown(),
+                     ),
+        DocFileSuite('../directives.txt',
+                     setUp=setup.placefulSetUp,
+                     tearDown=setup.placefulTearDown(),
+                     optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+                     ),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Copied: Zope3/trunk/src/zope/app/pagelet/tests/test_pagelet.pt (from rev 38449, Zope3/trunk/src/zope/app/pagelet/tests/testfiles/test_pagelet.pt)
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/tests/testfiles/test_pagelet.pt	2005-09-12 12:46:09 UTC (rev 38449)
+++ Zope3/trunk/src/zope/app/pagelet/tests/test_pagelet.pt	2005-09-16 20:44:54 UTC (rev 38498)
@@ -0,0 +1 @@
+<div>testpagelet macro content</div>

Deleted: Zope3/trunk/src/zope/app/pagelet/tests/test_pagelet.py
===================================================================
--- Zope3/trunk/src/zope/app/pagelet/tests/test_pagelet.py	2005-09-16 20:36:25 UTC (rev 38497)
+++ Zope3/trunk/src/zope/app/pagelet/tests/test_pagelet.py	2005-09-16 20:44:54 UTC (rev 38498)
@@ -1,44 +0,0 @@
-##############################################################################
-#
-# 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 tests
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import unittest
-
-import zope.component
-
-from zope.security.checker import defineChecker
-
-from zope.testing.doctestunit import DocTestSuite
-from zope.testing.doctestunit import DocFileSuite
-
-from zope.app.testing import placelesssetup, ztapi, setup
-
-
-
-def test_suite():
-    return unittest.TestSuite((
-        DocTestSuite('zope.app.pagelet.tales'),
-        DocTestSuite('zope.app.pagelet.collector'),
-        DocFileSuite('../README.txt',
-                     setUp=setup.placefulSetUp,
-                     tearDown=setup.placefulTearDown(),
-                     ),
-        ))
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')



More information about the Zope3-Checkins mailing list