Personal tools
You are here: Home Documentation Tutorials Using the Resource Registries to control CSS and Javascript
Support

Get Help

Join our chat rooms or support forums if you have more specific questions.

Plone Training
Learn how to design, build, and deploy a website in Plone through one of the numerous Plone training sessions around the world.
Find Plone training…
 
Document Actions

Using the Resource Registries to control CSS and Javascript

Note: Return to tutorial view.

Plone has two neat tools for managing Cascading Stylesheets and Javascript in a handy way. This tutorial explains some whys and hows and even has a minimal practical example of how it works.

Why do we even have these registries?

Why were the Resource Registries written, what do they do, and why are they useful?

The ResourceRegistries spring out of ( as most features in Plone ) frustrations with the state of the world before their existence: If you wanted to add a CSS style sheet or a Javascript library to your Plone site, beyond using the ploneCustom.css-file, you would have to override the header templates. This was painful from a maintenance point of view, and it also didn't allow it happening more than once. There was no way of Products supplying their own css files without massive conflicts if more than one Product attempted the same. Having several style sheets and Javascript files to make things more manageable on the filesystem was painful too.

With the existence of ResourceRegistries we were also able to split up Plone's CSS and Javascript into more manageable parts that can be turned on or off at the click of a button. We couldn't do this in earlier versions of Plone as splitting the style sheets would increase the number of separate http-requests needed to display a page incredibly.

The resource registries should:

  • Make it easier to work with and supply your own Cascading Style Sheets and Javascripts in Plone
  • Make it possible/easier to add conditions to your Cascading Style Sheets and Javascripts so they only apply when you want them to
  • Make it easy for Product authors to supply Cascading Style Sheets and Javascripts for their products without  getting conflicts with other products
  • Reduce the number of http-requests needed to display a Plone page in a browser
  • Pack Cascading Style Sheets and Javascripts to reduce the download sizes of files to users, and the bandwidth usage from serving a Plone site
  • Make it easy to change priorities amongst Cascading Style Sheets and Javascripts
  • Make it easy to disable all or parts of Plone's default Cascading Style Sheets and Javascripts

What are the registries?

The Resource Registries currently consist of two Plone tools living in the ZMI in the root of your Plone site. They have been part of the Plone bundle/installers since Plone 2.1.

They can be used with Plone 2.0.x as well. There is a special readme-file in the product for installation instructions for Plone 2.0.x

How do the registries work?

Each registry has an ordered list of resources, CSS or Javascript files, each with its own set of attributes. Entries in the registries will be linked automatically in Plone pages in the standard templates when the browser requests a page. The registries have been configured to have very sensible defaults — so for almost all use-cases (probably 90%+) it is merely the matter of adding the id of a resource you want to use.

NOTE: For experimentation, for example when reading this document, make sure to check the "debug/development mode" checkbox on the top of the configuration panel. ( read more about why in part 4 )


Overview and example walkthrough

Basic operations of the CSS-and Javascript-registries – and a truly minimal example of how to use them in real life

The registries are two tool that live only in the ZMI. They have no interface in the Plone portal UI itself.
they are called portal_css and portal_javascript. You can easily find them when browsing the ZMI of your Plone site.

css registry in the ZMI

Once selected, the css-registry ( the one we use for this example. The javascript one is almost exactly the same) will present an interface displaying all the registered resources ( in the case of the CSS-registry, the resources are CSS-files)

CSS-registry main UIEach entry in the registries has an id that references a resource that can be found in the current Plone acquisition context. This normally means that the corresponding object should live in portal_skins like custom templates and most customisation-stuff do in Plone. Whether it exists somewhere like portal_skins/custom or in your own filesystem product makes no difference. Technically it could be a tool or a utility or anything that has a name and is avaialable, but most commonly it will be a File object ( for static CSS and JS) or a DTML Method (for dynamic variable replacement). The Resource Registries makes no difference as to what the object is, as long as it can be found and called, rendered or printed as a string.

So to use one of the registries, you have to

  1. Have a resource (for example a File) in the current context ( for example portal_skins/custom) with some CSS or Javascript in it
  2. Make an entry in the corresponding registry (for example portal_css) with the id of the resource.

