DIYPloneStyle: Creating a Custom Style for Plone 2.1 and 2.5
This tutorial will teach you how DIYPloneStyle can be used as a base for creating a custom style product for Plone 2.1 or Plone 2.5 that adds to a portal a new skin selection and makes use of the new stylesheet and javascript registries.
Introduction
Introducing DIYPloneStyle and the purpose of this tutorial.
Installation and basic example
Quick learning from the basic example included in DIYPloneStyle.
You can add to this folder the images that will override the ones shipped with Plone (mainly action and content type icons). It is better to keep them in a separate folder for having tidy folder listings in the 'portal_skins' tool. * **A custom base_properties.props file** From this file, you can learn how to replace the portal logo by another one, and how to simply change portal style properties.
This file is not used by the example, but is provided by the skeleton theme created by the "generator script":/documentation/tutorial/creating-custom-style/automated-setup for your convenience. note -- Customizing 'base_properties.props' is the easiest way to modify the style attributes of Plone UI elements, but it has its caveat as you will see "further in this tutorial":base-properties. * **A custom stylesheet (diystylesheet.css.dtml)** The most interesting thing about that stylesheet is probably that its name is not (and must not be) 'ploneCustom.css.dtml'. You will learn in a "further chapter":stylesheets of this tutorial how to register stylesheets with the new *portal_css* tool introduced in Plone 2.1 instead of using the old 'ploneCustom.css' implementation. Stylesheets and 'base_properties.props' are stored in the 'DIYPloneStyle/skins/diystyle_example_styles' folder. * **A set of empty stylesheets** Their names are 'public.css.dtml', 'base.css.dtml', 'generated.css.dtml', and 'portlets.css.dtml'. They are used to disable equivalent Plone stylesheets by overriding them with empty CSS files (see chapter about "skin layers":skin-layers). * **Some templates** As Alexander Limi states, it is ok to customize Plone templates as long as it is only for small structural changes. The templates that are customized in the example are kept in 'DIYPloneStyle/skins/diystyle_example_templates'.
Getting Started - The Manual Way
Preparing DIYPloneStyle for making it the skeleton of a new visual theme for Plone.
This file is where you will add your own CSS rules. 1 **Rename all the folders** which name starts with 'diystyle_base' in the 'skins/' directory to something that suits better your product name (2). 1 **In config.py,** change the name of your skin selection by modifying the 'name' value of the first entry in 'SKINSELECTIONS' (3). If your product won't provide more than one skin selection, you can remove the 'layers' key from that entry (make sure 'SKINSELECTIONS' match folder names in your skins directory).
Change 'DEFAULTSKIN' to make it use the name of your skin selection.
In the 'STYLESHEETS' declaration, replace 'diystylesheet.css' by the name you chose for that template, omitting the '.dtml' suffix. 1 **In Extensions/Install.py,** edit the relevant lines in the import declarations (see '# CHANGE' comments). 1 **In tests/testStyleInstallation.py,** replace all occurences of 'DIYPloneStyle' by the name of your product (see '# CHANGE' comment). 1 **Edit README.txt,** give it another description, remove the usage and credits paragraphs, and replace author names and email addresses.
If you plan to distribute your work, please leave a note stating that it is based on DIYPloneStyle. 1 **Clear HISTORY.txt** from its DIYPloneStyle related content. 1 **Remove the basic example** - **Remove all the files** which name starts with 'diystyle_example' in the 'skins/' directory. - **In config.py,** in the 'SKINSELECTIONS' declaration, remove the lines declaring the 'DIY Style Example' skin. 1 **Remove the bin/ folder** as the script it contains only works on a clean, left unmolested version of DIYPloneStyle. **That's it!**
Now you can test the initial state of your visual theme by restarting the Zope server and installing it from the *Site Setup > Add/Remove Products page* (as manager, in the Plone interface). Your Plone Site should now look like this:
**Now have fun with your new project!**
Troubleshooting --
This part of the tutorial is likely to be the one that will put you into
some trouble.See the "Troubleshooting":troubleshooting section of this tutorial if you feel that you are in a desperate situation.
(1) It is safer to work with a copy of the product so that it's easy to compare with the original version if you feel like in trouble. back
(2) Unless you configured it otherwise in the 'config.py' module, any folder located in the 'skins/' directory of your product will be registered as an *FSDirectoryView* with the portal skins tool. Because *FSDirectoryViews* must have a unique name/id in the skins tool, good practice is to include your product name into folder names to ensure these don't clash - particularly when using a name that might be commonly used. back
(3) In versions prior to 1.0.3, the name of the skin selection is setup using the 'SKINNAME' variable. back
Getting Started - The Automated Way
Using the built-in generator script for quick skeleton creation.
You learned from the "first part of this chapter":getting-started how to
manually setup DIYPloneStyle for making it a ready to go skin skeleton
product.
There is a much faster way to get a clean product that can become a new style
for Plone, by making use of the included generator script.
In the DIYPloneStyle product folder on the filesystem, there is a 'bin/'
directory where you will find a python script called 'generator.py'.
This script can be used for applying all the manual modifications that are
listed in the previous part of this chapter.
Download and Expand DIYPloneStyle
* Place the expanded DIYPloneStyle product folder in the 'Products/'
directory of your Zope instance.
* **Uninstall DIYPloneStyle** if you already installed it
(in Plone, as manager, go to *Site Setup > Add/Remove Products*).
Run the script
On Unix/Linux/OSX
From a bash shell (from the Terminal), use a command which should look like
this one::
/path_to_zope_instance_home_folder/Products/DIYPloneStyle/bin/generator.py --productname MyOwnPloneSkin
On Windows
* Choose *run* from the Windows *Start menu* and type 'cmd'. Press *OK*
* Run the script with a command which should look like this one::
python c:\instance_home_folder\Products\DIYPloneStyle\bin\generator.py --productname MyOwnPloneSkin
On Unix like systems, you can call the script from any directory.<br />
On Windows you can't: your current working directory must be outside the
product.
I've heard about permission problems on Windows when using the script from a
subversion checkout of DIYPloneStyle.<br />
If you need to work with the latest *svn trunk* version of the product under
Windows, take the time to remove all its '.svn' folders before running the
script.
Start Building
You now have a fresh Plone skin product in the 'Products/' directory of
your Zope instance.<br />
All you have to do when you want it to be installable in Plone is to restart
the Zope server.
Note --
If you want to learn more about the possible script arguments, you can either
see the script output when called without args (or with the '--help' option)
or read its fairly easy to understand code.
Organizing the skins layers
A bit of theory on the portal_skins tool mechanism.
The install function first creates a skin selection containing the layers of the skin it is based on, then adds the product specific layers to it. On the filesystem, the product specific layers are the folders that are located in the product 'skins/' directory (*). In practice, if your product is built for customizing a Plone site by adding a few stylesheets and replacing graphical UI elements (images like the logo and some icons), you won't need to have much more than one layer to add to your skin selection (**). But there are situations where it might be useful to have several layers, mainly for organizing skin elements into categories (images, customizations, stylesheets, etc). (*) Any folder located in the 'skins/' directory of your product will be registered as an FSDirectoryView with the portal *Skins Tool*, and then be added to your skin selection layers. Exceptions are folders which name starts with '.' or equals 'CVS' or '{arch}' (This is hardcoded in *Products.DIYPloneStyle.Extensions.utils.getSkinsFolderNames()*). (**) If DIYPloneStyle provides more than one skin layer (if its 'skins/' folder contains more than one folder), it's only for making easier the example removal part of the *Get Started* process.
Working with Base Properties
Editing base_properties.props for quick customization.
I am not yet aware of how and when this will be implemented, so check for further updates of this paragraph. You can find more information about the Plone pre-defined properties in the file 'CMFPlone/skins/plone_styles/ploneCustom.css'. You may need to use your own properties in addition to the ones that are pre-defined in Plone. Instead of adding new properties to 'base_properties.props', it is probably better practice to create a new '.props' file in your skin layer and to register a stylesheet that uses it (instead of the base_properties one - see in the original 'DIYPloneStyle/skins/diystyle/renameThisFile.css.dtml' DTML code).
Registering and customizing stylesheets
Best use of the Resource Registries.
As we saw in the "previous chapter":base-properties, we still have to use 'base_properties.props' for defining our basic graphical chart. But now that we can register stylesheets with the CSS tool, 'ploneCustom.css' is kept for backward compatibility only. Another limit of Plone without the ResourceRegistries was that there was no possibility to put a condition on whether a stylesheet should be loaded or not. Stylesheet registration in DIYPloneStyle is set up in 'config.py', in the 'STYLESHEETS' declaration. 'STYLESHEETS' is a tuple of python dictionaries, one dictionary for each stylesheet to register with the *portal_css* tool. If you need to put a condition on a stylesheet, you have too add to its dictionary an 'expression' key. It's value is a TAL expression that works the same way as for actions in the *portal_actions* tool. You can learn more about the stylesheet attributes (dictionary keys) from the 'STYLESHEETS' inline comments. Customizing existing stylesheets DIYPloneStyle can be useful not only for registering new stylesheets: you can also define in the 'config.py' how you want to customize resources that are already registered in the registries. In the 'STYLESHEETS' declaration, simply add a dictionary with the same 'id' than the one of the resource that you want to customize, and add a key to the dictionary for each resource property that you want to modify. It can be handy for instance for disabling some Plone default resources in order to start a project from absolute no-style scratch or to put specific conditions on them to define different styles for public and registered modes. **Note:** All customizations will be automatically reverted when uninstalling the product. Practical example A very common use case is to define a skin for public anonymous access, and keep a basic plone style for members access. One easy way to do so is to put a condition on the product specific stylesheet(s), and disable basic plone resources under the same condition. In the 'config.py' file of your product, declare your stylesheets like these ones (in 'STYLESHEETS'):: STYLESHEETS = ( {'id': 'diystylesheet.css', 'media': 'screen', 'rendering': 'import', 'expression': 'python: member is None'}, {'id': 'base.css', 'expression': 'python: member is not None'}, {'id': 'public.css', 'expression': 'python: member is not None'}, {'id': 'portlets.css', 'expression': 'python: member is not None'}, {'id': 'generated.css', 'expression': 'python: member is not None'}, )
Troubleshooting
Some solutions in case you encounter problems.
In Firefox, press shift while clicking the reload button. In IE, use the key combination <Ctrl-F5>.
Do not underestimate this possible issue, it covers at least **60% of the problems** that you may encounter with a skin product (based on DIYPloneStyle or not). Beware of any TTW customization -- Some of your product skin elements might have been customized from within the ZMI, and be overridden by their equivalent in the 'custom' skin layer. This one also covers a lot of the possible problems you might experience. Uninstall your product before renaming its elements -- If you forgot to do so before renaming stylesheets or javascripts, you can resolve conflicts from the *portal_css* and *portal_javascripts* tools in the ZMI.
If you didn't uninstall the product before renaming it or the skin selection, revert your changes on the filesystem, uninstall the product and rename the elements again. Check that the product is loaded in Zope -- From the ZMI, go to '/Control_Panel/Products/manage_main' and check that the product is listed and not marked as broken.
If it's not listed you should double check the product installation on the filesystem, making sure that the user who launches the Zope server has at least read access on it.
If it is marked as broken, you should check your error log and make sure that your business python code is valid (this should only happen if you added a broken Python class definition to your initial skeleton Plone style product). Make sure that the product is installable in Plone -- If your product is not listed or is marked as removed in *Site Setup > Add/Remove Products* or in the Quick Installer (*portal_quickinstaller* in the ZMI), it probably means that you have to debug the module 'Extensions/Install.py'. Use the provided testing framework -- DIYPloneStyle comes with basic unit tests.
Follow the links from the "Resources":resources chapter of this tutorial if you care about learning the Plone Unit Testing Framework. Use of the generator script Check that the script uses the right python interpreter -- Thank you Casper R. Nielsen for suggesting me to add this point.
With unix like systems, you can run the script by calling it directly, omitting the python command. If you get the error 'bad interpreter: No such file or directory' by calling the script that way, it's because the first line of the script refers to a file that does not exist.
To make it run without error, you can either:
- prefix the shell command by the python command
$ python generator.py --productname CustomSkin
or by the full path of the python interpreter. For instance:$ /usr/local/bin/python generator.py --productname CustomSkin
- edit the first line of the script to make it point to your python interpreter.
Traceback (most recent call last):
File "DIYPloneStyle/bin/generator.py", line 226, in ?
generateDirectoryCopy( path, path.replace('DIYPloneStyle', productname) )
File "DIYPloneStyle/bin/generator.py", line 182, in generateDirectoryCopy
os.mkdir(dstDirectory)
OSError: [Errno 13] Permission denied: '/Users/david/plone-instance/Products/CustomStyle/'
it is probably because you don't have write permissions on the folder
where DIYPloneStyle resides and where the new product will be created.
Get Further support
From the Plone community --
Before adding a comment to the manual, please post your question/issue on
the "plone-users":/contact#users mailing list or try to get some support
on the IRC
"#plone":irc://irc.freenode.net/plone channel.From the DIYPloneStyle product authors -- Feel free to contact DIYPloneStyle authors by sending them an email (email addresses appear in the product 'README.txt' file).
Resources
Related documentation, Zope/Plone products and CSS oriented developer tools.
To learn more about the registries' API, you can install "DocFinderTab":http://zope.org/Members/shh/DocFinderTab. This product is recommended anyway as soon as you start learning the Zope/Plone API. "Customizing Plone - the Plone 2.0 approach":http://plone.org/events/conferences/1/archive/customizingplone by Alex Limi -- An overview of Plone 2.0 layout structure and philosophy, and of what you can do with CSS.
(This document can be used as a good demo of the full-screen mode in Opera that uses the 'projection' CSS media ,which displays Plone page sections as projection slides). TTW Customization These links can be useful for a better understanding of the *Skins Tool* machinery and how things are organized with regard to Plone User Interface elements. The Plone Book by Andy McKay -- Chapter 7, about "Customizing the Look and Feel of Plone":http://docs.neuroinf.de/PloneBook/ch7.rst is a must-read for People who need to understand better the *Skins Tool* machinery. "Where is what?":../where-is-what by Jet Wilda and John DeStefano -- A reference on what templates and CSS control the UI elements and where to find them in the ZMI (updated for Plone 3.0). "Plone Skin Dump":http://quintagroup.com/services/plone-development/products/skin-dump -- A Plone product developped by Quinta Group, which "allows to create Plone product based on some ZMI located skin folder (eg "custom") from portal_skins. So you can easy create Plone product with skin based on folder with customized styles and page templates". Plone Skin Dump supports stylesheets registration since version 0.3.0. Filesystem Development The "How-to section":/documentation/how-to/ of plone.org -- There are many good resources from the section **User Interface: Styles and styling, CSS**.
In particular the one about "Creating a Custom Skin":/documentation/how-to/creating-custom-skins by Ben Calder. "Best Practices for Plone development":/documentation/tutorial/best-practices by Joel Burton -- It will give you good advice if you plan to develop filesystem python code based products. The following references may seem off topic as they are mainly about developing content types, but they are valuable for learning how to build Python products for Plone. "MySite":http://www.neuroinf.de/LabTools/MySite by Raphael Ritz -- This tutorial/product for Plone newbies (and less newbies) covers many aspects of the product development on the filesystem. "RichDocument":/documentation/tutorial/richdocument by Martin Aspeli -- Although this tutorial/product is more about creating a new type of content for Plone, It has a short section covering the "use of the ResourceRegistries":/documentation/tutorial/richdocument/resourceregistries The Plone Book by Andy McKay -- There is also a chapter about "Writing a Product in Python":http://docs.neuroinf.de/PloneBook/ch12.rst. DIYPloneStyle ships *Unit Tests Included*.
Even if most of the following references describe the Zope and Plone Unit Testing Framework, it's really easy to adapt them to any product *for* Plone. "PloneTestCase":/products/plonetestcase/ -- PloneTestCase is a thin layer on top of the "ZopeTestCase":http://www.zope.org/Members/shh/ZopeTestCase package. It has been developed to simplify testing of Plone-based applications and products. "How to write unit tests for Plone":/development/info/writing-unit-tests -- This document shows how easy it is to write unit tests and describes how to set up your environment to invoke them. "the ZopeTestCase Wiki":http://www.zope.org/Members/shh/ZopeTestCaseWiki/FrontPage -- A comprehensive documentation about the Zope Unit Tesing Framework. Other Plone Skins Products Most of the graphical designs for Plone that can be found are not yet making use of the Resource Registries, but adapting the code should be easy now that you read this tutorial ;-) The "Products section":/products of plone.org -- Is a central repository for Plone Add-ons. It has a section dedicated to "visual themes":/products/by-category/themes that can be used as a source of useful examples on how to apply new designs to a Plone site. "ploneskins.org":http://www.ploneskins.org/ -- Is another repository for Plone skins. CSS Design "official W3C CSS documentation":http://www.w3.org/Style/CSS/ -- The official Cascading Style Sheets documentation delivered by the Word Wide Web Consortium. "CSS Zen Garden: The Beauty in CSS Design":http://www.csszengarden.com/ -- A demonstration of what can be accomplished visually through CSS-based design. "A List Apart":http://www.alistapart.com/ -- A web magazine that "explores the design, development, and meaning of web content, with a special focus on techniques and benefits of designing with web standards". Famous book author web sites -- Some authors of books about CSS design like "Eric Meyer":http://meyerweb.com, "Jeffrey Zeldman":http://www.zeldman.com/, "Dan Cederholm":http://www.simplebits.com/ and "Owen Briggs":http://www.thenoodleincident.com have their own web site that are good places for finding documentation, examples and recipes. Mozilla/Firefox Tools and Extensions The following tools are your best friends when you need to inspect the CSS attributes of Plone page elements or find out what id or class you want to override in your stylesheets. "DOM Inspector":http://www.mozilla.org/projects/inspector/ -- This Mozilla tool can be used to inspect and edit the live DOM of any web document. "Web Developer":http://chrispederick.com/work/firefox/webdeveloper/ -- Adds a menu and a toolbar with various web developer tools. "Aardvark":http://www.karmatics.com/aardvark/ -- This extension displays on a Web page the attributes (like ID or class name) of a selected element. "EditCSS":http://addons.mozilla.org/extensions/moreinfo.php?id=179 -- Stylesheet modifier in the Sidebar. "ColorZilla":http://www.iosart.com/firefox/colorzilla/index.html -- Advanced Eyedropper, ColorPicker, Page Zoomer and other colorful goodies. It assists web developers and graphic designers with color related tasks - both basic and advanced. "View formatted source (format source extension)":https://addons.mozilla.org/en-US/firefox/addon/697 -- Displays formatted and color-coded source and optional CSS information for each element. You can see exactly which CSS rules match for an element. The rules are displayed including file name and line number. The topmost element is that with the highest priority. You can fold/unfold/hilite block elements (table, tr, td, div, span,...). Really cool feature: select a block level element of interest directly in the page and view it's source! To help you to quickly analyze the source code you can view images directly from the source and add comments to folded block elements. The code view is based on the rendered document, so you will also see dynamically (by Javascript) created and modified html elements! Works also with frames and selected text. "View Rendered Source Chart":https://addons.mozilla.org/en-US/firefox/addon/655 -- Creates a Colorful Chart of a Webpage's Rendered Source Code.
Displays Dynamically Generated HTML and Static HTML Together.
Removes JavaScript Code, Displays JavaScript Output.
Excellent as a Visual Aid in Learning Environments.
Translations
This tutorial in your language (?).
Chinese --
"Chinese translation":http://www.czug.org/plone/tutorial/diyplonestyle
Japanese --
"Japanese translation":http://nagosui.org:8080/Nagosui/plone-visual/DIYPloneStyle-nyusukese/creating-custom-style/
German --
"German translation":http://amantke.de/index.php?/content/view/37/23/
