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 ----------
Name Description
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
name1 desc1
name2 desc2
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)