Example walkthrough of adding a CSS resource

As a simple example of how the most basic functionality, we'll add and register a minimal stylesheet that adds to the background of your Plone a terrible red color.
  1. in your ZMI, navigate to portal_skins/custom
  2. from the add-item menu, select File
  3. Give the new File an id of 'css-demo.css'
  4. paste the following content into the file:
    body{ background-color : red }

    …and save it

  5. Now you have your resource. Now we just have to link it from the Plone site to make the style apply:
    in your ZMI, navigate to the CSS-Registries: portal_css

  6. scroll to the bottom of the form, where there is a form for adding a stylesheet

  7. in the id field, enter 'css-demo.css'  (Leave the other values as they are by default for now)

Voila! – view your Plone site and you'll easily notice its (admittedly quite horrifying) shiny red background color!

Conditions, merging, caching and debugging

some more details on how the ResourceRegistries function

Conditions

When a user agent (i.e a Browser) makes a page request, all the resources registered in the registry are evaluated against their condition field. If the condition is true, the resource is served to the browser. If the condition evaluates to false, the resource is not served.

This gives you the ability to conditionally serve different style sheets or scripts based on logic like whether the user is logged in, whether you are in the "Human Resources"-section of your intranet of if the content-type is a news-item.

Read more in my small and general how-to on CMF Expressions

Merging

Whenever you click the save-button in a registry, a new set of css or javascript files are created. The registry will try to assemble the different resources into bigger lumps/files to server to the browser. This is to reduce the number of http-requests necessary and can improve performance considerably.

The rules for merging resources

  1. The registry will only try to merge resources that are adjacent in the list. Otherwise you would risk that the order of operations in the browser would be affected (order of code in javascript and the order of the cascade in CSS. This would possibly affect rendering or execution in the browser in a negative way, and is therefore not available ).
  2. Two adjacent resources are only merged if their condition is exactly the same (more about conditions in the next chapter)
  3. Two adjacent resources are not merged if they don't have the 'allow merging' checkbox checked

The magically assembled 'Files' are assigned a new random number as their name. So you'll find entries like <link rel="stylesheet" href="plone2341.css" /> in your html source.
You can inspect how the resources will be merged if you click the second tab in the registry; "composition". It will present you with a list of 'magic' files, like 'plone2341.css', and nested within them the component resources they are constructed from. You can click each entry to inspect what it will look like when served.

The CSS-composition UI


The css-registry composition UI

Each merged resource will have a small snippet in the source identifying its origin so that you can get hold of the full unmodified source if you need.
The comment stuff usually looks like the following.
/* ----- base.css ----- */
@media screen {
/* http://yourhost/plone/portal_css/base.css?original=1 */
/* */

Caching and HTTP

The merged resources are automatically served with HTTP-headers optimized for being cached a long time. Since the auto-generated number is being changed every time you save the registry settings, the browser will request the new 'files' and not use its old cached values anyway. The scheme is actually rather clever.

The potential problem with the caching scheme is that the registry doesn't know if you change the files in the skins directories unless you touch the "save" button in the registry. This  is only an issue while you are working on your CSS (or Javascripts) to get them right, but can cause massive confusion if you make changes and only see cached styles/scripts in the browser. To avoid this issue, we have added a handy "debug and development" mode to the registries.

Debug and development mode

To enable the debug and development mode, check the corresponding checkbox in the registry configuration page and click "save".
Enabling the debug and development mode
  • Disables merging of resources (great for finding bugs and specific declarations with the inspectors and development tools like Firebug)
  • Sets HTTP-headers for not caching so that you get a fresh copy every time
  • Disables compression

These settings affect performance in an adverse way, so make sure to disable the debug mode when your Plone goes live.

Resource parameters

The parameters for a registry entry in the CSS (and Javascript) registry.

When working with CSS in the CSS Registry, each stylesheet has some parameters that can be tweaked.

id
The Zope id of the stylesheet to be used.
expression
A CMF expression to be evaluated to check if the stylesheet should be included in output or not.
media
The media for which the stylesheet should apply, normally empty or 'all'. other possible values are 'screen', 'print' etc. Read more about the media settings of CSS at w3.org
rel
Link relation. defaults to 'stylesheet', and should almost always stay that way. For designating alternative stylesheets. This is used for the toggle between large, medium and small fonts in default Plone. Don't change this one unless you know what you are doing.
title
the title of an alternate stylesheet.
rendering
How the stylesheet is linked from the html page. This is an advanced setting. Leave it set to the default 'import' unless you know the effects of different ways of rendering and linking stylesheets
import
the default. normal css import
link
works better for old browsers and is needed for alternate stylesheets
inline
render the stylesheet inline instead of linking it externally. Shouldn't be used at all! It isn't possible to create sites which validate if you do.
For more information see: http://developer.mozilla.org/en/docs/Properly_Using_CSS_and_JavaScript_in_XHTML_Documents
compression
Whether and how much the resource should be compressed
none
the original content will not be changed
safe
the content will be compressed in a way which should be safe for any workarounds for browser bugs. Conditional code for Internet Explorer is preserved since ResourceRegistries 1.2.3 and 1.3.1.

full
the content will be compressed with some additional rules.For css all comments and most newlines are removed, this may break special browser hacks, so use with care. For javascript this encodes variables with special prefixes according to the rules described here (Special Characters):
http://dean.edwards.name/packer/usage/ The source code needs to be written according to those rules, otherwise it's more than likely that it will break.
safe-encode
- only available for javascript
- 'full-encode' - only available for javascript. Additionally encodes keywords. This heavily compresses the javascript, but it needs to be decoded on the fly in the browser on each load. Depending on the size of the scripts this could lead to timeouts in Firefox. Use with special care!

Using Resource Registries programmatically

Instructions for controlling the CSS and Javascript registries programmatically instead of through the user-interface. This is especially relevant for product authors or for crating file-system-based site-configuration products.

The by far most common need for using the ResourceRegistries programmatically is to register resources with the installation of products.
A very common use-case is 'site-configuration'-products and 'themes' that usually supply at least one CSS-file. (The equivalent of what we used ploneCustom.css for back in 2004). Other common uses are supplying custom javascript files, either with site-configurations or as client-side supplemements to custom products.

There are currently two main approaches to supplying registry configuration through filesystem code

  1. Python API calls, typically called from a product's Install.py module. Very flexible, but somewhat cumbersome and opaque to non-programmers. The old-style way of doing it. Has access to more (rarely needed) functionality than (2)
  2. GenericSetup XML configuration ( the new shiny way of supplying Plone configuration settings )

Configuring the ResourceRegistries from the Python APIs

ResourceRegistries/Interfaces/registires.py has the authorative list, but here are some examples. These examples are for the CSS-registry (chosen because it is more commonly used, and also more often used by non-programmers)

To work with the tool, you must first get your hands on the tool itself…
from Products.CMFCore.utils import getToolByName
CSSRegistry = getToolByName(self, 'portal_css')
To register a new resource ( the same as using the add-form in the UI ) , you can simply do
CSSRegistry.registerStylesheet(self, id)
…and stick with the defaults. They are usually just what you need anyway.

if you feel you need more detailed control, there are many options you can supply if you need
CSSRegistry.registerStylesheet(self, id, expression='', media='', rel='stylesheet',title='',
rendering='import',  enabled=1,
cookable=True, compression='safe', cacheable=True)
Using python calls for installation stuff is, however, rapidly becoming obsolete. GenericSetup is the new way, and luckily the ResourceRegistries also supports this scheme.

Configuring the ResourceRegistries with GenericSetup XML

Note that this approach is instead of the Python API approach listed above. You don't need both.
If you have not worked with GenericSetup yet, there is a nice tutorial from Rob Miller right here on plone.org. If you do know the basic of it, all you have to do is add a file called cssregistry.xml to your profile and let it contain something like this
<?xml version="1.0"?>
<object name="portal_css" meta_type="Stylesheets Registry">
<stylesheet title="" cacheable="True" compression="safe" cookable="True"
    enabled="1" expression="" id="css-test.css" media="screen"
    rel="stylesheet" rendering="import"/>
</object>
As you can see, the parameters are the same as through Python or through the user-interface-forms.

For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by