[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