Examining themes with Omelette and Python

Installing themes with Buildout

For a lot of website projects, a theme downloaded from plone.org (http://plone.org/products) or the Python Package Index (http://pypi.python.org) is enough to launch a professional-looking site. If your project falls into this category, or if you just want to experiment, follow the steps in this chapter.

Searching for themes on plone.org

We will need to find a theme we like. We can do that by browsing to http://plone.org. Next, click on Downloads Add-on Product Releases | Themes|.

You should see (result similar to):

Examining themes with Omelette and Python

Click on a theme to view a screenshot and select one you like, for example beyondskins.ploneday.site2010, and add the package to your buildout.cfg file.

Adding themes with Buildout

In 03-appearance-wpd2010.cfg, we extend the last known working configuration file from Chapter 2, that is 02-site-basics-blog.cfg.

It looks like this:

extends = 02-site-basics-blog.cfg

eggs += beyondskins.ploneday.site2010
zcml += beyondskins.ploneday.site2010

In addition to adding the package name to the eggs parameter, we must add it to the zcml parameter as well.

Now stop Plone (with Ctrl + C or Ctrl +Z/Enter) and run:

$ bin/buildout -c 03-appearance.cfg

Updating zope2.

Updating fake eggs

Updating instance.

Getting distribution for 'beyondskins.ploneday.site2010'.

Got beyondskins.ploneday.site2010 1.0.3.

Now start Plone:

$ bin/instance fg

Installing themes in Plone

Browse to http://localhost:8080/Plone. Now, click on Site Setup Add/Remove Products| and you should see:

Examining themes with Omelette and Python

Check the box next to WorldPloneDay: Theme for 2010 edition 1.0.3 and click on Install.

Now browse to http://localhost:8080/Plone and you should see:

Examining themes with Omelette and Python

This theme is the courtesy of Simples Consultoria (http://www.simplesconsultoria.com.br/). Thank you!

You can examine the anonymous view (what everyone else sees) by loading in your browser (that is. by using the IP address instead of the hostname). You can also load either of these URLs ( or http://localhost:8080/Plone) from another web browser (besides the one you are currently using) to see the anonymous view (for example, Safari or Internet Explorer, instead of Firefox).

Examining themes with Omelette and Python

To display the blog entry to the public, we have transitioned the other objects in the site root to the private state.

Examining themes with Omelette and Python

Simply put, a theme is a collection of templates, images, CSS, JavaScript, and other files (such as Python scripts) that control the appearance of your site.

Typically these files are packaged into a Python package, installed in your Plone site with the help of Buildout, and installed in Plone via the Add/Remove Products configlet in Site Setup.

Once installed, certain elements of the theme can be edited through the Web using the ZMI. However, these changes only exist in the site's database. Currently there is no easy way to transfer changes made through the Web from the database to the filesystem; so there is a trade-off for performing such customizations through the Web. If you lose your database, you lose your customizations.

Depending on your goals, it may not be entirely undesirable to store customizations in your database. But nowadays, most folks choose to separate their site's logical elements (for example themes, add-on functionality, and so on) from their site's content (that is data).

Creating a filesystem theme and resisting the urge to customize it through the Web accomplishes this goal. Otherwise, if you are going to customize your theme through the Web, consider these changes volatile, and subject to loss.

Installing and using Omelette

A great way to examine files on the filesystem is to add Omelette (http://pypi.python.org/pypi/collective.recipe.omelette) to your buildout.cfg and examine the files in the parts/omelette directory.

Omelette is a Buildout recipe that creates (UNIX filesystem) symbolic links from all the Zope 2, Plone, and add-on installation files to one convenient location. This makes the job of examining files on the filesystem much easier.

To install Omelette, in 03-appearance-omelette.cfg, we have this:

In this configuration file, we extend the sections and parameters in 03-appearancewpd2010.cfg, and add a new section called omelette to the parts parameter(in the buildout section).

Remember that using the += syntax adds the new value to the current value, so the parts list becomes:

extends = 03-appearance-wpd2010.cfg
parts +=

recipe = collective.recipe.omelette
eggs = ${instance:eggs}
packages = ${zope2:location}/lib/python

(We can examine the current state of the buildout by looking in the .installed.cfg file in the root directory of the buildout.)

We also tell Omelette what files to link in the eggs and packages parameters:

  • ${instance:eggs}: Refers to the packages in the eggs directory.
  • ${zope2:location}/lib/python: Refers to the modules in the parts/zope2/lib/python/ directory.

You can read more about how to configure Omelette here: http://pypi.python.org/pypi/collective.recipe.omelette.

Now stop Plone (with Ctrl + C or Ctrl +Z/Enter) and run:

parts = zope2 instance plonesite omelette

You should see:

$ bin/buildout -c 03-appearance-omelette.cfg

Omelette in Windows

As of version 0.5, Windows supports Omelette if you have the Junction program installed (and configured in your path). Junction is easy to install, and available here: http://www.microsoft.com/technet/sysinternals/fileanddisk/junction.mspx.

Now that Omelette has been installed, take a look in the parts/omelette directory.You should see:

$ bin/buildout -c 03-appearance-omelette.cfg

Getting distribution for 'collective.recipe.omelette'.

Got collective.recipe.omelette 0.9.

Uninstalling plonesite.

Updating zope2.

Updating fake eggs

Updating instance.

Installing plonesite.

zope/configuration/xmlconfig.py:323: DeprecationWarning: zope.app.
annotation has moved to zope.annotation. Import of zope.app.annotation
will become unsupported in Zope 3.5


Retrieved the admin user

A Plone Site already exists and will not be replaced

Installing omelette.

Exploring modules with zopepy

These files correspond directly to the modules available in Python when Plone is running. To demonstrate this, let us configure a Python interpreter with the modules added to the sys.path.

In 03-appearance-zopepy.cfg, we have this:

$ ls -1 parts/omelette
























We extend the last working configuration in 03-appearance-omelette.cfg and add a new section called zopepy (short for "Zope Python").

Now stop Plone (with Ctrl + C or Ctrl +Z/Enter) and run Buildout:

extends = 03-appearance-omelette.cfg
parts +=

recipe = zc.recipe.egg
eggs = ${instance:eggs}
interpreter = zopepy
extra-paths = ${zope2:location}/lib/python
scripts = zopepy

You should see:

$ bin/buildout -c 03-appearance-zopepy.cfg

This creates a script that invokes the Python interpreter with the Plone modules added to the sys.path. Now if you run bin/zopepy, you can explore modules in Python.

For example, you can import the beyondskins module (from the top-level namespace):

$ bin/buildout -c 03-appearance-zopepy.cfg

Uninstalling plonesite.

Updating zope2.

Updating fake eggs

Updating instance.

Installing plonesite.

DeprecationWarning: zope.app.
annotation has moved to zope.annotation.
Import of zope.app.annotation
will become unsupported in Zope 3.5


Retrieved the admin user

A Plone Site already exists and will not be replaced

Updating omelette.

The recipe for omelette doesn't define an update method. Using its
install method.

Installing zopepy.

Generated interpreter '/Users/aclark/Developer/plone-site-admin/

Python will try to evaluate any statement you input. For example, type beyondskins and hit Enter:

$ bin/zopepy

>>> import beyondskins


Python will tell you that beyondskins is a module. You can also try to call beyondskins (as if it were a function or class method):

>>> beyondskins

<module 'beyondskins' from '/Users/aclark/Developer/plone-siteadmin/

Python will now tell you that module objects are not callable. You can use the builtin dir function to view the attributes of the beyondskins module:

>>> beyondskins()

Traceback (most recent call last):

File "<console>", line 1, in ?

TypeError: 'module' object is not callable

Now, Python will tell you its attributes. You can inquire about a specific attribute such as __path__:

>>> dir(beyondskins)

['__builtins__', '__doc__', '__file__', '__name__',

Python will return its value. Just for fun, you can inquire about any attribute of any module:

>>> beyondskins.__path__



The value of Products.__path__ is too long to print here. It contains a list of all packages that contain a Products module. All of this code ends up in the Products namespace in Python, handy!

We could spend the rest of the book learning Python, but let's return to theming instead.

Overview of theme package files

You will notice a beyondskins directory in parts/omelette that contains two files:

  • __init__.py
  • ploneday

The __init__.py file tells Python to treat this directory as a module, and that ploneday is another directory.

Plone packages typically do not make use of the top-level or mid-level namespaces, so let us look inside (the third-level module) beyondskins/ploneday/site2010 instead:

>>> Products.__path__


Here is an overview of (most of) these files and directories:

  • __init__.py: This file tells Python the directory is a module; see http://docs.python.org/tutorial/modules.html for more information.
  • __init.__pyc: This file contains compiled byte code; see http://docs.python.org/tutorial/modules.html for more information.
  • __init__.pyo: This file contains optimized and compiled byte code; see http://docs.python.org/tutorial/modules.html for more information.
  • browser/: This directory contains new-style customization code (that is, code that makes use of the Zope Component Architecture), such as browser views, portlets, viewlets, and resources like image, CSS, and JavaScript files. Visit: http://plone.org/documentation/kb/customization-for-developers/zope-3-browser-views for more information.
  • configure.zcml: This file contains ZCML code used to load components defined in your package. It is also responsible for loading other ZCML files within a package:

    $ ls -H -1 parts/omelette/beyondskins/ploneday/site2010





















  • locales/: This directory contains translations for multilingual sites. Visit http://plone.org/documentation/manual/developer-manual/internationalization-i18n-and-localization-l10n for more information.
  • profiles/: This directory contains GenericSetup (http://plone.org/documentation/kb/genericsetup) code typically in the default directory, to indicate the default profile. GenericSetup can be used to configure all manner of settings in Plone. If you are not familiar with it, try the following:
    • Navigate to Site Setup Zope Management Interface | portal_setup | Export|
    • Scroll to the bottom and click on Export all steps
  • You will get a compressed, archived file that contains many XML files containing various settings. You can add these files to the profiles/default/ directory of your add-on package, then edit them to customize the settings.
  • setuphandlers.py: While many settings can be configured using GenericSetup, some cannot. This file holds ad hoc Python code used to configure various settings that cannot be configured elsewhere (that is, using GenericSetup).
  • skins/: This directory contains Zope 2 File System Directory Views (FSDV) that contain Content Management Framework (CMF) skin layers that contain templates, images, CSS/JavaScript files, and Python scripts.
  • skins.zcml/: This file contains ZCML code that registers FSDVs used by the CMF to facilitate skin layers.


    <!-- File System Directory Views registration -->

    <!-- Note: This could also be done for all folders at once
    by replacing the previous lines with this one:
    <cmf:registerDirectory name="skins" directory="skins"
    recursive="True" />


  • tests.py: This file (or directory) typically contains unit tests (and doctests) for the package. See http://plone.org/documentation/kb/testing for more information.


In this article we have learned:

  • Installing themes with Buildout
  • Examining themes with Omelette and Python

You've been reading an excerpt of:

Plone 3.3 Site Administration

Explore Title