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 toslash.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 Evoquedomain
. - The functions
qp.pub.common.header
and
qp.pub.common.footer
are no longer needed, so are not imported.
Instead, we do importqp.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 Evoquedomain
for the site, via the
separately specifiedset_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 thepformat
utility. - We set a template under a name that we will use as default.
-
We designate the
- We override
Publisher.page()
so that it knows how
to get and evoque a template. Note that thepage()
API
remains identical — except for the added optionaltemplate
keyword by which an export may select which template to use.
If notemplate
keyword is specified on
page()
then the default template name is used. - We migrate the presentation code from
SiteDirectory.index()
to theitems.html
template. We also tell the
index()
method to use theitems.html
template. - Just for the heck of it, we also make
items.html
anoverlay
,
overriding only thecontent
sub-template,
on top ofbase.html
—
that takes over the functionality of
theheader()
andfooter()
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) -> qpy.xml 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}