How to write templates for Plone 4
Macros, slots, viewlets and other monsters.
Important! Plone 4 has an updated master template (main_template.pt). If you have customized main_template in your theme on a previous version of Plone you'll want to check it against the most recent changes in Plone 4.
In this how-to we will review changes, mainly those related to the content column. Please be sure to examine main_template.pt in your check-out of Plone 4.
Important slots in Plone 4:
- content-title - slot containing view's title. Contains auto-generated title in main_template.pt
- content-description - slot containing view's description. Contains auto-generated description in main_template.pt
- content-core - slot that sits below description in main_template and renders exactly a view's core like text of a Document object, folder listing for a Folder view and so on.
- main. This slot is still available in Plone 4. First for backwards compatibility reasons and second for the views that don't need to render viewlet managers or need to have title/description other than the auto-generated one.
Viewlet managers.
All viewlet managers related to the content column that you normally would put in your templates in Plone 3 are now managed by main_template.pt. This means that if your template needs viewlet managers you don't need to explicitly put them in your template. It's important to fill the correct slots in this case.
The new strategy has dramatically simplified templating for content types. Take a look at document_view.pt for an example. It now does little except insert content in the right slot.
Templates for an object's view.
In Plone 3 one usually used the 'main' slot as the container for everything related to the content column. This led to a mess in the content column: elements appearing in unexpected places and unpredictable markup in general.
Plone 4 makes the templates used for views of objects a lot simpler. As we saw above, first you don't need to put viewlet managers in a template that is going to be used as a view for an object like document_view, event_view, etc.
Next, unless you really need to write a custom title or description for your view you should avoid filling 'main' slot. Instead, Plone 4 provides you with the new 'content-core' slot that contains your view's core content only. main_template.pt will provide you with object's title, description and viewlet managers automatically.
As an example of how slim and meaningful an object's view in Plone 4 can be, let's take a look at document_view.pt in Plone 4:
<metal:content-core fill-slot="content-core">
<metal:content-core define-macro="content-core">
<metal:field use-macro="python:context.widget('text', mode='view')">
Body text
</metal:field>
</metal:content-core>
</metal:content-core>
That is all you need for this view (not counting wrapping <html> element with general definitions).In this case we fill only the "content-core" slot; that means we get all all the rest — viewlet managers, title and description — from main_template.pt
General templates other than objects' views.
Even though Plone 4 is good in letting you avoid putting a lot of extra stuff in your templates in a lot of cases you will still need to fill "main" slot and put some elements in your template yourself. The good news is that in most of these cases you probably don't need viewlet managers. Otherwise you would fill "content-title", "content-description" and "content-core" slots for title, description and content's core respectively. But there are some important notes to keep in mind when writing such template anyway:
- The content title should always have class "documentFirstHeading";
- If you need a standard title or description, fill "content-title" or "content-description" slots respectively;
- Descriptions should always have class 'documentDescription';
- Everything that is after title or description in the template should be wrapped with <div id="content-core">;
- <a class="link-parent"> should be within <div id="content-core">;
- If there is a need to explicitly put portal message into a template, it should be placed above document's title. But preferably into plone.abovecontenttitle viewlet manager
-
Important! if you fill a slot never do this on a <div> element. Use <metal:meaningfulname> instead like:
<metal:content-core fill-slot="content-core">
This is important because
Content core
</metal:content-core>- minimizes the number of empty <div> elements in Plone's output
- makes markup much more predictable. In Plone 3 more than 50% of templates filled "main" slot from <div> that led to empty <div> wrapping the whole content like:
<div id="content">
Keeping in mind that the rest of the templates in Plone didn't have that empty <div> tag sometimes one got very unpredictable results when parsing a DOM tree with javascript or applying rules in rules-based theming technologies like Deliverance and XDV.
<div>
Content
</div>
</div>
Related items.
Plone 4 doesn't explicitly call a macro for related items in main_template.pt anymore. Instead, related items are handled via a viewlet assigned to the plone.belowcontentbody viewlet manager. So please don't call this deprecated macro in your templates as you might have in previous Plone versions.
Disabling columns.
In order to unify the way we disable stuff in Plone, columns in Plone4 are disabled in the same way as the border when editing a content - via REQUEST variable. Let's see how.
Old
<metal:left fill-slot="column_one_slot" />
<metal:right fill-slot="column_two_slot" />
New
<metal:block fill-slot="top_slot"
tal:define="disable_column_one python:request.set('disable_plone.leftcolumn',1);
disable_column_two python:request.set('disable_plone.rightcolumn',1);" />
Removal of redundant IDs and classes for the content area.
In Plone 3, there were three IDs/classes that covered exactly the same area, so we simplified it. We kept the #content selector, and got rid of the others. If you have a theme and want it to work the same way in both Plone 3 and Plone 4, you should do the following substitutions using your favorite editor's search/replace tool:
-
#region-content→#content -
.documentContent→#content -
.configletis just removed from configlets' templates - Any internal anchor link to
href="#documentContent"→href="#content"
We also updated all templates in Plone that do fill-slot="content" to remove references to #region-content and .documentContent, so these should not exist anywhere in the source HTML anymore.
Portal status message.
Portal status message in Plone 4 has been moved out of #content element and is located
between content tabs ("View", "Edit", etc) and actually #content. If you have any view in your
theme that explicitly adds portal status message, please update those if you want to have consistent
markup.
Ideally your custom portal status message should fill header slot and not be within 'main'
or 'content-core' slots you fill in the templates
