Soon after you install and run Plone for the first time, you will probably want to
change the appearance. The effort needed to do so varies, and depends largely on your
goals. If you are not picky, adding a new theme to Plone can be as simple as adding a
package to your buildout.cfg
file, running Buildout, and restarting
Plone.
However, if you want a high quality, unique, and a professional-looking theme for your site, it could take several days, weeks, or even months to achieve the desired result.
In this chapter, we will cover the spectrum from easy and small changes with a high impact to more complex changes that require more effort. However, keep in mind that this is not a comprehensive coverage, help is just enough to rather a site administrator gain speed quickly. If you want to learn theming in depth, see the book "Plone 3 Theming", Veda Williams, Packt Publishing.
In this chapter, you will learn:
Installing themes with Buildout
Examining themes with Omelette and Python
Overview of theme package files
Creating a theme package with ZopeSkel
Examining themes in the ZMI
Making changes through the Web
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.
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):
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.
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:
[buildout] extends = 02-site-basics-blog.cfg [instance] 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.
Refer to Chapter 2, Site Basics, for a detailed explanation of why this is necessary.
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.
$ bin/instance fg
Browse to
http://localhost:8080/Plone
. Now, click on
Site Setup | Add/Remove
Products and you should see:
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:
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 http://127.0.0.1:8080/Plone
in
your browser (that is. by using the IP address instead of the hostname). You can
also load either of these URLs (http://127.0.0.1:8080/Plone 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).
To display the blog entry we created in Chapter 2 to the public, we have transitioned the other objects in the site root to the private state.
If you are unfamiliar with how to transition objects from the public state to the private state, please see Chapter 9 of "Practical Plone 3", Veda Williams, Packt Publishing.
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.
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:
[buildout] extends = 03-appearance-wpd2010.cfg parts += omelette [omelette] recipe = collective.recipe.omelette eggs = ${instance:eggs} packages = ${zope2:location}/lib/python
In this configuration file, we extend the sections and parameters in
03-appearance-wpd2010.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:
parts = zope2 instance plonesite omelette
(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:
$ bin/buildout -c 03-appearance-omelette.cfg
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. /Users/aclark/Developer/plone-site-admin/buildout/parts/zope2/lib/python/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 __import__(arguments[0]) Retrieved the admin user A Plone Site already exists and will not be replaced Installing omelette.
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:
$ ls -1 parts/omelette Products/ archetypes/ beyondskins/ borg/ collective/ easy_install.py@ elementtree@ feedparser.py@ five/ kss/ markdown.py@ mdx_footnotes.py@ mdx_rss.py@ openid@ pkg_resources.py@ plone/ setuptools@ simplejson@ site.py@ webcouturier/ wicked/ z3c/ zc/
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:
[buildout] extends = 03-appearance-omelette.cfg parts += zopepy [zopepy] recipe = zc.recipe.egg eggs = ${instance:eggs} interpreter = zopepy extra-paths = ${zope2:location}/lib/python scripts = zopepy
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:
$ bin/buildout -c 03-appearance-zopepy.cfg
You should see:
$ bin/buildout -c 03-appearance-zopepy.cfg Uninstalling plonesite. Updating zope2. Updating fake eggs Updating instance. Installing plonesite. /Users/aclark/Developer/plone-site-admin/buildout/parts/zope2/lib/python/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 __import__(arguments[0]) 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/buildout/bin/zopepy'.
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/zopepy >>> import beyondskins >>>
Python will try to evaluate any statement you input. For example, type beyondskins and hit Enter:
>>> beyondskins <module 'beyondskins' from '/Users/aclark/Developer/plone-site-admin/buildout/eggs/beyondskins.ploneday.site2010-1.0.3-py2.4.egg/beyondskins/__init__.pyc'>
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() Traceback (most recent call last): File "<console>", line 1, in ? TypeError: 'module' object is not callable
Python will now tell you that module objects are not callable. You can use the
built-in dir
function to view the attributes of the
beyondskins module:
>>> dir(beyondskins) ['__builtins__', '__doc__', '__file__', '__name__', '__path__', 'ploneday']
Now, Python will tell you its attributes. You can inquire about a specific
attribute such as __path__:
>>> beyondskins.__path__ ['/Users/aclark/Developer/plone-site-admin/buildout/eggs/beyondskins.ploneday.site2010-1.0.3-py2.4.egg/beyondskins'] >>>
Python will return its value. Just for fun, you can inquire about any attribute of any module:
>>> Products.__path__ ['/Users/aclark/Developer/plone-site-admin/buildout/eggs/Plone-3.3.5-py2.4.egg/Products', …
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.
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:
$ ls -H -1 parts/omelette/beyondskins/ploneday/site2010 README.txt __init__.py __init__.pyc __init__.pyo browser/ configure.zcml doc/ locales/ profiles/ profiles.zcml setuphandlers.py setuphandlers.pyc setuphandlers.pyo skins/ skins.zcml tests.py tests.pyc tests.pyo updateTranslations.sh version.txt
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:
<include package=".browser" /> <include file="skins.zcml" /> <include file="profiles.zcml" />
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). For more information about
setuphandlers.py
, see Chapter 6 of "Professional
Plone Development", Martin Aspeli, Packt Publishing.
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.
<configure xmlns="http://namespaces.zope.org/zope" xmlns:cmf="http://namespaces.zope.org/cmf" i18n_domain="beyondskins.ploneday.site2010"> <!-- File System Directory Views registration --> <cmf:registerDirectory name="beyondskins_ploneday_site2010_images"/> <cmf:registerDirectory name="beyondskins_ploneday_site2010_templates"/> <cmf:registerDirectory name="beyondskins_ploneday_site2010_styles"/> <!-- 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" /> --> </configure>
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.
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-the-filesystem, or Chapter 4 of "Plone 3 Theming", Veda Williams, Packt Publishing.
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.
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)
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).
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
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
$ ../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.
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: A Plone PAS AnonymousUserFactory Plugin 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 is needed (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-plone-logo/).
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.
Now that we have seen in part how themes work, let us take a closer look at their representation in Zope Object Database (ZODB).
Browse to
http://localhost:8080/Plone
. Click on Site
Setup | Zope Management Interface
and you should see:
This is a Through the Web (TTW) representation of all the objects in the database at the Plone site level (the application root is one level above).
The most frequently used theme-related objects here are:
portal_css
portal_javascripts
portal_skins
portal_view_customizations
Of these, portal_css
and portal_javascripts
are most often used to enable their respective debug modes, wherein the CSS and
JavaScript files are not compiled into a single file (not to be confused with Zope
2's debug mode which detects filesystem changes in real time when
enabled).
Take a look at your site with Firebug, in particular the style tab.
You should see:
Now enable debug mode in portal_javascripts
and look again. You
should see:
When portal_css
debug mode is enabled, we can see (or by
viewing the HTML source) that the CSS files are loaded individually in
Firebug.
The same applies to portal_javascripts
debug mode.
This can be absolutely invaluable when trying to correlate various visual elements with their respective sources.
In addition to debug mode, you can also add CSS/JavaScript files to their respective registries through the Web, which brings us to the next topic.
Let us continue our ZMI walkthrough by examining both
portal_skins
and portal_view_customizations
.
Browse to http://localhost:8080/Plone
. Click on Site Setup | Zope
Management Interface |
portal_skins.
You should see:
If you scroll down and click on my_theme_custom_images you will find the image you added earlier:
If you wanted to upload a new image, you could click the Customize button and upload it, but keep in mind that change will only exist in the database.
Assuming you want to keep the my.theme
package up-to-date
(in a software repository for example), you may prefer to customize the image on
the filesystem (and resist the temptation to customize it through the
Web).
If you do customize through the Web, consider the changes only temporary or volatile.
Next up is portal_view_customizations
where we will explore
yet another way to customize the logo.
Browse to http://localhost:8080/Plone
. Click on Site Setup | Zope
Management Interface |
portal_view_customizations |
zope.interface.interface |
plone.logo.
You should see:
If you wanted to, you could click the Customize button and change the image tag code:
Since we used the same file (logo.jpg), the site will look exactly the same.
But now you can upload a new image and change the code as you see fit. To
demonstrate this, let us now browse to
http://localhost:8080/Plone
and click on
Site Setup | Zope Management
Interface | portal_skins
| custom and add an image:
You can use any image you like, but we will use
Vlogo250.gif
from the Zope logo pack: http://www.zope.com/about_us/legal/low_res.zip.
Now return to http://localhost:8080/Plone
and click
on Site Setup |
Zope Management Interface |
portal_view_customizations |
zope.interface.interface |
plone.logo and change the filename to
Vlogo250.gif:
<a metal:define-macro="portal_logo" id="portal-logo" accesskey="1" tal:attributes="href view/navigation_root_url" i18n:domain="plone"> <tal:comment replace="nothing"> <img src="logo.jpg" alt="" tal:replace="structure view/logo_tag" /> </tal:comment> <img src="Vlogo250.gif" /> </a>
You should see:
That's it for this chapter. We have just demonstrated several ways to customize Plone's appearance with (hopefully) simple examples to convey the pros and cons of each method.
You have learned:
How to browse for themes on plone.org and install them with Buildout
How to use Omelette and Python to examine theme package contents
About theme package contents
How to create a theme package, and perform a simple customization
How to find your way around the ZMI
How to customize themes through the Web
See you in Chapter 4, where we will discuss site administration, including user and group management with LDAP.
18.119.142.232