Switching site template, dynamically, per user

The use of overlays, or template inheritance, where the
base template is used to define the site layout
could be a simple and effective way to manage a theme for a site.
In addition, multiple site themes could be managed simply via
multiple site base templates.
Evoque supports dynamic data-driven overlays
and dynamic in two very handy ways:

  • First, by the possibility of using logically named templates that
    allows assigning a name to any template, and then retrieving it by that name.
    The dynamic part comes from the fact that we can at runtime change which
    template is pointed to by a given name (by first doing a
    template.unload() and then loading another template
    under the same name).
  • Second, by the fact that a template may specify which
    template it overlays by means of a parameter that will be evaluated for
    each rendering at runtime.

For this case, the second technique makes it
really trivial to parametrize the base template per user.
Here’s the essence of an overlay page template that does this:

a dynamic page overlay: site_dyn_page_var.html
$overlay{name=my_site_theme}
$begin{content}page: ${message}$end{content}

Where, on each rendering, which base template to use is determined
by the runtime value of my_site_theme.
Assume we have loaded the template with:

page_overlay = domain.get_template("site_dyn_page_var.html")

We can then specify a different value for my_site_theme
on each rendering:

page_overlay.evoque(my_site_theme="site_template_divs.html", ... )

Note that if you want to make sure you always have a fallback value
for my_site_theme
(for all renderings, all templates, and all users)
then just set it on the domain’s globals:

domain.set_on_globals("my_site_theme", "site_template_table.html")

example details

For completeness, let’s fill in the full details for this simple example
(that forms part of the Evoque test cases, and is included in the distribution).

a couple base templates as site themes

theme one: site_template_table.html
$begin{header}site-table: <h1>${title}</h1>$end{header}
$begin{content}site-table: ${message}$end{content}
$begin{footer}site-table: ${footer}$end{footer}
<html>
<head><title>site-table: ${title}</title></head>
<body>
    <table class="layout">
        <tr><th>$evoque{#header}</th></tr>
        <tr><td>$evoque{#content}</td></tr>
        <tr><td>$evoque{#footer}</td></tr>
    </table>
</body>
</html>
theme two: site_template_divs.html
$begin{header}site-div: <h1>${title}</h1>$end{header}
$begin{content}site-div: ${message}$end{content}
$begin{footer}site-div: ${footer}$end{footer}
<html>
<head><title>site-div: ${title}</title></head>
<body>
    <div class="layout">
        <div class="header">$evoque{#header}</div>
        <div class="content">$evoque{#content}</div>
        <div class="footer">$evoque{#footer}</div>
    </div>
</body>
</html>

a couple renderings of the same page overlay

using theme one:
page_overlay.evoque(my_site_theme="site_template_table.html",
    title="hey tabby!", message="you're kinda square!", footer="you reckon?")
gives the output:

[KeyError: ‘auto’: File “/home/admin/py-packages/evoque/domain.py”, line 108, in get_collection
return self.collections[name]
: EvalError(evoque(name=u’site_dyn_page_table.txt’, collection=”auto”, raw=True, filters=[evoque_html_highlight]))]

using theme two:
page_overlay.evoque(my_site_theme="site_template_divs.html",
    title="howdie!", message="ya bin free floatin' good?", footer="sure thang!")
gives the output:

[KeyError: ‘auto’: File “/home/admin/py-packages/evoque/domain.py”, line 108, in get_collection
return self.collections[name]
: EvalError(evoque(name=u’site_dyn_page_divs.txt’, collection=”auto”, raw=True, filters=[evoque_html_highlight]))]