HTML layout engine
Project description
HTML layout engine
This package implements a page rendering model based on a static HTML document that is made dynamic from the outside by mapping content provider definitions to locations in the HTML document tree. This is called a “layout”.
The component architecture is utilized to provide extension points that allow wide application. Two-phase rendering is supported using the zope.contentprovider rendering scheme (update/render).
Static resources, as referenced by the HTML document (images, stylesheets and javascript files) are included carbon copy and published as browser resources (see zope.app.publisher.browser).
Benefits:
No template language required
Support for two-phase rendering
Integrates with creative workflow
Flexible extension points
Walk-through
Layouts and regions
Let’s begin by instantiating a layout. We’ll do this manually for the sake of this demonstration; usually this is done using the included ZCML-directive <browser:layout>.
>>> from z3c.layout.model import Layout>>> layout = Layout( ... "test", "%s/templates/default/index.html" % test_path, "test")
Register resource directory.
>>> import zope.configuration.config as config >>> context = config.ConfigurationMachine()>>> from zope.app.publisher.browser import resourcemeta >>> resourcemeta.resourceDirectory( ... context, "test", "%s/templates/default" % test_path) >>> context.execute_actions()
Layouts are made dynamic by defining one or more regions. They are mapped to HTML locations using an xpath-expression and an insertion mode, which is one of “replace”, “append”, “prepend”, “before” or “after”.
Regions can specify the name of a content provider directly or it may rely on adaptation to yield a content provider component. We’ll investigate both of these approaches:
>>> from z3c.layout.model import Region
First we define a title region where we directly specify the name of a content provider.
>>> title = Region("title", ".//title", title=u"Title", provider="title")
Then a content region where we leave it the content provider to component adaptation.
>>> content = Region("content", ".//div", "Content")
To register them with the layout we simply add them.
>>> layout.regions.add(title) >>> layout.regions.add(content)
Let’s define a context class.
>>> class MockContext(object): ... interface.implements(interface.Interface)
We need to provide a general adapter that can provide content providers for regions that do not specify them directly. As an example, we’ll define an adapter that simply tries to lookup a content provider with the same name as the region.
>>> from z3c.layout.interfaces import IContentProviderFactory>>> class EponymousContentProviderFactory(object): ... interface.implements(IContentProviderFactory) ... ... def __init__(self, region): ... self.region = region ... ... def __call__(self, context, request, view): ... name = self.region.name ... return component.getMultiAdapter( ... (view.context, request, view), IContentProvider, name)>>> from z3c.layout.interfaces import IRegion>>> component.provideAdapter( ... EponymousContentProviderFactory, (IRegion,))
Rendering
Before we can render the layout, we need to register content providers for the two regions. We’ll use a mock class for demonstration.
>>> from zope.contentprovider.interfaces import IContentProvider>>> class MockContentProvider(object): ... interface.implements(IContentProvider) ... ... __name__ = u"" ... ... def __init__(self, *args): ... pass ... ... def update(self): ... pass ... ... def render(self): ... return self.__name__ ... ... def __repr__(self): ... return "<MockContentProvider '%s'>" % self.__name__>>> from zope.publisher.interfaces.browser import IBrowserRequest >>> from zope.publisher.interfaces.browser import IBrowserView>>> component.provideAdapter( ... MockContentProvider, (MockContext, IBrowserRequest, IBrowserView), ... name="title")>>> component.provideAdapter( ... MockContentProvider, (MockContext, IBrowserRequest, IBrowserView), ... name="content")
Let’s instantiate the layout browser-view. We must define a context and set up a request.
>>> from zope.publisher.browser import TestRequest>>> context = MockContext() >>> request = TestRequest()
We need to have the request be annotatable.
>>> from zope.annotation.attribute import AttributeAnnotations >>> component.provideAdapter( ... AttributeAnnotations, (TestRequest,))
The view expects the context to adapt to ILayout.
>>> from z3c.layout.interfaces import ILayout >>> component.provideAdapter( ... lambda context: layout, (MockContext,), ILayout)>>> from z3c.layout.browser.layout import LayoutView >>> view = LayoutView(context, request)
Verify that the layout view is able to get to these providers.
>>> view.mapping {'content': (<Region 'content' .//div (replace) None>, <MockContentProvider 'content'>), 'title': (<Region 'title' .//title (replace) 'title'>, <MockContentProvider 'title'>)}
Now for the actual output.
>>> print view() <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <link rel="stylesheet" href="test/main.css" type="text/css" media="screen"> <title>title</title> </head> <body> <div id="content">content</div> </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'
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file z3c.layout-0.2.tar.gz
.
File metadata
- Download URL: z3c.layout-0.2.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0d7f1a71f2e92a71f2b02b77bf08eb69a1d1c5d28c3d7541f7f531310efa6e90 |
|
MD5 | 85a649bbabeb2dc165a531ca38a55661 |
|
BLAKE2b-256 | 88fdfc9361bf3add7e3eb3c4f56b42f52a41a0d260a5dd465f9a54f0697ed6ee |