<< All Blog Posts

Deploying Plone and Zine together with Deliverance using Repoze

Using the right tool for the right job

Six Feet Up loves Plone, but using Plone as a blogging tool has never been a strong point. Blogging isn't something that we felt that Plone did well out of the box. Much like most Plone products, you have to add in various third party products or create your own products if you want to get some of the really nice features that many of the typical blogging platforms like WordPress offer today like pingbacks. We had tried quite a few of these ways of stuffing blogging into Plone and ran into various issues of dependencies or incompatibilities along the way so we decided to go for a solution that wasn't in Plone.

Zine is a blogging platform written in Python and supports being deployed as a WSGI application, so it seemed like the perfect fit. Zine is basically a python clone of WordPress and has all the nice goodies and plugins that modern blogging platforms have come to enjoy. It is also relatively easy to theme and write plugins to extend its behavior.

We can also run Plone as a WSGI application by using the Repoze application repoze.zope2 instead of the standard Zope ZPublisher. The big benefit is that we can run multiple WSGI applications in a single process and utilize WSGI middleware like Deliverance to theme all of the applications as they are delivered. This type of setup can simplify deployment greatly and all works well with buildout, which we have a lot of knowledge about already.

Bringing together the pieces

Let's start by getting repoze.zope2, zine and deliverance added to our buildout. I added four additional parts to our existing buildout profile to get this process started.

[buildout]
...
parts = 
  ...
  repoze # this needs to be before the zope2 part or plone won't work
  ...
  deliverance # these have to go at the end or paster won't get all the right eggs listed
  zine-deps
  zine

I also added this to the [buildout] section to pin the version of the zopelib:

find-links =
    ...
    http://dist.repoze.org/zope2/latest/zopelib-2.10.7.0.tar.gz

...
versions=versions

[versions]
zopelib = 2.10.7.0

In these four new parts we will add in the new bits required to host the full WSGI stack for our deployment. Here are the parts we added:

[repoze]
recipe = zc.recipe.egg
eggs =
     PasteScript
     WSGIUtils
     repoze.zope2
     ${plone:eggs}
index = http://dist.repoze.org/plone/latest/simple

[deliverance]
recipe = infrae.subversion
as_eggs = true
urls =
    http://codespeak.net/svn/z3/deliverance/trunk deliverance

[zine-deps]
recipe = zc.recipe.egg
extra-paths = parts/zine/lib/zine
interpreter = python
eggs = Paste
       PasteScript
       PasteDeploy
       ${instance:eggs}
       ${repoze:eggs}
       ${deliverance:eggs}
       SQLAlchemy>=0.5.0
       Jinja2>=2.1.0
       Werkzeug>=0.4
       simplejson
       html5lib
       pytz
       Babel>=0.9.4
       lxml>=2.0
       Pygments>=0.9
       docutils==0.5
       zinebuildout>=0.4
       MySQL-python

[zine]
recipe = zc.recipe.cmmi
url = http://zine.pocoo.org/releases/Zine-0.1.2.tar.gz
extra_options = --python=python

With all of that added to your buildout profile you need to re-run buildout and it will download and install all the needed parts for you.

Configuring the paster WSGI stack

Before we can start up the new WSGI stack with paster, we will need to create a paster.ini for the WSGI stack and a rules.xml file for deliverance to use.

You can put both of these files in the root of your buildout. The paste.ini is using the zinebuildout egg to allow us to use Zine as an application in our paster stack. It is configured in the [app:zine] section. You will need to make an empty zine directory in your buildout that will contain the zine.ini once Zine has been configured through the web.

The paste.ini file configures two pipelines, one for each application. The blog pipeline has the deliverance filter applied to it so you get the Plone theme applied to the Zine blog.

paste.ini

[DEFAULT]
debug = True

[app:zine]
use = egg:zinebuildout
instance_folder = %(here)s/zine

[app:zope2]
paste.app_factory = repoze.obob.publisher:make_obob
repoze.obob.get_root = repoze.zope2.z2bob:get_root
repoze.obob.initializer = repoze.zope2.z2bob:initialize
repoze.obob.helper_factory = repoze.zope2.z2bob:Zope2ObobHelper
zope.conf = %(here)s/parts/instance/etc/zope.conf

[filter:errorlog]
use = egg:repoze.errorlog#errorlog
path = /__error_log__
keep = 20
ignore = paste.httpexceptions:HTTPUnauthorized
       paste.httpexceptions:HTTPNotFound
       paste.httpexceptions:HTTPFound

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

[pipeline:blog]
pipeline = egg:Paste#cgitb
           egg:Paste#httpexceptions
           errorlog
           deliverance
           zine

[filter:deliverance]
use = egg:deliverance#main
rule_filename = %(here)s/rules.xml

[server:main]
use = egg:repoze.zope2#zserver
host = localhost
port = 51047

[composite:main]
use = egg:Paste#urlmap
/blog = blog
/zope = zope

Configuring Deliverance to theme Zine with the Plone site theme

Deliverance is configured in the rules.xml file and points to the Plone application's main_template to get the look and feel. The rest of the rules drop bits that aren't needed and throw the Zine portlets and content into the right places in the Plone theme. We created a Zine plugin to wrap the Zine portlets with a more Plone like structure so that they blend right into the Plone theme.

rules.xml

<ruleset>
<theme href="/zope/Plone/main_template" />
<rule>
  <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" />
  <replace theme="//head/title" content="//head/title"  nocontent="ignore" />
  <!-- we don't need the reddit zine links -->
  <drop content="//div[@class='reddit']"/>
  <!-- let's drop the breadcrumbs from the plone theme -->
  <drop theme="#portal-breadcrumbs"/>
  <!-- let's drop the plone login box -->
  <drop theme="//td[@id='portal-column-one']/div/div"/>
  <!-- put the zine portlets in column one -->
  <append theme="//td[@id='portal-column-one']/div" content="//div[@class='sidebar']/*" nocontent="ignore"/>
  <!-- put the body of the zine in the content region -->
  <append theme="children:#region-content" content="children://div[@class='contents']" nocontent="ignore" />
  <!-- put the administrative links in column two -->
  <prepend theme="children:#portal-column-two" content="//div[@class='body']/ul" nocontent="ignore"/>
  <!-- make sure the login box has a spot when we need it -->
  <append theme="#viewlet-above-content" content="//div[@class='login-box']" nocontent="ignore"/>
</rule>
</ruleset>

Time to start up paster

Once these are all in place and you have created the zine directory at the root of your buildout, we can start the paster server. It is started like this:

bin/paster serve paste.ini

Now in your browser you can go to http://localhost:8080/zope to see the Zope/Plone instance. You will need to add a Plone Site to your instance. In my demo I gave it an id of "Plone". If you have a Plone Site with a different id, you will need to change the path to the in your rules.xml.

Now, when you go to http://localhost:8080/blog you will be presented with the Zine setup screens. If all went well, the screens should look like your Plone Site theme. At this point you will need to setup a MySQL database to hold the blog data and provide connection information as you go through the Zine setup wizard.

Now you can fix up and modify the rules.xml and theme in your Plone site to make the Zine blog blend into your site seamlessly. Enjoy!

Download the buildout used in this post

 


Thanks for filling out the form! A Six Feet Up representative will be in contact with you soon.

Connect with us