Skinning with pyquery and deliverance

I'm using deliverance since a few month now to skin this blog and afpy.org. I also contribute to pyquery since i like the idea of manipulating xml in python like with jQuery. So the next step is to use a kind of pyquery rule in deliverance.

After looking at the deliverance code it seems that adding new rules is easy. You just need to register it in the deliverance rules. So here is the result:

from deliverance import rules
from pyquery import PyQuery as pq

class PyQuery(rules.AbstractAction):
    """PyQuery rule for deliverance"""
    name = 'pyquery'
    def __init__(self, source_location, callback=None):
        self.source_location = source_location
        self.callback = callback

    def apply(self, content_doc, theme_doc, resource_fetcher, log):
        """apply the rule"""
        self.callback(pq([content_doc]), pq([theme_doc]), resource_fetcher, log)

    @classmethod
    def from_xml(cls, tag, source_location):
        """Parses and instantiates the class from an element"""
        use = tag.attrib['use']
        modname, funcname = use.split(':')
        mod = __import__(modname, globals(), locals(), [''])
        callback = getattr(mod, funcname)
        return cls(source_location, callback)

# register the new rule
rules._actions['pyquery'] = PyQuery

Now i'm able to use my rule. I just need to import the above module before any deliverance one:

from myproject import pyquery_rule
from deliverance.middleware import DeliveranceMiddleware
# initialize your middleware

Then here is the rules:

<ruleset>
  <theme href="/theme.html" />
  <rule class="default">
      <pyquery use="myproject.rules:default" />
  </rule>
</ruleset>

Where myproject/rules.py look like this:

def default(content, theme, resource_fetcher, log):
    """rule used for testing"""
    content('title').text('My site - '+content('title').text())
    content('#footer').remove()
    theme('body').append(content('body'))

content and theme are pyquery objects. Feel free to do whatever you want with them. Enjoy !!

Notice that this work only with deliverance's trunk (or >=0.3).

Combine zc.buildout and pip benefits

07/08/2008 python buildout pip lxml

I've just released a new zc.buildout recipe which allow to install packages with pip.

I am getting really excited about it because it has many advantages taken from both components.

  1. The recipe adds a virtualenv in the parts/ directory of your buildout then use this binary to generate executable python scripts. So you have a clean sandbox.
  2. The recipe is based on zc.recipe.egg#scripts so you can share your eggs between buildouts as usual.
  3. Of course, you can install some .pybundle files.
  4. You can build package from svn with the editables option.
  1. Each line found in the install option is the last part of a pip command. This allow you to build eggs with dependencies. For example to install lxml in a pure sandbox without libxml2 and libxslt installed you need Cython installed and this command line python setup.py install --static-deps to install lxml. This is easy with the recipe. Here is a sample configuration file for this case:
[buildout]
# the cache dir is used by buildout & pip
download-cache = download
parts = eggs

[eggs]
recipe = gp.recipe.pip

# eggs installed by pip (also add the Deliverance bundle)
install =
    Cython
    --install-option=--static-deps lxml==2.2alpha1
    http://deliverance.openplans.org/dist/Deliverance-snapshot-latest.pybundle

# eggs installed by zc.recipe.egg
eggs =
    Paste
    pyquery

That's all !! This works perfectly on my Mac OSX and should works on most system.

In fact zc.recipe.egg will work in most cases but when you need a clean sandbox and some extra options, gp.recipe.pip is a good alternative.