This is a pre-production deployment of Warehouse, however changes made here WILL affect the production instance of PyPI.
Latest Version Dependencies status unknown Test status unknown Test coverage unknown
Project Description

This package does two things. First, it does everything z3c.viewtemplate does – seperate the view code layer from the template skin layer. Second, it allows an unlimited number of templates to be plugged into any view class.

What’s this for?

Making masterpages simple is hard work. Using macros is fairly complicated for designers to deal with. In fact they don’t. Using z3c.viewtemplate with viewlets is fairly complicated for programmers to deal with. In fact I don’t. So this is another evolutionary step to allow designers and programmersto work together without necessarily knowing or even liking each other.

This work relies heavily on the working code done by Jurgen for z3c.viewtemplate.

A simple masterpage implementation

This is a simple masterpage implementation without using pluggabletemplates.

       class MyView(object):

               masterpage = ViewTemplateFile('templates/')
               subpage = ViewTemplateFile('templates/')

               authors = ['Roger Zelazny', 'Isaac Asimov', 'Robert Heinlien', 'J.R.R Tolkein']

               def __call__(self):
                       return masterpage()


       <h2>My Master Page</h2>
       <span tal:replace="view/subpage" />


               <li tal:repeat="author view/authors" tal:content="author" />

This is a very easy to follow pattern which can be extended fairly easily. This pattern runs into immediate problems when you want to change skins. Changing skins should be as easy as ++skin++design1 … +++skin++design2, but to do so, all of the view code needs to be duplicated. Which can be done, but as soon as one piece of view code is changed, all the other view code has to be patched and easily falls out of sync.

Enter viewplugs



So does this mean we’ll need to duplicate all of this configuration for ++skin++design2?? Not necessarily:

class Design2(Design1):
        """ Skin marker """

Now you can use ++skin++design1 one as your base and simply override the views or templates you need to change et. al. stylesheets and images.

By plugging templates into view code, each template can display each of the other templates:

<span tal:replace="view/template1" />
<span tal:replace="view/template2" />

And of course all view attributes are available:

<span tal:replace="view/myattr1" />

You can add as many views as you like, though, too many, and it could get recomplicated.


Before we can setup a view component using this new method, we have to first create a master template and subtemplate …

>>> import os, tempfile
>>> temp_dir = tempfile.mkdtemp()
>>> master = os.path.join(temp_dir, '')
>>> open(master, 'w').write('''<h2>Masterpage</h2><span tal:replace="view/subtemplate"/>''')
>>> subtemplate = os.path.join(temp_dir, '')
>>> open(subtemplate, 'w').write('''This is the subtemplate: <span tal:replace="view/taste" />''')
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> from zope import interface
>>> from z3c.pluggabletemplates.baseview import MasterView
>>> from z3c.pluggabletemplates.pagetemplate import RegisteredPageTemplate
>>> class IMyView(interface.Interface):
...     pass
>>> class MyView(MasterView):
...     interface.implements(IMyView)
...     master = RegisteredPageTemplate( 'master' )
...     taste = 'success'
...     subtemplate = RegisteredPageTemplate( 'subtemplate' )
>>> view = MyView(root, request)

Since the template is not yet registered, rendering the view will fail:

>>> print view()
Traceback (most recent call last):
ComponentLookupError: ......

Let’s now register the template (commonly done using ZCML):

>>> from zope import component
>>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
>>> from z3c.pluggabletemplates.zcml import TemplateFactory
>>> from zope.pagetemplate.interfaces import IPageTemplate

The template factory allows us to create a ViewPageTemplateFile instance:

>>> factory = TemplateFactory(master, 'text/html')

We register the factory on a view interface and a layer:

>>> component.provideAdapter(factory,
...            (interface.Interface, IDefaultBrowserLayer),
...            IPageTemplate, name="master")
>>> mastertemplate = component.getMultiAdapter(
...               (view, request), IPageTemplate, name="master"  )
>>> mastertemplate
< ...>

>>> factory = TemplateFactory(subtemplate, 'text/html')

We register the factory on a view interface and a layer:

>>> component.provideAdapter(factory,
...            (interface.Interface, IDefaultBrowserLayer),
...            IPageTemplate, name="subtemplate")
>>> subtemplate = component.getMultiAdapter(
...               (view, request), IPageTemplate, name="subtemplate"  )
>>> subtemplate
< ...>

Now that we have a registered template for the default layer we can call our view again:

>>> print view()
<h2>Masterpage</h2>This is the subtemplate: success


>>> import shutil
>>> shutil.rmtree(temp_dir)

Revision Log

  • 11/03/06 initial checkin
Release History

Release History


This version

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

Download Files

Download Files

TODO: Brief introduction on what you do with files - including link to relevant help section.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
z3c.pluggabletemplates-0.2-py2.4.egg (19.8 kB) Copy SHA256 Checksum SHA256 2.4 Egg Nov 4, 2006
z3c.pluggabletemplates-0.2.tar.gz (8.0 kB) Copy SHA256 Checksum SHA256 Source Nov 4, 2006

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS HPE HPE Development Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting