(For more resources on Plone, see here.)
Plone’s stock configuration delivers a great deal of concrete functionality: workflow, security, tagging, and more. However, the people whom you need to win over—like your boss and the public—often form their first impressions of your site based solely on visual design. Replacing the out-of-the-box look of Plone with one tailored to your organization is thus a very important task.
Changing the overall look of a Plone site requires more than just the web designer’s usual toolkit of HTML and CSS. In this article, we provide an introduction to the additional Zope- and Plone-specific techniques you need. We give an overview of Plone’s somewhat complicated theming situation, show how to theme a site in a portable, reusable way, and demonstrate practices that strike a balance among ease, speed, and compatibility with future versions of Plone. Theming is a complex topic, and there are entire books on that topic alone, so we also give plenty of outside references in case your needs extend beyond the basic.
An overview of Plone theming
Plone themes, also known as skins, are visual designs that can be applied to a site, independent of its content. There are two main ways to create a theme: through the web and via the filesystem.
Through-the-web versus filesystem
One of the great advantages of Zope (and thus Plone) has historically been the customization power available through its web-based interface. Though there are some holes in this functionality with Plone 3 and 4, you can, for the most part, still point and click your way to a working theme. The advantages of this approach are:
- Immediate feedback. Iterations are simple. As a result, you’re encouraged to test often, bugs turn up early, and bugs caught early are bugs solved easily.
- Explorability. Though the Zope Management Interface, where most theme work takes place, isn’t the best-organized or friendliest environment in the world, it at least offers some semblance of navigable structure. You can find a piece of HTML or CSS you want to customize, click a button, and begin editing. There’s less need to think abstractly.
- Accessibility. Through-the-web theming requires no access to the server’s filesystem, so it is usable by people without, for example, Unix command-line experience or the ability to restart Zope.
The alternative is theming by developing add-on products, which live on the server’s filesystem. The advantages of this are:
- Better tools. Expressing a theme as files and folders lets you use the entire ecosystem of filesystem-based development tools: proper text editors and version control systems, for example.
- Ease of re-use. Encapsulating a theme as a product means you can easily make use of it on more than one site, copy it from machine to machine, or share it with the world.
- Completeness. Some customizations can’t yet be done through the Web: for example, moving the search box from the top of the page to the bottom by moving its viewlet into a different viewlet manager.
In practice, a filesystem product is usually better, with through-the-web styling used to test changes and to make emergency in-production tweaks between Zope restarts.
A load of languages
Theming involves several special-purpose languages. Here’s the rundown:
Use in Theming
The old standby, Hypertext Markup Language defines the semantic
structure of every page. Plone’s markup sticks admirably to specifying
meaning and avoids visual design. For example, its navigation bars are
<ul>s, and its portlets (those omnipresent titled sidebars) are actually
definition lists (<dl>s) with the title as the term and the content as the
definition. Visual styling is applied almost wholly by CSS.
Cascading Stylesheets, another standard tool in the web designer’s kit,
apply a layer of visual design atop HTML. Because Plone’s HTML so
assiduously avoids visual design, we can change the look of a Plone site
substantially without tampering with markup.
Most theming can be done with just CSS, but sometimes, like when
adding new element to a page, only HTML changes will do. All HTML
in Plone is produced by Template Attribute Language (TAL), a simple
XML-based language so named because it nestles entirely within the
attributes of XML tags. Like other templating languages, TAL is a more
readable alternative to littering program code with bits of hard-coded
markup. It is good for inserting content into a page skeleton, repeating
portions of a page, and doing other simple presentation logic. More
complicated logic is best done in Python modules, where you aren’t
limited to cramped one-liners.
A good introduction to TAL is http://docs.zope.org/zope2/zope2book/ZPT.html.
The Macro Expansion for TAL (METAL) language helps combine
bits of TAL from different templates to create a single page.
is a good introduction.
The general-purpose language Zope and Plone are written in.
We will write almost no Python in this article, but it often does
make an appearance in page templates. It has a much more prominent
role in Zope 3-style theming than in Zope 2.
Some parts of theming use the Zope 3 component architecture, a scheme
for tying plugins and customizations into a large system like Plone. The
Zope Component Markup Language (ZCML) is an XML-based language
that specifies where to plug these in. For example, we will use ZCML to
tie our theme product to a third-party package that drastically simplifies
overriding some templates.
A variety of XML mini-languages, which show up in your product’s
profiles folder. These are run by GenericSetup, Plone’s installation
framework, when your theme product is installed or uninstalled.
Don’t let theming hold you up
Theming is complicated and can be time-consuming the first time through. Don’t make the common mistake of letting it hold up work on the rest of your site. Indeed, most information-oriented work—audience analysis, the creation and input of content, information architecture decisions, and development of custom content types—can go on without much thought toward the coat of paint that will eventually go over it. (Likewise, you can change the look of your site later without having to redo all your navigation and content.)
The few elements to decide on ahead of time are…
- Navigation. What is your navigation strategy? Should the theme provide space for main or contextual navigation or for a search field? It can help to have your graphic designer join you for the last few minutes of each information architecture discussion to synchronize expectations. Drawing wireframes is another fast way to get everybody on the same page. For an excellent primer on strategies for organizing your site’s content, see Peter Morville’s Information Architecture for the World Wide Web.
- CSS styles. The style menu in Plone’s built-in editor is commonly customized to suit the semantic needs of the site at hand. Decide early in the design process what styles will be needed: for example, body text, warning messages, sidebars containing supplementary material, and various levels of headings. It’s not necessary to settle on a look for these styles—just to enumerate them and establish their CSS class names. After that, theme and content work can progress in parallel.
Prepare your development environment
Before we get down the business of creating a theme, make sure you have all the tools and settings in place:
- Run Zope in foreground mode. When developing, always launch Zope using bin/instance fg rather than bin/instance start. At the cost of a little processor power, this greatly speeds development by…
- Printing error messages, usually hidden in the event.log file, to the terminal. Plone typically makes a lot of noise when it starts up; that can be ignored. But watch for errors, hidden among the innocuous INFO and DEBUG messages, when you exercise the functionality of your product.
- Turn on CSS debug mode. With Plone 3.3 or above, you can skip this step, as it’s implicitly done when you run Zope in foreground mode. In older versions of Plone, go into the ZMI, then to your Plone site, and finally to portal_css. There, turn on Debug/development mode. This will keep Plone from doing its clever caching, merging, and compression of stylesheets while you’re developing them, helping ensure that you always see the latest version of your work. Without CSS debug mode, your CSS changes will take effect only when Zope is restarted.
- Get Firefox, Firebug, and the Web Developer add-on. Firefox is a nice browser, but what really makes it shine is its third-party plugins. Get the latest version, available from http://www.getfirefox.com/, then grab two vital plugins, Firebug (http://getfirebug.com/) and Web Developer (https://addons.mozilla.org/firefox/addon/60).
- Turn off caching. In Firefox, show the Web Developer Toolbar (View ? Toolbars ? Web Developer Toolbar), then pull down its Disable menu and select Disable Cache. Together with enabling CSS debug mode, this will ensure that you always see your latest CSS changes. Nothing is more frustrating than spending hours chasing a problem, only to track it down to a stale cache. If you use Firefox for casual browsing, you may not wish to disable caching globally and slow down your surfing. In that case, be sure to use Shift+Command+R (on the Mac) or Shift+Ctrl+R (on other platforms) to force your stylesheets to reload when doing theme work.
Begin your theme
On-disk theme products can be quite verbose, so we employ a program to generate the skeleton of ours. We’ll then make a few clean-ups before moving on to making a visual impact.
Install paster and ZopeSkel
To generate the empty shell of a theme, we’ll use a code generation tool called paster. A set of Zope- and Plone-specific code snippets, called ZopeSkel, extends paster to provide a sort of “madlibs for Plone”, churning out skeletal products whose blanks we can fill in. Here’s how to get a copy of paster up and running:
- Some installations of Plone come with paster and ZopeSkel; check the bin folder in your buildout. If paster is in there, you’re done; skip to the next section. If not, read on.
- Install easy_install, a simple Python installer, which we can use to install paster and ZopeSkel. Follow the platform-specific instructions on the easy_install download page: http://pypi.python.org/ pypi/setuptools.
- Use easy_install to install ZopeSkel, which also automatically installs paster. For example: