Skip to main content

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.

browser.py:

       class MyView(object):

               masterpage = ViewTemplateFile('templates/masterpage.pt')
               subpage = ViewTemplateFile('templates/content.pt')

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

               def __call__(self):
                       return masterpage()

templates/masterpage.pt::

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

templates/index.pt::

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

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

design1/configure.zcml:

<browser:pluggableTemplates
        for="myapp.browser.MyView"
        layer=".skins.Design1"
        >
        <template
                name="master"
                file="templates/masterpage.pt"
                />
        <template
                name="subtemplate"
                file="templates/subtemplate.pt
                />
</browser:pluggableTemplates>

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.

Doctests

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, 'master.pt')
>>> open(master, 'w').write('''<h2>Masterpage</h2><span tal:replace="view/subtemplate"/>''')
>>> subtemplate = os.path.join(temp_dir, 'subtemplate.pt')
>>> 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
<zope.app.pagetemplate.viewpagetemplatefile.ViewPageTemplateFile ...>

>>> 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
<zope.app.pagetemplate.viewpagetemplatefile.ViewPageTemplateFile ...>

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
<BLANKLINE>

Cleanup

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

Revision Log

  • 11/03/06 initial checkin

Release files for z3c.pluggabletemplates 0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for z3c.pluggabletemplates 0.2
File Size Uploaded
z3c.pluggabletemplates-0.2.tar.gz 8.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for z3c.pluggabletemplates 0.2
File Interpreter ABI Platform
z3c.pluggabletemplates-0.2-py2.4.egg Legacy Egg format - - Details

Total release size: 27.8 kB

Release files / z3c.pluggabletemplates-0.2.tar.gz

Download URL z3c.pluggabletemplates-0.2.tar.gz
Size 8.0 kB
Tags Source
SHA-256 checksum
How to use checksums
54d503956a0b6491e8e8b40834da53de5c2e30107af23c4c1c0f91ce72fea8a9
BLAKE2b-256 checksum
How to use checksums
16017409af0d49554bfb39b92ad08a340114d9491b42a0a4cc73ecdf7956caba
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / z3c.pluggabletemplates-0.2-py2.4.egg

Download URL z3c.pluggabletemplates-0.2-py2.4.egg
Size 19.8 kB
Tags Egg
SHA-256 checksum
How to use checksums
0c3529ce8736ade71c608d3bf1114fd1d37dbcbf46e0db0de09f8a6b4496f1a1
BLAKE2b-256 checksum
How to use checksums
3f14d0c91a8cff2935f6f3f8a973b629170e47dbb1e4b0aa3912300e144b50cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release history Release notifications | RSS feed

This release

0.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page