Introduction
As we saw in the first approach, the renderers are the very heart of the whole Structured Document system. Even if the concept sounds quite simple, the implementation uses a lot of cutting-edge technologies, including an extensive use of zope3 components.
Learning by doing
Where to look for
Renderers basics are defined in sd.rendering. They are developped and used in sd.app.rendering
Give me facts : what a renderer truly is
- A multi adapter on an object and a browser request
- A python class generated from several mixins classes and a base class (see Renderer registration process)
According to the description above, a renderer is a BrowserPage with extra base classes.
Declaring a renderer
Renderers can be registered using ZCML. There are two possible registrations : chapter and paragraph renderers. We'll see them in details. But let's take it step by step.
Using the right namespace and including the necessary package
The registration is done using two statements : paragraphRenderer and chapterRenderer. They are defined in sd.app.renderering, using meta directives (see meta.zcml). Declaring a rendering will require us to use the correct namespace :
xmlns:sd="http://namespaces.zope.org/sd"
... Then include the definition package in our project.
<include package="sd.app.rendering" />
Renderer commons
A chapter and paragraph renderers are very similar. It can be generalized by the following schemas :
<chapterRenderer name="minimalistic_renderer" description="it only uses a template to renderer" targets="path.to.interface" template="mytemplate.pt" />
<chapterRenderer name="complete_renderer" description="A demo view" renderer="path.to.custom.class" template="path/to/template" targets="path.to.content.interface" folderish="True" filtering="path.to.some.interface" />
A real-world example
Taken from the sd.plugins module :
<configure xmlns="http://namespaces.zope.org/sd">
<include package="sd.app.rendering"/>
<paragraphRenderer
name="simple_video_renderer"
targets="p4a.video.interfaces.IVideoEnhanced"
description="Plone4Artists Video Renderer"
template="p4avideo_paragraph.pt"
renderer=".video_renderer.P4AVideoRenderer"
/>
</configure>
Fields
see the metadirectives file for complete informations
name : Python identifier
The unique name of the renderer. This name is the msgid used during the internationalization. This field is optional. If not provided, the default value is "default". Of course, as the name is unique, you can have only one "default renderer.
description : Text
This is the text displayed in the layout selection drop down menu in English. This is injected as the generated renderer docstring.
renderer : Dotted class path
The dedicated class used for the rendering. This class is only optional. A default renderer is already provided. See Renderer registration process below for more information
template : Filesystem relative path
The template used in the rendering process.
macro : Python identifier
Limits the rendering to the given macro, existing within the specified template.
targets : List of dotted interfaces paths
The renderer will be available for the content types implementing one of these interfaces.
folderish : Boolean
Defines if the renderer needs to be aware of the rendered item's content. This default is True by default for the chapterRenderer and False for the paragraphRenderer. Therefore, the explicit declaration is optional
filtering : Dotted interface path
If the renderer is folderish (see above), filtering can be used to filter the fetched content by restricting the query to the given interface. This field is optional.
Renderer registration process
On runtime, when the ZCML is read, the renderer is created out of python classes mixing. Then, it is registered as a multi adapter in the zope component registry, under the specified name.
The classes mixed are :
chapterRenderer
1. sd.rendering.base.ChapterStructuredRenderer
2. sd.rendering.base.FolderishRenderer unless folderish is explicitly set to False
3. the class defined in the renderer zcml definition under renderer
paragraphRenderer
1. sd.rendering.base.ParagraphStructuredRenderer
2. sd.rendering.base.FolderishRenderer if folderish is explicitly set to True
3. the class defined in the renderer zcml definition under renderer
Example of renderer custom class
Example of a renderer that could be used for an ATNewsItem. It provides an helper attribute to display the formated image tag.
class ATNewsItemRenderer(object):
"""Base class for an atnewsitem renderer.
"""
@property
def image(self):
return self.context.tag(scale='thumb')
Retrieving a renderer
Renderers are multi adapters. They adapt the object (implementing the interface defined in targets) and the request. Retrieving a renderer is simple. You only need to precise the kind of renderer you want to fetch by specifying the provided interface and its name. sd.rendering defines the provided interfaces : IChapterRenderer, IParagraphRenderer.
Code
queryMultiAdapter((object, self.request),
IChapterRenderer,
name = "my_nice_renderer")
URL
http://path.to.portal/item/@@name-of-the-renderer
