Personal tools
You are here: Home Members tseaver Software pushpage pushpage-0.1 pushpage README
Document Actions

pushpage README

by Tres Seaver last modified 2006-07-12 03:37

pushpage Overview

"Push"-mode is jargon used in a number of templating systems to describe templates which have their data "pushed" to them as a mapping, supplied by the application.

Zope Page Templates don't qualify, as they frequently traverse the top-level names (e.g., 'context', 'view', etc.) to "pull" data into the template.

Adopting this model has a couple of advantages, particularly for Zope applications:

  • The template code stays simpler, and therefore easier to maintain.
  • The view code which does the work has an easily testable API.
  • All the "heavy lifting" must be done by "trusted" code, and therefore without doing security checks.
  • Assuming that the values in the mapping are primitive types, the actual work of rendering the template can be done after closing the database connection, and could therefore be done "lazily" (e.g., by an IStreamITerator).

Using pushpage

A push page is a view which combines a ZPT template and a callable returning a mapping:

>>> from pushpage.browser import PushPageFactory
>>> TEMPLATE = """\
... <tal:block tal:repeat="row rows">
... <tal:span tal:replace="row/title">TITLE</tal:span>
... </tal:block>"""
>>> def getRows(context, request):
...     return {'rows': [{'title': 'First Title'},
...                      {'title': 'Second Title'},
...                      {'title': 'Third Title'},
...                     ]}
>>> factory = PushPageFactory(TEMPLATE, getRows)
>>> page = factory(None, None)
>>> print page()
<BLANKLINE>
First Title
<BLANKLINE>
Second Title
<BLANKLINE>
Third Title
<BLANKLINE>

Push pages can also be made from file-like objects:

>>> from StringIO import StringIO
>>> filelike = StringIO(TEMPLATE)
>>> page = PushPageFactory(filelike, getRows)(None, None)
>>> print page()
<BLANKLINE>
First Title
<BLANKLINE>
Second Title
<BLANKLINE>
Third Title
<BLANKLINE>

Push pages do not have access to the "standard" top-level names used in most ZPT:

>>> factory = PushPageFactory('<tal:x tal:replace="context/title" />',
...                           lambda context, request: {})
>>> page = factory(None, None)
>>> page()
Traceback (most recent call last):
...
KeyError: 'context'
>>> factory = PushPageFactory('<tal:x tal:replace="template/title" />',
...                           lambda context, request: {})
>>> page = factory(None, None)
>>> page()
Traceback (most recent call last):
...
KeyError: 'template'
>>> factory = PushPageFactory('<tal:x tal:replace="view/title" />',
...                           lambda context, request: {})
>>> page = factory(None, None)
>>> page()
Traceback (most recent call last):
...
KeyError: 'view'

We can pass along a security checker when instantiating a factory, which will then be annotated onto the pages it produces under the special '__Security_checker__' name (used by the security proxy machinery):

>>> checker = object()
>>> factory = PushPageFactory('<tal:x tal:replace="context/title" />',
...                           lambda context, request: {}, checker=checker)
>>> page = factory(None, None)
>>> page.__Security_checker__ is checker
True

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: