Attention

This document was written for an old version of Plone, Plone 3, and was last updated 930 days ago.

To learn how to upgrade to the current version of Plone, read the upgrade manual.

Writing rules

by Denys Mishunov last modified Nov 04, 2009 08:21 AM
How to compose and use actual rules when you're working with rules.xml

In your rules.xml add:

<replace content='/html/head/title' theme='/html/head/title' />

<drop theme="/html/head/style" if-content="/html/head/style"/>
<drop theme="/html/head/script" if-content="/html/head/script"/>    
<drop theme="/html/head/link" if-content="/html/head/link"/>

<append  content="/html/head/base" theme="/html/head" />
<append  content="/html/head/meta" theme="/html/head" />
<append  content='/html/head/style' theme='/html/head' />
<append  content='/html/head/script' theme='/html/head' />     
<append  content="/html/head/link" theme="/html/head" />

The first rule replaces <title /> in our static theme with the real title from Plone.

The second set of rules removes <style/>, <link/>, <script/> elements from our theme’s <head/> should Plone provide such elements (note the if-content in those <drop/> rules).

The third set of rules makes sure that we have all necessary bits from Plone’s <head/>.

Now the images. The reason why images are not rendered is because our style sheets are still trying to get the images from the ../images folder. The best way to make images render in our Plone theme is to use the “find & replace” function in our style sheets and replace relative paths for the images with just their IDs so that Plone searches for the images from site’s root.

After doing this your Plone site should look the same as your static index.html.

Now we can actually map content from Plone to our theme.

First, let’s add some useful stuff to our <body />

<prepend theme="/html/body" content="/html/body/@class" />
<prepend theme="/html/body" content="/html/body/@id" />	
<prepend theme="/html/body" content="/html/body/@dir" />

Now let’s make logo have a proper link and some more stuff

<prepend content="//*[@id='portal-logo']/attribute::href" 
        theme="//*[@id='logo']/a" />
<prepend content="//*[@id='portal-logo']/attribute::accesskey" 
        theme="//*[@id='logo']/a" />
<prepend content="//*[@id='portal-logo']/img/attribute::title" 
         theme="//*[@id='logo']/a" />

With these we linked the logo to the site’s root and provided some usability/accessibility helpers.

Now let’s replace our dummy site actions with something more useful

<replace content="//*[@id='portal-siteactions']" 
         theme="//*[@id='portal-siteactions']" />

… and copy the global navigation items into our theme

<copy content='//*[@id="portal-globalnav"]/li' 
      theme='//*[@id="global-navigation"]/ul' />

Now let’s populate the columns with real portlets. In the example theme we have only one column - the right one. But we also have portlets located below the content. So, to keep things simple, we will populate the bottom portlets with portlets from the standard left column:

<drop theme="//*[@id='bottom-portlets']" 
     if-content="not(//*[@id='portal-column-one']/div[@class='visualPadding']/*)"/>
<drop theme="//*[@id='column']" 
     if-content="not(//*[@id='portal-column-two']/div[@class='visualPadding']/*)"/>

<copy content="//*[@id='portal-column-one']/div[@class='visualPadding']/*" 
   theme="//*[@id='bottom-portlets']" />
<copy content="//*[@id='portal-column-two']/div[@class='visualPadding']/*" 
	theme="//*[@id='column']" />

The first set uses very powerful rules - the conditional drop. To remind you of the difference between drops: the regular drop drops the unnecessary element from Plone but the conditional drop removes the element from the theme on output if the ‘condition’ is True.

So, by using conditional drop rules, we want to avoid rendering the columns at all if Plone doesn’t give us any portlets for those columns.

The second set of rules copies portlets from Plone to our theme.

Now, let’s replace the dummy footer with the footer generated by Plone:

<copy content="//*[@id='portal-footer']/*" theme="//*[@id='footer']" />
<append content="//*[@id='kss-spinner']" theme="/html/body" />

We also append the spinner - the animated gif that is actually spinning when you do something in Plone - like save a document - and it takes some time to process the edit form. The spinner is appended to <body/> which means it will be the last child of the <body/> tag.

Finally let’s replace our dummy content with the content coming from Plone:

<copy content="//*[@id='portal-column-content']/*" 
      theme="//*[@id='document']" />

That’s pretty much it. You might want to check the example’s rules.xml though to see more rules that are used for polishing the result.


Contribute

Something wrong or out of date? Anybody can edit or create a new article in the knowledge base. Simply create an account on this site, log in, and click the Edit button to contribute.