Attention

This document was written for an old version of Plone, Plone 3, and was last updated 250 days ago.

To learn how to upgrade to the current version of Plone, read the upgrade manual.

How to Create a Plone 3 Theme Product on the Filesystem

by Veda Williams last modified Sep 13, 2012 01:48 PM
This tutorial describes the creation of a filesystem-based theme product for Plone 3.x. It is intended for integrators and assumes some familiarity with CSS, HTML, Javascript, and Plone/Zope.

Jumpstart Your Theme Development Using Paster

The quickest and most efficient way to get started is not to create your theme product folders and associated files from scratch, but to take advantage of a product generator which will automatically create the framework for a theme product based on your responses to a few interactive questions.

Using Paster Through the Web

New users may feel more comfortable using a through the web tool that allows them to generate a theme product. One such tool can be found at http://paster.joelburton.com/. You may wish to reference some of the information below for more information on what is actually happening as you fill out these questions.

Using Paster on Your Local Machine

For users more comfortable using the command line, you are more likely to use a tool called ZopeSkel and the paster templates it contains. ZopeSkel is a collection of PasteScript templates which can be used to quickly generate Zope and Plone projects like buildouts, archetypes products and, most pertinently for us, Plone themes.

To determine whether you have paster and ZopeSkel installed, try "paster create --list-templates" at the command line. If "plone3_theme" is not in the list of available templates, you may have to install paster and/or ZopeSkel, as explained by Daniel Nouri.

If you have paster and ZopeSkel installed, navigate to the directory where you'd like to create your product and run from the command line:

$ paster create -t plone3_theme plonetheme.mytheme

This will initiate a series of questions by the paster script. The defaults are largely appropriate for your first theme, so in many cases you can simply hit return. Here is example output from the interactive session.

Selected and implied templates:
ZopeSkel#basic_namespace A project with a namespace package
ZopeSkel#plone A Plone project
ZopeSkel#plone3_theme A Theme for Plone 3.0

Variables:
egg: plonetheme.mytheme
package: plonethememytheme
project: plonetheme.mytheme
Enter namespace_package (Namespace package (like plonetheme)) ['plonetheme']:
Enter package (The package contained namespace package (like example)) ['example']:mytheme
Enter skinname (The skin selection to be added to 'portal_skins' (like 'My Theme')) ['']:My Theme
Enter skinbase (Name of the skin selection from which the new one will be copied) ['Plone Default']:
Enter empty_styles (Override default public stylesheets with empty ones?) [True]:
Enter include_doc (Include in-line documentation in generated code?) [False]:True
Enter zope2product (Are you creating a Zope 2 Product?) [True]:
Enter version (Version) ['1.0']:
Enter description (One-line description of the package) ['An installable theme for Plone 3.0']:
Enter long_description (Multi-line description (in reST)) ['']:
Enter author (Author name) ['Plone Collective']:
Enter author_email (Author email) ['product-developers@lists.plone.org']:
Enter keywords (Space-separated keywords/tags) ['web zope plone theme']:
Enter url (URL of homepage) ['http://svn.plone.org/svn/collective/']:
Enter license_name (License name) ['GPL']:
Enter zip_safe (True/False: if the package can be distributed as a .zip file) [False]:

You cannot use 'delete' to correct a typo during the interactive session. If you make a mistake, ctrl-c to stop the script and start over.

Some of these questions warrant further explanation:

Enter namespace_package
It is good practice to use the 'plonetheme' namespace for your theme. You can use other namespaces, of course ('products' might be another), but unless you have a compelling reason to do otherwise, use 'plonetheme'.
Enter package
The 'package' is simply the lowercase name of your theme product, sans spaces or underscores.
Enter skinname
The 'skinname' is the human-readable name for your theme. Spaces and capitalization are appropriate.
Enter skinbase
In nearly all cases, you'll want to leave this as 'Plone Default'.
Enter empty_styles
Answering 'True' will cause empty stylesheets to be added to your product which will override the default base.css, public.css, and portlets.css included in any Plone site using the 'Plone Default' skin. 'False' will not add empty stylesheets.
Enter include_doc
Answering 'True' will cause inline documentation to be added to the files created by ZopeSkel. It is worth doing this at least once, as some of the documentation is quite useful.
Enter zope2product
Answering 'True' means that the package will be useable as an egg, it will be listed in the ZMI, skin folders will be registered as layers with the Skins Tool ('portal_skins'), and the Generic Setup profile for the product can be loaded via the Setup Tool ('portal_setup'). We'll explore some of this further; for now, suffice to say that you'll always want to enter 'True' here when generating a Plone theme.
Enter zip_safe
Stick with the default here.
Creating new eggs and packages quickly with paster
How to use the paster command to create new packages with proper setuptools- and egg-compliant filesystem layout quickly and easily.

