z3meld
Overview
z3meld is a set of Zope 3 bindings for the meld3 XML/HTML templating
system. It allows you to use meld3 templates within your Zope 3
application.
Requirements
Zope 3.1+
meld3 (http://www.plope.com/software/meld3)
Installation
Run 'python setup.py install'.
Copy the files named 'meld3-meta.zcml' and 'meld3-configure.zcml'
into your Zope3 instance's etc/package-includes directory.
(You can use the --home argument to install in order to place the
z3meld package into your Zope's instancehome/lib/python directory, e.g.
'python setup.py install --home=/path/to/z3instance').
Usage
You can declare meld3 pages in ZCML. Doing so is reminiscent of
declaring ZPT pages in ZCML, with a few differences. The main
difference is that the equivalents to "define-macro" and "use-macro"
are declared outside the templates themselves (in ZCML, typically).
For example, here's a definition of a meld3 page which registers a
page named 'foo.html'. 'foo.html' renders a "main template" with
its "content well" and "head slots" filled in by dynamic
transformations::
Here are the various templates and Python modules referred to by the
above ZCML::
main_template.html
------------------
This is the title
This is the head slot
This should get replaced.
table.html
----------
sampletransform.py
------------------
data = ( ('name1', 'desc1'), ('name2', 'desc2') )
class Transform:
def table_transform(self, element):
tr = element.findmeld('tr')
iterator = tr.repeat(data)
for el, thing in iterator:
el.findmeld('td1').content(thing[0])
el.findmeld('td2').content(thing[1])
def head_transform(self, element):
head = element.findmeld('headslot')
head.text = self.request['QUERY_STRING'] or 'The slot is filled'
When this view is called, it renders
into::
This is the title
The slot is filled
The 'class', 'attribute', and 'layer' arguments to
'browser:meld3page' are optional. The 'fill' directive is optional.
If the 'fill' directive is used, the 'class', 'attribute', and
'source' to that directive are optional. For more information, see
metadirectives.py in the package.
When a fill directive is used, the order that a page is composed is
this:
1. For each fill subdirective in the page, perform mutation of that
template according to its 'attribute' mutator.
2. Mutate the outermost template (the one named in the meld3page
directive) if we name a mutator via 'attribute'.
3. Attempt to fill the slots in the mutated main template with the
elements created by the result of step 1.
Gotcha observed in the wild: you might perform a "replace" of a node
that serves as the main template's "content well". When meld3 tries
to fill this slot, because you've replaced it (via step 2) it no
longer exists, and a "no such target slot" ValueError is raised.
Solution: don't replace/remove nodes in your main template's mutator
that are meant to serve as target slots.
Influencing Rendering
By default, the rendering of a meld3 page is performed in "HTML
mode". This mode provides the best browser compatibility. If you
need to influence the rendering of a particular page, you can use
the "render_attribute" argument to a page definition, which names a
method on the view class which converts the top-level element to a
string serialization::
An example "RenderingTransform" class that performs an alternate
meld3 serialization to XHTML with pipelining turned on might be::
class Transform:
def head_transform(self, element):
head = element.findmeld('headslot')
head.text = self.request['QUERY_STRING'] or 'The slot is filled'
def renderer(self, element):
from StringIO import StringIO
io = StringIO()
element.write_xhtml(io, pipeline=True)
return io.getvalue()
To Do
See TODO.txt for to-do items.
Reporting Bugs and Requesting Features
Please visit http://www.plope.com/software/collector to report bugs
and request features.
Have fun!
- Chris McDonough (chrism@plope.com)