Skip to content. | Skip to navigation

Sections
Personal tools
What is this?
Hi, my name is Tom Lazar and I'm a Plone and Zope developer based in Berlin, Germany and this is my personal and professional (no big difference, really...) website.
 

Deliverance á la WSGI for Plone

Exciting times to be a Plone developer...

Deliverance is the New Kid on the Block[tm] in the Plone world. I find the whole concept very intriguing and have decided to give it a try on both of my current new projects. (No risk, no fun, eh!?)

One of the two projects is smaller in scope where I am both the Zope/Plone developer and the HTML/CSS handyman and the other a larger affair together with another Zopista and an external web agency with up to five more people, none of which is experienced with - or much interested in - Plone, so I am curious, how Deliverance will hold up in these two quite different scenarios.

Now, if you just want to dip your toes into the proverbial water, I suggest you check out Martin Aspeli's Deliverance recipe (does that man ever sleep?) However, Martin's recipe, along with any other tutorial that I found floating about, uses deliverance in its so-called proxy mode where a second daemon is fired up that mediates between the web- and application server. This is not optimal, of course, as it pretty much defeats the whole point of the WSGI concept, so I set out to create a setup, where Plone would be themed by Deliverance configured as a WSGI middleware. Forthwith my notes:

I conducted my test on Mac OS X 10.5.2 with Python 2.4.5 installed via Macports. I didn't use virtualenv (although I should have) but had to make sure throughout the whole process, that python2.4 was used (as opposed to Leopard's default 2.5.1). To do that, I installed easy_install and setuptools explicitly for 2.4:

wget http://peak.telecommunity.com/dist/ez_setup.py
sudo python2.4 ez_setup.py
sudo python ez_setup.py -U setuptools

Before dealing with Deliverance I set up a WSGI enabled Plone instance. The buildout provided by repoze.plone proved to be the best candidate to do so (believe me!)

svn co http://svn.repoze.org/buildouts/repoze.plone/trunk repoze.plone
cd repoze.plone
python2.4 bootstrap.py
./bin/buildout

I then fired up the new instance as per instructions:

./bin/supervisord
./bin/addzope2user admin admin

I then could add a Plone instance foo at localhost:8080 just as always. I then stopped the zope instance so:

./bin/supervisorctl stop zope

and then restarted it using paster:

./bin/paster serve etc/zope2.ini

and sure enough, localhost:8080/foo was still there!

Now the only thing missing was Deliverance itself. To make it available for the instance, I simply easy_installed it into my system (this is the part, where next time I'll use virtualenv!):

sudo easy_install-2.4 Deliverance

This enabled me to add the following snippet to etc/zope2.ini:

[filter:deliverance]
paste.filter_app_factory = deliverance.wsgimiddleware:make_filter
theme_uri = file:///%(here)s/layout.html
rule_uri = file:///%(here)s/rules.xml

To use the deliverance as a filter in the WSGI stack I just had to add it somewhere. I chose to add it just after zope2 itself, so that my pipeline section looked like so:

[pipeline:main]
pipeline = egg:Paste#cgitb
           egg:Paste#httpexceptions
           egg:repoze.retry#retry
           egg:repoze.tm#tm
           egg:repoze.vhm#vhm_xheaders 
           errorlog
           deliverance
           zope2

Before restarting zope (or rather 'reserving it with paster') I had to add the rulefiles mentioned in the filter declaration. Eager as I was at this point, I simply borrowed the trivial default rule and theme from Martin's recipe, spiced it up a little with one of repoze.org's own rule files and created a etc/rules.xml file that looked like this:

<?xml version="1.0" encoding="UTF-8"?>
<rules xmlns:xi="http://www.w3.org/2001/XInclude" 
    xmlns="http://www.plone.org/deliverance">
    <prepend theme="//head" content="//head/link" nocontent="ignore" /> 
    <prepend theme="//head" content="//head/style" nocontent="ignore" /> 
    <append theme="//head" content="//head/script" nocontent="ignore" />    
    <append theme="//head" content="//head/meta" nocontent="ignore" />
    <append-or-replace 
        theme="//head" 
        content="//head/title"
        nocontent="ignore" />
    <append-or-replace theme="//div[@id='content']"
        content="//div[@id='region-content']"
        nocontent="ignore" />
</rules>

and a etc/layout.html file that looked like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">
<title>The Theme</title>
</head>
<body>
<h1>A theme</h1>
<div id="content">
</div>
<hr>
<address></address>
<!-- hhmts start -->Last modified: Fri Mar 16 09:33:37 CDT 2007 <!-- hhmts end -->
</body> </html>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <title>layout</title>
</head>
<body>
</body>
</html>

Now I could stop the foreground paster process, fire it up again, hit reload in my browser and voila! Bob was my proverbial Uncle!

Next, I'll give mod_wsgi a try. But, of course, not the one for Apache but... yup, there's a mod_wsgi for nginx, too, yay! Stay tuned...

P.S. I'd like to take this opportunity to thank Chris, Tres and Paul for their efforts to connect Zope and Plone with non-techies and non-Zopistas. I'm very confident that you guys are creating some serious groundwork here that will benefit us immensely during the next eight years! Rock on!