Background: Python Eggs, Generic Setup and Zope 3

Products, in Plone's parlance, are analogous to modules or extensions for other applications. In the move from Plone 2.5 to Plone 3, several important changes were made in the way Plone handles products. First, some products began to be packaged as Python eggs, which made them easier to manage, distribute and install. Second, products began to use GenericSetup as a means for installation. And third, products increasingly incorporated Zope 3 (Z3) technologies like browser views.

Python Eggs

A python egg is simply a bundle of files and directories which constitute a python package. Eggs can either be compressed, in which case they appear as a single *.egg file, or uncompressed. Eggs are similar in concept and function to Java's JAR files.

Eggs are installed via the setuptools framework, a side project of the Python Enterprise Application Kit (PEAK), which provides for package (and dependendency) management and distribution.

If you're using version control, you'll want to add *.egg-info and *.pyc to the ignore patterns for your setup so that the egg metadata and compiled python files aren't added to your repository.

A Quick Guide to Python Eggs
A good overview of eggs and setuptools from the folks at PEAK.
Hatch Python Eggs with SetupTools
David Metz takes a look at the setuptools framework.

GenericSetup

GenericSetup (GS) is a tool for managing site configuration in Plone using xml files. GS makes it possible to export customizations from one Plone site and import them into another. And to some extent, GS replaces the Portal QuickInstaller (QI) post-Plone 2.5 in that GS can be used to install products. In products which rely on GS, we find xml configuration files; in products which use the older, venerable QI for installation, by comparison, we find install methods written in python.

Keep in mind that GenericSetup does not currently allow you to undo the profile applied during installation. You can uninstall your theme using the QuickInstaller, however, assuming that an uninstall method is present.

Because our skeleton theme product utilizes GenericSetup to install itself, we will shortly be configuring several xml files needed by GS.

Understanding and Using GenericSetup in Plone
Now a bit dated, Rob Miller's tutorial on GS remains a useful resource for background on GS.
GenericSetup Improvements
More information about GS from Rob Miller.
Benefit NOW from Using GenericSetup and Z3 Technologies
Impress your colleagues by using GenericSetup and Zope 3 views efficiently and with minimal effort! This tutorial shows you how to add a new view, how to use it, how to add a new content type and how to hook it all up.

Zope 3 Technology

Despite any version number-induced miasma, remember that Plone 3 runs on Zope 2. Zope 3 is a dramatic rewrite of Zope 2 and some Zope 3 functionality has been backported to work under Zope 2. (And yes, Plone 3.) For a full explanation of the Zope 3 technologies involved, consult this tutorial:

Customization for developers
An overview of Plone 3 customization by Martin Aspeli.

Anatomy of a Plone Theme Product

Assuming that you've created your theme product successfully, you should have a directory structure that looks roughly like this:

    plonetheme.mytheme
docs
HISTORY.txt
INSTALL.txt
LICENSE.GPL
LICENSE.txt
MANIFEST.in
plonetheme
__init__.py
mytheme
__init__.py
browser
__init__.py
configure.zcml
images
README.txt
interfaces.py
stylesheets
main.css
README.txt
viewlet.pt
viewlets.py
configure.zcml
profiles
default
cssregistry.xml
import_steps.xml
jsregistry.xml
metadata.xml
plonetheme.mytheme_various.txt
skins.xml
viewlets.xml
profiles.zcml
setuphandlers.py
skins
plonetheme_mytheme_custom_images
CONTENT.txt
plonetheme_mytheme_custom_templates
CONTENT.txt
plonetheme_mytheme_styles
base.css.dtml
base_properties.props
CONTENT.txt
portlets.css.dtml
public.css.dtml
skins.zcml
tests.py
version.txt
plonetheme.mytheme-configure.zcml
plonetheme.mytheme.egg-info
dependency_links.txt
entry_points.txt
namespace_packages.txt
not-zip-safe
paster_plugins.txt
PKG-INFO
requires.txt
SOURCES.txt
top_level.txt
README.txt
setup.cfg
setup.py
zopeskel.txt

