I've just implemented a bit of magic in the templating system. The problem I was trying to solve was that I wanted slightly different displays of metadata about articles beneath the heading. My original templates displayed the name of the author (or authors) if any, the publication date, and the description if any. That looks good on a blog article like this, but pages on a more conventional ‘catalogue’ site, like the homepage for this site, it doesn't usually make sense to include the name of the author or the publication date.
I think I've solved this by allowing the generator classes to override particular templates, in a way which is orthogonal to the template overriding that designers can use to customize the set of default templates.
Templates are searched for using my template ‘provider’ class,
Daizu::TTProvider.
The processing starts by loading the template page.tt, and
that loads other templates with the
TT INCLUDE
directive. These are all looked for in the database working copy,
checking in _template directories in case the user has provided
their own template to override the default one. If none is found, the
default template is loaded from lib/Daizu/template.
So I could have a blog use, say, a different article_meta.tt template which includes the publication date. I could have done that just by putting the custom template in my content repository in the right place, but really the generator class which creates blogs (Daizu::Gen::Blog) should be able to make the blog articles get templated in the right way all by itself.
To make this possible I've extended TTProvider to allow a kind of
simple rewriting of template names. You can now pass a hash of these
rewrites to the
generate_web_page method.
I can also use this feature to control the ‘page content’
template, which I was previously doing by passing its name in to the
templates. I can now simply have the default templates loading a
template called page_content.tt and then rewrite that when
I'm publishing something like a blog archive page, which needs to use
a different template. For example:
$self->generate_web_page($file, $url, { 'page_content.tt' => 'blog/year_index.tt', }, { months => \@months, page_title => _year_archive_title($year), head_links => \%links, });
The second hash contains variables which are passed to the templates.
Now to use this rewriting to solve my original problem, I need to
have the blog pass in a rewrite when articles are published. Rather
than force it to override the
article method
just for this, I've changed that method to call a new generator method
called
article_template_overrides.
The base-class version returns an empty hash, so the blog one can provide
a trivial overridden version that rewrites the template which puts metadata
at the top of an article:
sub article_template_overrides { return { 'article_meta.tt' => 'blog/article_meta.tt' }; }
To make this kind of change easier I've also factored out the individual bits of metadata to separate templates, so the custom one the blog generator provides, called blog/article_meta.tt, just needs to include its own selection of metadata:
<div class="entry-meta"> [% INCLUDE 'article_meta/authors_pubdatetime.tt' %] [% INCLUDE 'article_meta/description.tt' %] </div>