Gizmo(QP) Templating – GTi Skin

There is really no such thing as Gizmo(QP) Templating per se —
Gizmo(QP) applications are free to supply their own template manager,
or skin, that may define templating any which way.
An application must however pick one skin, and the simple yet flexible
GTi Skin would certainly be the most attractive default choice.

The GTi Skin
is a hybrid that mixes external template files,
for easy specifying of bulk HTML boilerplate or content,
with the convenience of being able to call Qpy Templates
or any Python Callable, that the application
chooses to expose to the template evaluation space.
The result is a versatile yet super fast and lightweight templating
mechanism, with nothing new to learn for a python programmer.

external template files, in any format
evaluation of arbitrarily complex expressions, string formatted
extensible collection of callables, in pure python
familiar, versatile, lightweight, fast

There are two, often conflicting, views on templating
— one view believes in embedding code in markup, and the other believes
in embedding markup in code. Well, piccolo problema,
sometimes you want one and other times you want the other.
The GTi Skin allows the convenient combination of the best of
these two views, while remaining extremely lightweight and performant.

The GTi Skin is altro che Gran Turismo iniezione!
Or… chrome wheeled, fuel injected and steppin’ out over the line,
as the Boss might have said. Indeed, if there is a faster pure-python
templating package out there then let’s hear about it!

GTi addressing

But, the GTi name comes from something else —
from the cool feature that a Gizmo Template may also
liberally pull() in bits and pieces
of template source (or content, or source code, or any textual material!)
from any file, for inclusion and evaluation.
This makes re-use of template code really practical and easy.

For such re-use, bits of template code are delineated by a
begin.indicator and end.indicator markers.
Thus delineated, a bit of template source code becomes addressable
via the very simple Gizmo Template indicator that is just
a file name plus a fragment indicator, e.g.
template.html#indicator. Actually, the begin and
end markers are both optional, and the beginning and/or
the end of the file will be used instead. Plus, any unremoved
begin and end markers leave no trace in rendered
output as they always evaluate to the empty string.

This feature is really handy for technical sites, with content that
may frequently refer to live code or other textual documents,
and that must stay in sync with them as they change.
The Hello Pluto page is one example
of such use. The Comprehensive Demo
site provides numerous other examples of such usage
of GTi addressing.

Automatic template reloading

GTi-addressable external template files have another advantage —
they are automatically reloaded when modified, making content
development a lot less painful.

The template string that is extracted for a given gti
is cached. When the source file from which the template string
is extracted is modified, by default the GTi Skin will automatically
re-extract and update the template string in its cache.
This behaviour may however be controlled specifically, via the
Site Configuration
auto_relaod_templates boolean parameter. A comfortable
scenario is to turn off auto template reloading for the live
deployment of a site, see the
comprehensive online demo
for an example of this.

No <head> or <body> tags

All <head> content and <body> attributes
(e.g. onload actions, css class) are defined via
the dhi instance for
the page being generated. From this, the Gti Skin generates
a properly formatted html document, including the
document declaration, the html root element,
a complete head, as well as the opening and closing
of the body.

Thus, a page template should not include any
<head> or <body> tags. But, we may still make a page template
that is perfectly functional as a standalone html document —
we delineate what we need to use from it during runtime, using any
indicator we like. For example, here is a full html
document as template, in a file called page_template.html,
and we use runtime as delineation indicator:

<title>gti skin templating example</title>

… actual template markup, callables, content …


We can then address this page template via the gti:


Template evaluation

The Skin.eval attribute is an Evaluator instance
that selectively exposes values or callables to the template
evaluation namespace. The Evaluator class, a wrapper on python’s
eval builtin, has a globals and a locals
dictionary — the globals dict belongs to Skin, while the locals dict
is reserved for the calling Gizmo(QP) Directory and is reset on each
call to

Calling gtinfo()
from within a template will output a nicely formatted
listing of the currently executing template namespace.

Explicit exposure

All callables and values are explicitly exposed to
the template evaluation space. This is for two reasons:

  • The organization and names of available objects must
    make sense from a template’s point of view.
  • Should future security requirements constrain that only safe
    values and callables are exposed, then a decoupling layer is
    already in place to make this possible.

Trusted template code

Gizmo(QP) currently assumes that all template code is trusted.
This is convenient, e.g. allowing free access to the current hit
instance, along with the attached request and response
instances. This may change in the future, to be able to support
deployment contexts that are not able to trust template code.

Template pre-processing

For more comfortable content authoring, the
GTi Skin supports markup pre-processors —
a raw template string extracted from a file with a given
extension is pre-processed according to that extension.
This pre-processing only marks up the string to HTML —
all evaluation is done per request on the
cached marked-up string.

Currently, files with a .txt or .markdown
extension are pre-processed. The first is wrapped in <pre>
tag, while the second is processed as
Adding other pre-processors is easy.