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 overlays, or template inheritance -- 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
<html> <head><title>site-table: ${title}</title></head> <body> $begin{header}site-table: <h1>${title}</h1> $end{header} $begin{content}site-table: ${message} $end{content} $begin{footer}site-table: ${footer}$end{footer} <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
<html> <head><title>site-div: ${title}</title></head> <body> $begin{header}site-div: <h1>${title}</h1>$end{header} $begin{content}site-div: ${message}$end{content} $begin{footer}site-div: ${footer}$end{footer} <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:
<html> <head><title>site-table: hey tabby!</title></head> <body> <table class="layout"> <tr><th>site-table: <h1>hey tabby!</h1> </th></tr> <tr><td>page: you're kinda square!</td></tr> <tr><td>site-table: you reckon?</td></tr> </table> </body> </html>
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:
<html> <head><title>site-div: howdie!</title></head> <body> <div class="layout"> <div class="header">site-div: <h1>howdie!</h1></div> <div class="content">page: ya bin free floatin' good?</div> <div class="footer">site-div: sure thang!</div> </div> </body> </html>