Your message has been sent.
This article has been saved to your account.
Go to my account
This article has been emailed to your Kindle.
Send this article
Complete the form below to send this article, Creating a theme package with ZopeSkel, to a friend (or to yourself). We will never share your details (or your friend's) with anyone. For more information, read our Privacy Policy.
Plone is a powerful web application used mainly for website content management and comprised of many different, but related Python packages.
In the previous article we have learned how to install themes with Buildout and examine themes with Omelette and Python. Remember, we will not cover theme creation in depth; this is only a sample for site administrators (who may or may not be required to develop themes, in addition to managing their site).
In this article by Alex Clark, author of Plone 3.3 Site Administration , we will learn how to create a theme using the ZopeSkel tool to generate some of the boilerplate code.
(Read more interesting articles on Plone here.)
Creating a theme package with ZopeSkel
Now that we have examined someone else's theme, let us try creating our own.
Remember, we will not cover theme creation in depth; this is only a sample for site administrators (who may or may not be required to develop themes, in addition to managing their site).
For more information about creating themes, Visit: http://plone.org/documentation/kb/how-to-create-a-plone-3-theme-product-on-thefilesystem.
To create a theme, we will use the ZopeSkel tool (http://pypi.python.org/pypi/ZopeSkel) to generate some of the boilerplate code. ZopeSkel uses PasteScript (http://pypi.python.org/pypi/PasteScript) to facilitate package generation using a set of templates.
Other options include:
- Write everything by hand from memory
- Copy the contents of another theme package
- Use another tool such as ArchGenXML to generate boilerplate code (http://plone.org/products/archgenxml)
Adding ZopeSkel to a buildout
Now let's add ZopeSkel to our buildout.
In 03-appearance-zopeskel.cfg, we have this:
[buildout]
extends = 03-appearance-zopepy.cfg
parts +=
zopeskel
[zopeskel]
recipe = zc.recipe.egg
dependent-scripts = true
We extend the previous working configuration file, and add a new section called zopeskel.
This section uses the zc.recipe.egg recipe (http://pypi.python.org/pypi/zc.recipe.egg) to download ZopeSkel from the Python Package Index (zc.recipe.egg will search the Python Package Index for packages that match the section name zopeskel).
We set dependent-scripts to true, to tell Buildout to generate Python scripts for ZopeSkel's dependencies such as PasteScript, which includes the paster script.
Now stop Plone (with Ctrl + C or Ctrl + Z/Enter) and run Buildout:
$ bin/buildout -c 03-appearance-zopeskel.cfg
You should see:
$ bin/buildout -c 03-appearance-zopeskel.cfg
Uninstalling plonesite.
Updating zope2.
Updating fake eggs
Updating instance.
Installing plonesite.
…
Updating zopepy.
Installing zopeskel.
Getting distribution for 'zopeskel'.
Got ZopeSkel 2.16.
Getting distribution for 'Cheetah>1.0,<=2.2.1'.
…
Got Cheetah 2.2.1.
Getting distribution for 'PasteScript'.
Got PasteScript 1.7.3.
Getting distribution for 'PasteDeploy'.
…
Got PasteDeploy 1.3.3.
Getting distribution for 'Paste>=1.3'.
…
Got Paste 1.7.3.1.
Generated script '/Users/aclark/Developer/plone-site-admin/
buildout/bin/
zopeskel'.
Generated script '/Users/aclark/Developer/plone-site-admin/
buildout/bin/
paster'.
Generated script '/Users/aclark/Developer/plone-site-admin/
buildout/bin/
easy_install'.
Generated script '/Users/aclark/Developer/plone-site-admin/
buildout/bin/
easy_install-2.4'.
You will notice that in addition to bin/zopeskel, Buildout also installed the "dependent scripts" bin/paster and bin/easy_install (the latter of which we do not really need in this case).
Running ZopeSkel
Now try running ZopeSkel with the command:
$ bin/zopeskel
You should see:
Usage:
zopeskel <template> <output-name> [var1=value] ... [varN=value]
zopeskel --help Full help
zopeskel --list List template verbosely, with details
zopeskel --make-config-file Output .zopeskel prefs file
...
This tells us we need to pick a template and output-name.
ZopeSkel goes on to list the available templates. They are:
|
archetype: |
A Plone project that uses Archetypes content types |
|
kss_plugin: |
A project for a KSS plugin |
|
plone: |
A project for Plone products |
|
plone2_theme: |
A theme for Plone 2.1 |
|
plone3_portlet: |
A Plone 3 portlet |
|
plone_app: |
A project for Plone products with a nested namespace |
|
plone_pas: |
A project for a Plone PAS plugin |
|
plone2.5_theme: |
A theme for Plone 2.5 |
|
plone3_theme: |
A theme for Plone 3 |
|
plone2.5_buildout: |
A buildout for Plone 2.5 projects |
|
plone3_buildout: |
A buildout for Plone 3 installation |
|
plone_hosting: Plone hosting: |
buildout with ZEO and Plone |
|
recipe: |
A recipe project for zc.buildout |
|
silva_buildout: |
A buildout for Silva projects |
|
basic_namespace: |
A basic Python project with a namespace package |
|
nested_namespace: |
A basic Python project with a nested |
|
basic_zope: |
A Zope project |
(Read more interesting articles on Plone here.)
In our case, we will choose plone3_theme.
The output-name is the name of the package we want to create for example, my.theme.
Since we are creating a new package, let us change directories to the src directory and run ZopeSkel from there, like this:
$ cd src
$ ../bin/zopeskel plone3_theme my.theme
You should see:
$ ../bin/zopeskel plone3_theme my.theme
plone3_theme: A theme for Plone 3
This creates a project for a theme for Plone 3.
…
This will be followed by a series of questions, which you can answer based on these suggestions:
- Mode: Easy: This mode asks the least number of questions it needs to do its job.
- Skin name: My Theme: This name will show up in various places, including Site Setup Add/Remove Products|.
- Empty styles: False: This means we want our theme to look like the Plone Default theme. If you answer True, you will get an unstyled theme instead.
- Include documentation: True: This means our code will be generated with helpful comments included inline.
- Version: 1.0: This means our theme is ready for production use! Feel free to adjust this value if you like.
- Description: An installable theme for Plone 3: You can change this to whatever you like.
Running Paster
Next, when ZopeSkel completes, it tells us about the additional commands we can run to generate more boilerplate code.
We do not need to do it now, but if you are curious, try this:
$ cd my.theme
$ ../../bin/paster addcontent --list-all
You should see the following templates available (to generate more boilerplate code):
|
anonymous_user_factory_plugin: Plugin |
A Plone PAS AnonymousUserFactory |
|
atschema: |
A handy AT schema builder |
|
authentication_plugin: |
A Plone PAS Authentication Plugin |
|
challenge_plugin: |
A Plone PAS Challenge Plugin |
|
contenttype: |
A content type skeleton |
|
credentials_reset_plugin: |
A Plone PAS CredentialsReset Plugin |
|
extraction_plugin: |
A Plone PAS Extraction Plugin |
|
form: |
A form skeleton |
|
formfield: |
Schema field for a form |
|
group_enumeration_plugin: |
A Plone PAS GroupEnumeration Plugin |
|
groups_plugin: |
A Plone PAS Groups Plugin |
|
i18nlocale: |
An i18n locale directory structure |
|
portlet: |
A Plone 3 portlet |
|
properties_plugin: |
A Plone PAS Properties Plugin |
|
role_assigner_plugin: |
A Plone PAS RoleAssigner Plugin |
|
role_enumeration_plugin: |
A Plone PAS RoleEnumeration Plugin |
|
roles_plugin: |
A Plone PAS Roles Plugin |
|
update_plugin: |
A Plone PAS Update Plugin |
|
user_adder_plugin: |
A Plone PAS UserAdder Plugin |
|
user_enumeration_plugin: |
A Plone PAS UserEnumeration Plugin |
|
user_factory_plugin: |
A Plone PAS UserFactory Plugin |
|
validation_plugin: |
A Plone PAS Validation Plugin |
|
view: |
A browser view skeleton |
|
zcmlmeta: |
A ZCML meta directive skeleton |
Some of these which apply to themes are:
- i18nlocale
- portlet
- view
To add a portlet (little boxes on the left and right side of your site) to your theme,try this:
$ ../../bin/paster addcontent portlet
We could go on, but let's come back to basics now.
We now have a new theme package, but we do not have a new theme package in our buildout or in Plone. Let us now add our package to the buildout and to Plone.
The easiest way to do this is to tell Buildout we are developing a new package, by setting the value of the develop parameter in the buildout section to our package name (and relative filesystem path, in this case src/my.theme).
In addition to making Plone aware of this package, we must list it in the eggs parameter of the instance section.
In 03-appearance-develop.cfg, we have:
[buildout]
extends = 03-appearance-zopeskel.cfg
develop = src/my.theme
[instance]
eggs += my.theme
Now stop Plone (with Ctrl + C or Ctrl + Z/Enter) and run Buildout:
$ bin/buildout -c 03-appearance-develop.cfg
You should see:
$ bin/buildout -c 03-appearance-develop.cfg
Develop: '/Users/aclark/Developer/plone-site-admin/buildout/src/my.theme'
Uninstalling plonesite.
Updating zope2.
Updating fake eggs
Updating instance.
Installing plonesite.
…
The first line indicates that Buildout has recognized our new package. You may encounter an error during the Buildout run, when the collective.recipe.plonesite recipe tries to start Plone and add a Plone site. Ignore that for now. In fact when Buildout finishes and you restart Zope, you may see an (obnoxiously long) error like this:
$ bin/instance fg
/Users/aclark/Developer/plone-site-admin/buildout/parts/instance/bin/
runzope -X debug-mode=on
2010-05-02 11:38:08 INFO ZServer HTTP server started at Sun May 2
11:38:08 2010
…
OSError: [Errno 2] No such file or directory: '/Users/aclark/
Developer/plone-site-admin/buildout/my.theme/my/theme/locales'
But this error is good; it means we have succeeded in adding our package to Buildout and Plone.
To fix this error (if you get it), create a locales directory where Plone says one isneeded (ZopeSkel forgot to do this for us; a future release that is a release newer than ZopeSkel 2.16 should address the problem.):
$ mkdir src/my.theme/my/theme/locales
Now start Plone and you should see:
$ bin/instance fg
/Users/aclark/Developer/plone-site-admin/buildout/parts/instance/bin/
runzope -X debug-mode=on
2010-05-02 11:44:28 INFO ZServer HTTP server started at Sun May 2
11:44:28 2010
Hostname: 0.0.0.0
Port: 8080
…
2010-05-02 11:44:40 INFO Application New disk product detected,
determining if we need to fix up any ZClasses.
2010-05-02 11:44:40 INFO Zope Ready to handle requests
The second to last line indicates that Zope 2 has found our package!
Next, browse to http://localhost:8080/Plone. Now, click on Site Setup Add/Remove Products |and look for our package in the Quick Installer:

Check the box next to My Theme 1.0 and click Install.
You will notice the beyondskins.ploneday.site2010 theme has disappeared, and the Plone Default theme has returned (because My Theme 1.0 is based on Plone Default).
Now that our theme is installed, we can try to make a simple customization, like changing the logo.
To do that, we are going to copy a file with the same name as the default logo to our custom images directory: src/my/theme/skins/my_theme_custom_images.
But how do we know the logo image filename? One easy way to find it is to use the Firefox web browser with the Firebug add-on installed (http://getfirebug.com/):

The next step is to add a file of the same name to the custom images folder in our theme package.
You can use any image, but we will use plone-logo-128-white-bg.png from the Plone logo pack on plone.org (http://plone.org/foundation/logo/the-plonelogo/).
For adding the file just mentioned:
$ cp ~/Desktop/plone-logo-128-white-bg.png my.theme/my/theme/skins/my_
theme_custom_images/logo.jpg
Now without restarting Plone (assuming you are running it in the foreground with bin/instance fg), reload the front page and you should see:

This is a simple example of customizing Plone with a filesystem theme package. We can customize many aspects of Plone's appearance using this technique.
Why did this work?
You may wonder why we copied plone-logo-128-white-bg.png to logo.jpg. The short answer is because it works, and the file extension does not matter.
The medium length answer is that we have registered a new filesystem directory view and it is higher in the skin resolution order than Plone's filesystem directory view. Both contain an object called logo.jpg, but ours is discovered first.
The long answer is that there is a feature in Zope 2 called Acquisition that makes this customization possible (http://docs.zope.org/zope2/zope2book/Acquisition.html). In addition to the (core) Acquisition feature, there is a powerful add-on called the Content Management Framework (CMF) that Plone uses extensively. Plone registers a filesystem directory view and adds resources to it; then we customize a resource by ensuring it is acquired before Plone's resource is acquired.
Summary
In this article we have learned how to create a theme using the ZopeSkel tool to generate some of the boilerplate code.
If you have read this article you may be interested to view:
-
Security in Plone Sites [article]
-
Through the Web Theming using Python [article]
About the Author :
Alex Clark
Alex Clark is a Plone Consultant from Bethesda, MD, USA. He runs a thriving Plone consultancy along with his wife, Amy Clark. Together, they service a wide variety of government, corporate, and non-profit organizations in the greater Washington, D.C. area, and worldwide. For more information, please see http://aclark.net.This is his first book and he hopes that people enjoy the result and get inspired to use Plone.
Books From Packt
|
|



Post new comment