Quick and easy Plone theming with XDV
Testing new stuff
Plone is evolving. Future versions will support new and very easy ways to customize different part of the CMS. XDV is one of them, as a result of the maturity of deliverance, XDV let's you use a static set of resources as Plone theme using xpath rules. If that sounds awkward, believe me, describing is harder than do it.
At the end of Plone's theming documentation, the author encourages you to try it, after all "the best way to learn is by doing". At that point i found the approach easy enough give it a try and even if i'm kinda reluctant to explore new ways of doing certain tasks, i was very curious to test if XDV promises were true. I didn't spend to much time looking for a design, and i just picked the first one among a list of four:
xdvtheme.inventions
The idea behind XDV is very simple, you put a facade in front of Plone. That facade, named theme, is built with a set of static htmls, css and js and it is wired with Plone by a set of rules that maps Plone's original skin with the theme.
Invention a two-column layout theme, is very simple and so the rules required to do the job, all you have to do is write a list of rules and voila, you get Inventions working in Plone.
In my case, i decided to modify the CSS because i wanted to clear the code a little bit. Although it wasn't necessary at all, sometimes it is easier to modify the theme's css than writing a rule, if the code is under your control you might do this, but that's not always the case as i knew from a Matt Hamilton's talk, where he uses deliverance to integrate a .net portal, Plone and Moodle.
The rules are stored in a file called rules.xml. In this case i need just 5 rules, one for the title, content, global navigation, right column and the last one to remove images in portlets, respectively:
<rules xmlns="http://openplans.org/deliverance"> <!-- title --> <replace content='/html/head/title' theme='/html/head/title' />
<!-- content area -->
<copy content='//*[@id="content"]' theme='//*[@id="leftcolumn"]' /> <copy content='//*[@id="portal-globalnav"]' theme='//*[@id="links"]' /> <!-- Portlets --> <copy content='//*[@id="portal-column-two"]' theme='//*[@id="rightcolumn"]' /> <drop content='//*/dl/dd/a/img' /> </rules>
There are five kind rules: copy, replace, drop, prepend and append. Combining them with XPath expressions you manipulate each element and merge both themes. They're not very hard constructions and you can use two tools to make the job even easier. The first one is firebug, firebug let's you select an element and get the Xpath construction. The other one is banjo, following a post by Nate Aune:
"Banjo is a web-based tool which loads in the browser. The browser window is divided into three panes: one pane that loads the Plone site, one pane that loads the theme, and one pane that we’re calling the control panel. You simply click on the element in your Plone site, and then click on the corresponding element in your theme to “map” these elements together. The resulting mappings are written out as rules in the rules.xml file, which is used by Deliverance to insert Plone’s HTML in the proper placeholder in the theme’s HTML".
Performance
When I got the inventions theme working and I started to test it, I found it very fast. How fast ?, let's see some tests made at home. The first one was against my predictions. Using apache's benchmark tool i got:
| xdvtheme.inventions |
Plone's default skin |
|
|---|---|---|
| Server Software: Zope/(Zope) Server Hostname: dev.menttes.com Server Port: 14777 Document Path: /demo Document Length: 13299 bytes Concurrency Level: 1 Time taken for tests: 2.749304 seconds Complete requests: 10 Failed requests: 0 Write errors: 0 Total transferred: 135810 bytes HTML transferred: 132990 bytes Requests per second: 3.64 [#/sec] (mean) Time per request: 274.930 [ms] (mean) Time per request: 274.930 [ms] (mean, across all concurrent requests) Transfer rate: 48.01 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 270 274 3.6 274 281 Waiting: 269 273 3.9 272 281 Total: 270 274 3.6 274 281 |
Server Software: Zope/(Zope) Server Hostname: 200.68.91.21 Server Port: 14777 Document Path: /demo Document Length: 23605 bytes Concurrency Level: 1 Time taken for tests: 2.541178 seconds Complete requests: 10 Failed requests: 0 Write errors: 0 Total transferred: 238870 bytes HTML transferred: 236050 bytes Requests per second: 3.94 [#/sec] (mean) Time per request: 254.118 [ms] (mean) Time per request: 254.118 [ms] (mean, across all concurrent requests) Transfer rate: 91.69 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 242 253 12.3 248 272 Waiting: 241 252 12.3 247 271 Total: 242 253 12.3 248 272 |
So, using xdvtheme.inventions, the transfer rate is nearly the half than the default skin. It seems my machine needs more time to apply the rules, and even if xdvtheme.inventions requires to transfer half of data, 12,98Kb against 23,05Kb, the result favors to Plone's default skin since it takes 242ms against 270ms. Then, from server side, default approach seems to be better.
Although the results I got with ab, I still found inventions faster in my browser. The key here seems to be that variable ab calls document length. Using YSlow I compared time to load the home page, data being transfered in kilobytes and per components.
Quick thought: length matters. Even paying the price at server side, Plone's default skin takes 3 times more to get loaded in Firefox 3.5. It requires more than 100Kb of Javascript, where i had no need to use js in inventions.
This remind me a talk gave by Joel Burton in Naples, where he started saying Plone is not slow, it just performs to many tasks. And I find these simple comparisons supporting that idea because we're comparing a general purpose skin, elastic, with editor and multiple layout support against a fixed-layout one, no edition support and it covers a very particular case. Anyway, if you don't need such general purpose solution for certain scenarios, now there's an alternative and it's easier and more flexible than existing approaches.
Testing, feedback welcome
xdvtheme.inventions runs with Plone 3.3rc5, it requires collective.xdv and a web server or Products.Reflecto to make available the static content. If you want to try it, just run:
$svn co http://svn.plone.org/svn/collective/xdvtheme.inventions/trunk/ themes
and then just follow readme.txt's instructions. Any comment, question or feedback is always welcome.
Resources
- Lipstick on a Pig, Matt Hamilton's talk. Slides with audio.
- Theming Plone with XDV - Limi's tutorial to get started with xdv.
- collective.xdv package documentation at pypi
- Banjo, creating deliverance/xdv rules TTW - Blog post and video, by Nate and friends.
- Deliverance Project
- Deliverance Demo and Deliverance Tutorial efforts at Sorrento Sprint - another implmentation for inventions, in this case using deliverance, i found this example after i finished xdvtheme.inventions.
- Products.Reflecto - a tool to incorporate part of the file system into a Plone site by Jarn.
- Apache Benchmarking tool
- YSlow - performance benchmarking tool by yahoo
- Plone Users mailing list - thanks to Jon Stahl for the Reflecto tip
- Menttes' team