qp

Integrating Evoque Templating with the QP Web Framework is pretty straightforward. As an explanation, here's the echo demo site, included in the QP distribution, modified to use Evoque. The changes are probably self-explanatory, but for the record here's a commentary on each one:

  • First of all slash.qpy is renamed to slash.py as the source code is now 100% python.
  • We import (first 2 import lines) what we need to be able to set up an Evoque domain.
  • The functions qp.pub.common.header and qp.pub.common.footer are no longer needed, so are not imported. Instead, we do import qp.pub.common.page, and the template used for each page rendering will take care of its own header and footer.
  • We override Publisher.__init__() to be able to set up an Evoque domain for the site, via the separately specified set_domain() method.
    • We designate the evoque/ sub-folder as root for our default template collection, but this can be anywhere on the file system. We may of course also specify other collections.
    • We extend the evaluation global namespace as we need to, here we only will need the pformat utility.
    • We set a template under a name that we will use as default.
  • We override Publisher.page() so that it knows how to get and evoque a template. Note that the page() API remains identical -- except for the added optional template keyword by which an export may select which template to use. If no template keyword is specified on page() then the default template name is used.
  • We migrate the presentation code from SiteDirectory.index() to the items.html template. We also tell the index() method to use the items.html template.
  • Just for the heck of it, we also make items.html an overlay, overriding only the content sub-template, on top of base.html -- that takes over the functionality of the header() and footer() QP functions while also offering additional flexibility, e.g. may have as many base templates as desired, or a base template can be more complex than just to handle a header and a footer.

The code - slash.py

import sys from os.path import join, dirname, abspath import logging from evoque.domain import Domain from qp.pub.publish import Publisher from qp.pub.common import get_request, page from qp.fill.directory import Directory from pprint import pformat class SitePublisher(Publisher): configuration = dict( http_address=('', 8001), as_https_address=('localhost', 9001), https_address=('localhost', 10001), scgi_address=('localhost', 11001), ) def __init__(self, **kwargs): super(SitePublisher, self).__init__(**kwargs) self.set_domain() def set_domain(self): default_dir = abspath(join(dirname(__file__), 'evoque')) # create template domain instance # here restating all defaults, for doc convenience self.domain = Domain(default_dir, restricted=False, errors=3, log=logging.getLogger("evoque"), cache_size=0, auto_reload=60, slurpy_directives=True, quoting="xml", input_encoding="utf-8", filters=[] ) # extensions to global namespace self.domain.set_on_globals("pformat", pformat) # preload a default template, e.g. for error pages self.domain.get_collection().get_template("", "base.html") # other setup e.g. adding other collections, template aliases # see: http://evoque.gizmojo.org/usage/ def page(self, title, *content, **kwargs): """(title, *content, **kwargs) -> h8 Return a page formatted according to the site-standard. """ # we make use of only the "template" kwarg -- there are # other possibilities, see: domain.get_template() template = kwargs.get("template", "") return self.domain.get_template(template).evoque( title=title, content=content, **kwargs) class SiteDirectory(Directory): """ This site displays the http request. """ def get_exports(self): yield '', 'index', None, None def index(self): items = get_request().__dict__.items() items.sort() return page('HTTP Request', template="items.html", items=items) def _q_traverse(self, components): return self.index()

The templates

base.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <title>${title}</title> </head> <body class="standard"> $begin{content} ${content} $end{content} $evoque{#content} </body> </html>

items.html

$overlay{base.html} $begin{content} <h1>${title}</h1> <div style="margin:1em; padding:1em; border:1px solid gray;"> <dl> $for{ key, value in items } <dt>${key}</dt> <dd style="white-space:pre">${pformat(value)}</dd> $rof </dl> </div> $end{content}