Building our own Plone 3 Theme Add-on Product

Exclusive offer: get 50% off this eBook here
Plone 3 Intranets

Plone 3 Intranets — Save 50%

Design, build, and deploy a reliable, full-featured, and secure Plone-based enterprise intranet easily from scratch

$26.99    $13.50
by Víctor Fernández de Alba | July 2010 | Content Management Open Source

Plone is a highly extensible Content Management System built on Zope application server, which is written in Python. Plone is very suitable for building intranets. No matter what size, or purpose, it offers a solution to the most common intranet needs, and more. Although it shows its real power in medium and large-scale corporate intranets, we can take advantage of Plone even in small-scale scenarios, such as small work groups, software projects, or research teams.

In this article by Víctor Fernández de Alba, author of the book Plone 3 Intranets, we will see how to build our own Plone 3 theme add-on product.

(For more resources on Plone, see here.)

We can build our own theme add-on product from scratch. It can be done easily with PasteScript. Just type this on our command line from the root of our buildout:

$ cd src
$ paster create -t plone3_theme plonetheme.myintranet

Answer all the questions with the default option except for:

  • Skin Name: A human facing name for the theme, added to portal_skins, for example, MyIntranetTheme.
  • Skin Base: Name of the theme from which this is copied. By default, it is Plone Default. Answer the default option here.
  • Empty Styles?: If true, it will override default public stylesheets with empty ones. Answer False.
  • Include documentation?: If true, the generated theme will include auto- explanatory documentation, desirable for beginners.

The resultant theme add-on product will be generated in the src buildout folder. This add-on is completely usable right now, but it's innocuous. Once installed, it will replace the original Plone default theme with the one in this package.

Installing the product

Just proceed as any other add-on product. However, since we are developing the product, we should specify it in our buildout by filling the develop directive in the buildout section and the eggs directive in the instance section in our buildout.cfg file:

[buildout]
...
develop = src/plonetheme.myintranet
...
[instance]
...
eggs = plonetheme.myintranet

Go to the package folder, src/plonetheme.myintranet/plonetheme/myintranet, and edit the configure.zcml file. As we don't want to define an i18n folder, delete the following line if it exists:

<i18n:registerTranslations directory="locales" />

And then, rerun buildout.cfg:

$ ./bin/buildout
$ ./bin/instance fg

Now, go to the Add-on Products control panel configlet and install it.

If we browse our site, we will notice that nothing has changed, because we've chosen to inherit the default theme in our new one. But, now the theme defined in our theme add-on product is in use in our site. Check it out in portal_skins:

Building our own Plone 3 Theme Add-on Product

Notice three things in the previous screenshot: the Default skin is our recently created skin and three additional Plone skin layers have been added to the top of the layer's precedence order list. These three layers will contain the resources we may need for our new theme. These layers represent three folders inside our package structure; to be more precise, those inside skins folder:

Name of the layer/folder

Description

plonetheme_myintranet_custom_images

It will contain our theme images.

plonetheme_myintranet_custom_templates

It will contain our theme custom templates.

plonetheme_myintranet_styles

It will contain our theme styles.

In fact, this layer organization is merely for convenience, as all the layers can contain any type of resources.

Customizing Plone skin layer resources

As our theme product is positioning the new layers on the top of the precedence order, the elements we place in these folders will override those in layers with less precedence. Just place our custom resource in any of the layers defined by our product and name it as the original one. Our custom resource will override the default one. We can also place other resources we may use, such as our custom templates, images, and styles as well.

Enabling CSS debug mode

By default, the changes made to our product will not be available until we restart our instance. For the changes to take effect immediately, we should enable CSS debug mode in CSS resource registry. We will find this setting at the top of the portal_css ZMI view.

In debug/development mode, stylesheets are not merged to composites, and caching and compression of CSS is disabled. The registry also sends HTTP headers to prevent browsers from caching the stylesheets. It's recommended to enable this mode during CSS-related development. Remember to turn it off again when we finish CSS modifications, as debug mode affects site performance.

Customizing the site logo

Plone renders the site logo combining two kinds of resources—the viewlet plone. logo provides the HTML structure needed and a Plone skin layer image. Let's say we want to change the site logo and add an additional logo of our company containing a link to the corporate web besides it. We need to customize the original logo with the logo of our intranet and add the required HTML structure to add the new company logo besides the original one. We will need to customize the original logo and the plone.logo viewlet. Later, we will need to add our company logo as a new Plone skin layer image.

Customizing the logo image and adding a new one

We should override the original logo image with our customized one. In order to accomplish this, we should rename the image we've chosen to use as our site logo with the same name as the original one. The original logo image is called logo.jpg and it is located in the plone_images skin layer. We override it by simply placing our customized image inside skins/plonetheme_myintranet_custom_images and naming it exactly the same as the original one. Place the image for the second logo here too, and name it as company-logo.png.

