[Checkins] SVN: z3c.layout/trunk/src/z3c/layout/ Added transforms
to support special cases where the static template needs mangling.
Malthe Borch
mborch at gmail.com
Sun Aug 3 21:45:08 EDT 2008
Log message for revision 89336:
Added transforms to support special cases where the static template needs mangling.
Changed:
U z3c.layout/trunk/src/z3c/layout/README.txt
U z3c.layout/trunk/src/z3c/layout/interfaces.py
U z3c.layout/trunk/src/z3c/layout/meta.zcml
U z3c.layout/trunk/src/z3c/layout/model.py
U z3c.layout/trunk/src/z3c/layout/zcml.py
-=-
Modified: z3c.layout/trunk/src/z3c/layout/README.txt
===================================================================
--- z3c.layout/trunk/src/z3c/layout/README.txt 2008-08-04 00:57:46 UTC (rev 89335)
+++ z3c.layout/trunk/src/z3c/layout/README.txt 2008-08-04 01:45:07 UTC (rev 89336)
@@ -149,3 +149,33 @@
</body>
</html>
+Transforms
+----------
+
+To support special cases where you need to use Python to transform the
+static HTML document at compile time, one or more transforms may be
+defined.
+
+ >>> from z3c.layout.model import Transform
+
+Let's add a transform that adds a language setting to the <html>-tag.
+
+ >>> def set_language(node):
+ ... node.attrib["lang"] = "en"
+
+ >>> layout.transforms.add(
+ ... Transform(set_language))
+
+ >>> layout.parse().getroot().attrib["lang"]
+ 'en'
+
+And another transform that assigns a class to the <body>-tag.
+
+ >>> def set_class(node, value):
+ ... node.attrib["class"] = value
+
+ >>> layout.transforms.add(
+ ... Transform(lambda body: set_class(body, "front-page"), ".//body"))
+
+ >>> layout.parse().xpath('.//body')[0].attrib["class"]
+ 'front-page'
Modified: z3c.layout/trunk/src/z3c/layout/interfaces.py
===================================================================
--- z3c.layout/trunk/src/z3c/layout/interfaces.py 2008-08-04 00:57:46 UTC (rev 89335)
+++ z3c.layout/trunk/src/z3c/layout/interfaces.py 2008-08-04 01:45:07 UTC (rev 89336)
@@ -41,3 +41,6 @@
value_type=schema.Object(schema=IRegion),
required=False)
+ def parse():
+ """Parse template using lxml's HTML parser class. Transforms
+ are applied before the tree is returned."""
Modified: z3c.layout/trunk/src/z3c/layout/meta.zcml
===================================================================
--- z3c.layout/trunk/src/z3c/layout/meta.zcml 2008-08-04 00:57:46 UTC (rev 89335)
+++ z3c.layout/trunk/src/z3c/layout/meta.zcml 2008-08-04 01:45:07 UTC (rev 89336)
@@ -3,13 +3,17 @@
<complexDirective
name="layout"
- schema=".interfaces.ILayout"
+ schema=".zcml.ILayoutDirective"
handler=".zcml.LayoutDirective">
<subdirective
name="region"
- schema=".interfaces.IRegion" />
-
+ schema=".zcml.IRegionDirective" />
+
+ <subdirective
+ name="transform"
+ schema=".zcml.ITransformDirective" />
+
</complexDirective>
</directives>
Modified: z3c.layout/trunk/src/z3c/layout/model.py
===================================================================
--- z3c.layout/trunk/src/z3c/layout/model.py 2008-08-04 00:57:46 UTC (rev 89335)
+++ z3c.layout/trunk/src/z3c/layout/model.py 2008-08-04 01:45:07 UTC (rev 89336)
@@ -11,15 +11,23 @@
class Layout(object):
interface.implements(interfaces.ILayout)
- def __init__(self, name, template, resource_path, regions=None):
+ def __init__(self, name, template, resource_path, regions=None, transforms=None):
self.name = name
self.template = template
self.regions = regions or set()
+ self.transforms = transforms or set()
self.resource_path = resource_path
def parse(self):
tree = lxml.html.parse(self.template)
+
+ # rebase resources
utils.rebase(tree, self.resource_path)
+
+ # apply transforms
+ for transform in self.transforms:
+ transform(tree)
+
return tree
class Region(object):
@@ -39,3 +47,17 @@
self.xpath,
self.mode,
repr(self.provider))
+
+class Transform(object):
+ def __init__(self, handler, xpath=None):
+ self.handler = handler
+ self.xpath = xpath
+
+ def __call__(self, tree):
+ handler = self.handler
+
+ if self.xpath:
+ for node in tree.xpath(self.xpath):
+ handler(node)
+ else:
+ handler(tree.getroot())
Modified: z3c.layout/trunk/src/z3c/layout/zcml.py
===================================================================
--- z3c.layout/trunk/src/z3c/layout/zcml.py 2008-08-04 00:57:46 UTC (rev 89335)
+++ z3c.layout/trunk/src/z3c/layout/zcml.py 2008-08-04 01:45:07 UTC (rev 89336)
@@ -1,4 +1,8 @@
+from zope import interface
+from zope import schema
+
from zope.component import zcml
+from zope.configuration import fields
from zope.app.publisher.browser import resourcemeta
import interfaces
@@ -7,17 +11,38 @@
import md5
import os
+class ILayoutDirective(interface.Interface):
+ name = interfaces.ILayout.get('name')
+ template = interfaces.ILayout.get('template')
+
+class IRegionDirective(interfaces.IRegion):
+ pass
+
+class ITransformDirective(interface.Interface):
+ handler = fields.GlobalObject(
+ title=u"Handler that implements transform",
+ required=True)
+
+ xpath = schema.TextLine(
+ title=u"X-path expression for transform",
+ required=False)
+
class LayoutDirective(object):
- def __init__(self, _context, name, template, regions=()):
+ def __init__(self, _context, name, template):
self._context = _context
self.name = name
self.template = template
self.regions = set()
-
+ self.transforms = set()
+
def region(self, _context, *args, **kwargs):
self.regions.add(
model.Region(*args, **kwargs))
+ def transform(self, _context, *args, **kwargs):
+ self.transforms.add(
+ model.Transform(*args, **kwargs))
+
def __call__(self):
path, filename = os.path.split(self.template)
@@ -27,7 +52,8 @@
resource_path = '++resource++%s' % resource_name
layout = model.Layout(
- self.name, self.template, resource_path, self.regions)
+ self.name, self.template, resource_path,
+ self.regions, self.transforms)
# register resource directory
resourcemeta.resourceDirectory(
More information about the Checkins
mailing list