Things may seem a little complicated at this point, but not to worry. Let's take closer look at the main files and directories according to their respective functions.

Documentation

docs/
The docs directory contains installation instructions (INSTALL.txt), license files, and the development log (HISTORY.txt).
README.txt
The top-level text file contains the one-line description of the product you entered during the interactive session with ZopeSkel. Other README files exist throughout the product.

Python Package

plonetheme/
This is a namespace package, which serves to group other packages.
mytheme/
This is the actual name of your theme, usually the name of the client or project you are working on.
tests.py
Python tests for our package go here. Typically themes don't have much python code, and so don't have much in the way of testing.
version.txt
The version of our product. This information is also contained in /profiles/default/metadata.xml.

Python Egg

plonetheme.mytheme.egg-info/
The egg metadata is stored here.
setup.cfg
This configuration file contains information used to create egg-info files.
setup.py
If we wanted setuptools to handle the installation of the package and dependencies we could install via "python setup.py install" (for now, we don't).

GenericSetup

profiles.zcml
Register appropriate GenericSetup profiles.
profiles/
"Default" is the current configuration profile (only one profile is automatically created, but more could be added). Within our configuration profile we have XML files which tell GS how to configure CSS files (cssregistry.xml), Javascript files (jsregistry.xml), skin layers (skins.xml), and viewlets (viewlets.xml). Metadata.xml tracks the product version number and other metadata, import_steps.xml _____ and the presence of plonetheme.mytheme-various.txt tells GS to look to setuphandlers.py for additional methods.

Zope 3

plonetheme.mytheme-configure.zcml
This is the ZCML slug which must be placed in the etc/package-includes if the theme is installed as a python package (ours won't be).
configure.zcml

skins.zcml
Register skin layers (images, styles, templates) as filesystem directory views.
browser/

Stylesheets, Templates and More

Once you've got your theme product in place, the next step is to modify the pieces that Plone gives us, specifically templates, stylesheets, and viewlets.

Templates/
Plone templates, specifically the main_template that controls the layout of a Plone site, can be grabbed from the parts/plone/CMFPlone/skins/plone_templates directory. Most of the templates that were contained here in 2.5 have been moved to eggs and are controlled by viewlets. To modify a template from this directory, copy it to your theme product, into your theme's skins/templates folder and make your modifications there.
Stylesheets/
Plone's default stylesheets can be found in your buildout/parts/plone/CMFPlone/skins/plone_styles directory. It's usually advisable to create a stylesheet specific to your theme product, e.g. "mytheme.css" (where "mytheme" is the name of your theme product), and then take any relevant styles from CMFPlone's stylesheets and customize them in your own theme product, rather than overriding entire CMFPlone stylesheets. The one exception here may be IEFixes.css, which you likely want to keep intact as a single file, since it is called in explicitly from the main_template.
Viewlets/
It is a great oversimplification to state that most often you will be overriding viewlets from eggs commonly known as plone.app.layout, plone.app.portlets, and plone.app.content. Those viewlets, can be found in your buildout/eggs/ in packages named "plone.app.layout[xx]," "plone.app.portlets[xx]," and "plone.app.content[xx]," where [xx] is a version number. When modified, these viewlets and their related code belong in your theme product's browser/ directory. For more information on how to work with viewlets, read this tutorial.

If modifying page templates, you won't need to restart Zope in order to see your changes take effect. Changes to python, XML or ZCML, however, will require a restart.

Customization for developers
An overview of Plone 3 customization by Martin Aspeli.
Find the best theme of iphone 4s deals handset

Installing Your Theme Product 

For more information, go here: http://plone.org/documentation/how-to/how-to-install-a-3-x-theme-using-buildout

 

 


Contribute

Something wrong or out of date? Anybody can edit or create a new article in the knowledge base. Simply create an account on this site, log in, and click the Edit button to contribute.