Personal tools
You are here: Home Documentation Tutorials Customizing the viewlets in main_template Overriding a template viewlet
Support

Get Help

Join our chat rooms or support forums if you have more specific questions.

Plone Training
Learn how to design, build, and deploy a website in Plone through one of the numerous Plone training sessions around the world.
Find Plone training…
 
Document Actions

Overriding a template viewlet

How to use Zope 3 technology to override a viewlet with template definition.

David Convent

Since Plone 3.0, main_template.pt calls viewlet managers instead of METAL macros. Learn from this tutorial how viewlets can be programmatically reordered, hidden or added (from a product on the filesystem).
Page 5 of 7.

In the previous chapters of this tutorial we learned how to add a viewlet to a viewlet manager for a specific theme, and how to hide a viewlet from a viewlet manager in a specific theme. By combining these two techniques we should be able to override a default Plone viewlet with a custom one for a specific theme. It shouldn't be that different than hiding the targeted Plone viewlet and adding/positioning a custom one.

Actually, it is different, and simpler.

Theory

The key concept here is the use of a Zope 3 skin layer.

We saw in the previous chapter how to make use of a Zope 3 skin layer to make sure that the viewlet we added to our theme would not render in any other one. In this chapter we will make use of the same skin layer to override a default Plone viewlet with a custom one.

Principle is this:

In our product (or package), we declare in configure.zcml a viewlet that has the same name as one of the Plone default viewlets, but with a different constructor class or template than the original one (We can use a template even if the original declares a class and vice and versa).

By using the layer attribute in the custom viewlet zcml declaration, we register the viewlet for a Zope 3 skin layer. That skin layer has the same name as the name of the theme that is added to the portal_skins tool.

Zope 3 skin layers are bound to skin selections in portal_skins (themes) thanks to the plone.theme package. Which means that a skin layer is applied if its name matches the name of the selected skin in portal_skins.

A viewlets that is registered for a skin layer is rendered when that layer is applied, and overrides any other viewlet that has the same name but which is not registered for that layer.

Practice

Let's see how we can apply this viewlet overriding within MyTheme, the product that we started to develop in the previous chapters.

Our goal here is to have the footer rendering a different text than the default Plone one in our theme.

1. Creating/Registering the Zope 3 skin layer

Both ZopeSkel and DIYPloneStyle generate code that defines the skin layer interface in MyTheme/browser/interfaces.py. The interface class is named IThemeSpecific and inherits from plone.theme.interfaces.IDefaultPloneLayer.

The plone3_theme template of ZopeSkel generates a package which includes a browser/ directory and a Zope 3 skin layer by default.

That is not the case with the generator script of DIYPloneStyle.

In order to have a Zope 3 skin layer added to a product generated with DIYPloneStyle, you have to run the script with the option --add-viewlet-example.

If you already generated your product with DIYPloneStyle without the --add-viewlet-example option, see in the previous chapter how to add the skin layer manually.

2. Identifying which viewlet to override

We have to identify which viewlet we want to override, and for which viewlet manager it is registered.

Plone ships with a basic user interface for reordering and hiding/showing viewlets inside their viewlet managers. To access that configuration page, point your browser to the URL http://localhost:8080/portal/@@manage-viewlets (or equivalent based on your Zope/Plone installation).

The viewlets management page should look like this one (rendered with the Plone Default theme):

manage-viewlets.jpg

By the end of that page, we can identify the footer region, and note that it is rendered by a viewlet manager called plone.portalfooter. We can also see that two viewlets are registered with plone.portalfooter: plone.footer and plone.colophon. plone.footer is our target: it is the one that we want to see rendered differently in our theme.

3. Write the code that renders the viewlet

Now that we know which viewlet we want to override, let's have a look at its code in our Plone installation on the file system. Plone default viewlets are declared in the plone.app.layout.viewlets package.

Most of the time, that package can be found in $INSTANCE_HOME/lib/python/plone/app/layout/viewlets/. It might be located somewhere else in the $PYTHONPATH though. Depending on the zope installation (win32 or unix like operating system, installation from source, installer, eggs or else…), you may need to use the search tools available in your operating system to locate the package.

Inside the plone.app.layout.viewlets package, we see in configure.zcml where is the code that renders the default plone.footer viewlet in the Plone Default theme. We find the default footer viewlet declaration by the end of the file:

<!-- Footer -->
<browser:viewlet
   name="plone.footer"
   for="*"
   manager=".interfaces.IPortalFooter"
   template="footer.pt"
   permission="zope.Public"
   />

We note that this viewlet isn't rendered by a Zope 3 view but directly from a template, which name is footer.pt. We can make a copy of that template in the browser/ directory of MyTheme. No need to give it a different name.

Edit the template to make it render a different text than the one in the Plone Default theme, for instance:

<div id="portal-footer" i18n:domain="plone">
  <p>
    <span i18n:translate="design_author" tal:omit-tag="">
      Design by
      <span i18n:name="author" tal:omit-tag="">
        <a href="http://mypage.org">John Doe</a>
      </span>.
    </span>
  </p>
</div>

4. Register the custom viewlet in configure.zcml

In order to register the template with the portal footer viewlet manager, we simply copy the portion of ZCML code that we found in lib/python/plone/app/layout/viewlets/configure.zcml (see upper in this page) into MyTheme/browser/configure.zcml, and we edit it to make sure it uses the right interfaces for the manager and the Zope 3 skin layer:

<!-- The customized footer -->
<browser:viewlet
   name="plone.footer"
   for="*"
   manager="plone.app.layout.viewlets.interfaces.IPortalFooter"
   layer=".interfaces.IThemeSpecific"
   template="footer.pt"
   permission="zope.Public"
   />

5. Done

That's all, we can now restart Zope, install the new theme from Site Setup > Add-on Products in the Plone interface, and reload the portal front page (or any other page) to see the result in the footer region.

Other example

Another example of viewlet overriding can be found in DIYPloneStyle/example/custom_footer/. It is quite easy to understand and should be self explanatory now that you read most of this chapter.

This example is slightly different than the one we just covered though: the new viewlet uses a Zope 3 browser view for its rendering. Principles are the same anyway.

The product layout on the file system is also a bit different than the one typically found in a product generated by DIYPloneStyle or ZopeSkel. All viewlet code is kept at first level package in a browser.py module. There is no browser sub-package (folder). This is for showing that there is more than one only possible layout for organizing a plone theme package/product.

  • In browser.py, we find IThemeSpecific, the interface of the Zope 3 skin layer, and FooterViewlet, the viewlet class that overrides the default plone one.
  • footer.pt is the template rendered by FooterViewlet.
  • profiles/default/ is the usual Generic Setup profile for the product.
  • The interface, the viewlet and the product Generic Setup profile are all declared in a single configure.zcml.

And now… happy customizing!

 
by David Convent last modified September 11, 2007 - 08:37 All content is copyright Plone Foundation and the individual contributors.

For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by