Overriding templates

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>

< Displaying null values in psql | PictureArticle plugin >