Dynamic META tags in Template Toolkit

Thanks to Jonas Liljegren, I finally found a workaround to a limitation in the Template Toolkit.

I tend to wrap all my templates in a base template, which will add a standard header and footer etc to every page. TT allows you to set META variables in your inner template which will affect how this gets processed.

So, for example, in my default wrapper file I tend to have something like:

   DEFAULT wrapper = template.wrapper or 'wrapper/main_content';
   PROCESS components/browser_title;
   PROCESS components/header;
   PROCESS $template WRAPPER $wrapper;
   PROCESS components/footer;

This allows the inner content of every page to be wrapped in a certain way (in the main_content wrapper), but be overriden within a given template, by saying:

  [% META wrapper = "wrapper/flibble" %]

However, due to how the version of TT works, this can only contain static text. This causes problems in, for example, my “browser_title” template, which will contain something like:

  <title>[% template.browser_title || "My Site Name" %]</title>

It’s fine if I want to set the title of a particular page to “Product Information”, but less good if I want to set it to the name of the particular product being passed to that template!

Jonas came up with a useful hack to get around this. He defined a new Interpolate plugin which would, when USEd, translate any template variable starting with a minus sign into a re-evaluated version of that:

package MyPath::Template::Plugin::Meta::Interpolate;
use strict;
use base "Template::Plugin";
sub new {
    my ($self, $context, @params) = @_;
    my $template = $context->stash->{'template'};
    foreach my $key (keys %{$template}) {
        next if $key =~ /^_/;
        my $val = $template->{$key};
        if( $val =~ /^-(.*)/ ) {
            my $src = "[% $1 %]";
            $template->{$key} = $context->process(\$src, {});
        }
    }
    return $self;
}

Now, in my template, I can do:
[% META browser_title = -product.name %]

Perfect for improving the google ranking of all my dynamically generated product pages!

Thanks Jonas.

3 thoughts on “Dynamic META tags in Template Toolkit

  1. I recently hit this problem, which was very annoying.

    I was going to use your method, but I’m having trouble installing TT plugins so I did like the following in my wrapper template:

    [% meta.title or template.title or site.title %]

    “meta.title” simply being something that I define inside the actual page template:

    [% meta.title = “$thread.title – Foohon Pie Forums” %]

    Not sure if this is the best way to do it, but it’s quick and easy, and doesn’t involve any dependencies.

Leave a Reply

Your email address will not be published. Required fields are marked *