Customizing the plone.logo viewlet

Customizing a viewlet is a little trickier than overriding skin layer resources. We will need to tell Zope that we want to override the original viewlet declaration by creating an overrides.zcml file in the plonetheme/myintranet folder of our custom add-on product, and add the attribute that tells Zope where to find the new template associated to this viewlet:

<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:i18n="http://namespaces.zope.org/i18n"
i18n_domain="plonetheme.myintranet">
<!-- The new logo viewlet declaration -->
<browser:viewlet
name="plone.logo"
manager="plone.app.layout.viewlets.interfaces.IPortalHeader"
class="plone.app.layout.viewlets.common.LogoViewlet"
template="browser/newlogo.pt"
permission="zope2.View" />
</configure>

Then place this Zope page template called newlogo.pt in the browser folder of our add-on product:

<a id="portal-logo-company"
tal:attributes="href string:http://www.mycompany.com/">
<img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="company-logo.png"
alt="Company.com logo"
title="Company.com logo"/></a>
<a metal:define-macro="portal_logo"
id="portal-logo"
accesskey="1"
tal:attributes="href view/navigation_root_url"
i18n:domain="plone">
<img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="logo.jpg" alt=""
tal:replace="structure view/logo_tag" /></a>

We leave the original logo template at the end of the file and add a new link tag with the structure for the new logo and the reference to the new Plone skin layer image (company-logo.png).

Restart our instance to see the changes applied. This is needed because we have overridden a viewlet defining an additional ZCML file.

Plone 3 Intranets Design, build, and deploy a reliable, full-featured, and secure Plone-based enterprise intranet easily from scratch
Published: August 2010
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

(For more resources on Plone, see here.)

Customizing Plone CSS

If you followed the previous example, you've probably noticed that the recently added new logo is somehow displaced. If we want to adjust its position, we will need to customize some CSS files. In this case, we need to define a style for the new ID (portal-logo-company) introduced by the structure of the company logo. We can do it in an empty CSS file provided by the PasteScript template, already available in our theme product. It's called main.css and it's located in the plonetheme/myintranet/browser/stylesheets/ folder.

Open it and add these lines:

#portal-logo-company img {
border:0 none;
margin:1em 0 1em 2em;
padding:0;
}

We can also adjust some other CSS declarations by adding them to this file. As main.css is located at the bottom of the CSS chain, the definitions in it will be the last being applied. For this reason, we can override any previous CSS definitions by redefining them in this file.

For example, let's adjust the space between both logos by reducing the margin defined by the portal-logo ID. Add these lines to main.css file:

#portal-logo img {
margin:1em 0 1em 1em;
}

If you want to know more about Plone CSS and the resources involved in Plone styling, you should check the CSS files located in the plone_styles layer. They are organized by importance, styled elements, or purpose. The following table gives a little summary about them:

Name of the CSS resource

Description

member.css.dtml

Plone member specific CSS, such as styling for the colors

assigned to workflow states in the state drop-down box.

base.css.dtml

Plone basic elements CSS, such as styling for basic tag

elements (a, body, and so on)

public.css.dtml

Plone public facing elements CSS, such as style for the

content headers (h1, h2, and so on).

columns.css.dtml

Plone table-based layout CSS.

authoring.css.dtml

Plone authoring/editing environment CSS.

portlets.css.dtml

Plone portlets CSS.

controlpanel.css.dtml

Plone control panel CSS.

print.css.dtml

Plone print CSS applied when printing some site element.

deprecated.css.dtml

Deprecated Plone CSS elements that will disappear in

the next version.

navtree.css.dtml

Plone navigation tree CSS.

invisibles.css.dtml

Plone invisible elements and accessibility elements CSS.

forms.css.dtml

Plone forms CSS.

RTL.css.dtml

Plone right-to-left CSS (for Arabic and Hebrew).

ploneCustom.css.dtml

Blank CSS file ready for quick style customization.

Since Plone 4 no longer uses DTML files to define CSS, if we want to customize them , we should just remove the .dtml extension from the previous Files.

Resetting Plone CSS

If we want to reset the CSS defined by Plone completely, we should include these empty files in our product skin layer folder plonetheme/myintranet/skins/ plonetheme_myintranet_styles:

  • base.css.dtml
  • public.css.dtml
  • portlets.css.dtml

How to customize CSS effectively
It's recommended to use some kind of helper application when dealing with CSS, for example, Firebug (http://getfirebug.com/). This tool will help us to identify the correct CSS file used by any element of the site and preview the results of any change to the CSS on the fly. Don't forget to enable debug/development mode in your portal_css resource registry!

More about customizing viewlets

