plone.tiles implements low-level, non-Plone/Zope2-specific support for creating "tiles" in the Deco layout system.
For the purposes of this package, a tile is a browser view and an associated utility providing some metadata about that view. The metadata includes a title and description, an 'add' permission and optionally a schema interface describing configurable aspects of the tile. The idea is that a UI (such as Deco) can present the user with a list of insertable tiles and optionally render a form to configure the tile upon insertion.
A tile is inserted into a layout as a link:
<link rel="tile" target="placeholder" href="./@@sample.tile/tile1?option1=value1" />
The sub-path (tile1` in this case) is used to set the tile id attribute. This allows the tile to know its unique id, and, in the case of persistent tiles, look up its data. sample.tile is the name of the browser view that implements the tile. This is made available as the __name__ attribute. Other parameters may be turned into tile data, available under the data attribute, a dict, for regular tiles. For persistent tiles (those deriving from the PersistentTile base class), the data is fetched from annotations instead, based on the tile id.
There are three interfaces describing tiles in this package:
- IBasicTile is the low-level interface for tiles. It extends IBrowserView to describe the semantics of the __name__ and id attributes.
- ITile describes a tile that can be configured with some data. The data is accessible via a dict called data. The default implementation of this interface, plone.tiles.Tile, will use the schema of the tile type and the query string (self.request.form) to construct that dictionary. This interface also describes an attribute url, which gives the canonical tile URL, including the id sub-path and any query string parameters. (Note that tiles also correctly implement IAbsoluteURL.)
- IPersistentTile describes a tile that stores its configuration in object annotations, and is needed when configuration values cannot be encoded into a query string. The default implementation is in plone.tiles.PersistentTile. To make it possible to have several tiles of a given type on the same layout, the annotations are keyed by the tile __name__.
In addition, tiles are described by ITileType, which contains attributes for the tile name, title, description, add permission and schema (if required).
A properly configured tile, then, consists of a browser view providing IBasicTile or one of its derivatives, and a utility providing ITileType with the same name as the tile browser view. There is a convenience ZCML directive - <plone:tile /> - to register both of these components in one go.
To support creation of appropriate tile links, plone.tiles.data contains two methods - encode() and decode() - to help turn a data dictionary into a query string and turn a request.form dict into a data dict that complies with a tile's schema interface.
The most basic tile looks like this:
from plone.tiles import Tile class MyTile(Tile): def __call__(self): return u"<html><body><p>Hello world</p></body></html>"
Note that the tile is expected to return a complete HTML document. This will be interpolated into the page output according to the following rules:
- The contents of the tile's
<head />section is appended to the output document's
- The contents of the tile's
<body />section will replace the tile placeholder as indicated by the tile link.
Note that this package does not provide these interpolations. For a Plone implementation of the interpolation algorithm, see plone.app.blocks
If you require a persistent tile, subclass plone.tiles.PersistentTile instead. You may also need a schema interface if you want a configurable transient or persistent tile.
To register the tile, use ZCML like this:
<configure xmlns:plone="http://namespaces.plone.org/plone"> <plone:tile name="sample.tile" title="A title for the tile" description="My tile's description" add_permission="my.add.Permission" schema=".interfaces.IMyTileSchema" class=".mytile.MyTile" permission="zope.Public" for="*" layer="*" /> </configure>
The first five attributes describe the tile by configuring an appropriate ITileType directive. The rest mimics the <browser:page /> directive, so you can specify a template file and omit the class, or use both a template and class.
If you want to register a persistent tile with a custom schema, but a template only, you can do e.g.:
<plone:tile name="sample.persistenttile" title="A title for the tile" description="My tile's description" add_permission="my.add.Permission" schema=".interfaces.IMyTileSchema" class="plone.tiles.PersistentTile" template="mytile.pt" permission="zope.Public" for="*" />
If you want to override an existing tile, e.g. with a new layer or more specific context, you must omit the tile metadata (title, description, add permission or schema). If you include any metadata you will get a conflict error on Zope startup. This example shows how to use a different template for our tile:
<plone:tile name="sample.persistenttile" template="override.pt" permission="zope.Public" for="*" layer=".interfaces.IMyLayer" />
See tiles.rst and directives.rst for more details.