All the default viewlets are defined in a Plone egg called plone.app.layout. We can find it by browsing the eggs folder inside our buildout.cfg folder. We can override any of them following these steps:

  • Use the manage-viewlets view to identify the viewlet we want to customize.
  • Search the viewlet declaration in the configure.zcml file inside the plone. app.layout-1.2.5-py2.4.egg/plone/app/layout/viewlets folder. For example, if we want to customize the portal breadcrumbs located in the plone.path_bar viewlet, find the snippet of code referring to this viewlet. It should look like this:

    <!-- The breadcrumbs -->
    <browser:viewlet
    name="plone.path_bar"
    manager=".interfaces.IPortalTop"
    class=".common.PathBarViewlet"
    permission="zope2.View" />

  • Copy these lines to the overrides.zcml file and modify them to look like:

    <!-- The new site breadcrumbs declaration -->
    <browser:viewlet
    name="plone.path_bar"
    manager="plone.app.layout.viewlets.interfaces.IPortalTop"
    class="plone.app.layout.viewlets.common.PathBarViewlet"
    template="browser/newpathbar.pt"
    permission="zope2.View" />

  • As we are overriding a viewlet located in another egg product, we should complete the prefix in the manager attribute with the full path to the plone. app.layout egg. Do the same for the class attribute.
  • Add a line with a template attribute defining where the new template for this viewlet is located. Its location is relative to our product folder. In the example, we are defining a new template for the viewlet called newpathbar. pt located in the browser folder. It's recommended that we copy the default template defined by plone.app.layout and customize it. We will find it in the plone.app.layout-1.2.5-py2.4.egg/plone/app/layout/viewlets folder; it's called path_bar.pt.

Using Generic Setup to customize a theme

Once more, Generic Setup (GS) has some configuration files that help us to customize some theming aspects of our site. We can add the following GS definition files to the default profile of our product:

Generic Setup file

Description

cssregistry.xml

It configures the CSS resource registry (portal_css). We can add more CSS resources and configure them. By default, Paster defines the main.css file and places it at the bottom of the CSS chain.

jsregistry.xml

It defines the JavaScript resource registry (portal_javascript).

viewlets.xml

It configures the position and the visibility of the site viewlets. Basically we can perform all the tasks provided by manage-viewlets view.

skins.xml

This file holds the setup configuration for the portal_skins tool. We can enable new layers and position and order them in the layer precedence list.

Theming—best practices

Whilst theming for an intranet, it is important to keep one thing in mind: try to keep it as clean and simple as possible for one thing only—performance. Most of the time, our intranet will be used by authenticated members. This means that all the security calculations, template generating, and the JavaScript needed in the edit mode will be at work.

Try to minimize their effects by not bloating our intranet theme. It will be always well-received by our users and their subjective sense about how our site performs. Think that an intranet usually doesn't have to sell anything, as a public site would do. Probably the only thing we have to sell to our intranet users is value, productivity, elegance, efficiency, and a corporate look and feel. So, try to deliver all of these to them!

This doesn't mean that our intranet has to be austere, ugly, or boring. On the contrary, it's just a matter of finding the correct balance and applying it.

Summary

In this article we covered the building of our own theme add-on product. We also covered the best practices on theming an intranet.


Further resources on this subject:


Plone 3 Intranets Design, build, and deploy a reliable, full-featured, and secure Plone-based enterprise intranet easily from scratch
Published: August 2010
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Víctor Fernández de Alba

Víctor has been an IT architect at UPCnet, the Barcelona Tech University (UPC) IT company since 2001. He has led the design and technical architecture of the more than 100 projects undertaken by the UPCnet Plone Team since its inception in 2004. He has taught Plone to non-technical end users at the university several times. This allowed him to use this close experience with users to improve the usability of web projects developed by his team. He also writes manuals about Plone targeted at end users.

The flagship project of the UPCnet Plone Team is Genweb UPC. This project allows deploying a fully featured, theme customized, and end-user ready site in a few short steps. It has helped to launch more than 200 Plone-powered sites at the university including departmental websites and intranets, university services, faculties sites, and other entities. In December 2009, the UPCnet Plone Team finished one of its more ambitious projects and the main website of the Barcelona Tech University became a reality. It was developed focusing on scalability, high performance, and usability using Plone.

Books From Packt

Plone 3 Multimedia
Plone 3 Multimedia

Joomla! 1.5 Site Blueprints
Joomla! 1.5 Site Blueprints

Moodle 2.0 First Look
Moodle 2.0 First Look

CMS Made Simple 1.6:   Beginner's Guide
CMS Made Simple 1.6: Beginner's Guide

FreeSWITCH 1.0.6
FreeSWITCH 1.0.6

YUI 2.8: Learning the Library
YUI 2.8: Learning the Library

Compiere 3
Compiere 3

Moodle 1.9 Teaching Techniques
Moodle 1.9 Teaching Techniques

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software