http://www.perlmonks.org?node_id=655845


in reply to Re: Abstracting away layout details when using large HTML::Template-based sites?
in thread Abstracting away layout details when using large HTML::Template-based sites?

Thanks for the reply, as you suggest my content will be coming from an external source, along with all other page data. In this case it will be coming from a database.

Your solution of moving things around doesn't really apply terribly well when I consider how I would be using this in practise I'm afraid.

For the simple case which I've presented it does work fine, but the general problem of recursively expanding templates doesn't.

One thing that I notice is if you have a layout.tmpl like this:

<html> <head> <title><!-- tmpl_var name='title' --></title> </head> <body> <!-- tmpl_include name='page.inc' --> </body> </html>

Things work! The page.inc containing:

<h2><!-- tmpl_var name='title' --></h2>

Is correctly processed via this code:

my $template = HTML::Template->new( filename => 'layout.tmpl' ); $template->param( title => "Steve" ); print $template->output();

So suddenly my problem is reduced to including variable files! Unfortunately a similar lack of recusive support means this doesn't work:

<!-- tmpl_include name='<!-- tmpl_var name='filename' -->'>

But via a filter I can get this same aim:

# # Replace ### with environmental variable variable 'page' # sub filter { my ($text_ref ) = shift; my $val = $ENV{'page'}; $$text_ref =~ s/###/$val/g; }; # # Load 'layout.tmpl' - and have that include 'page.inc'. # # THis will expand the following in *both* files! # # <!-- tmpl_var name='title' --> # # $ENV{'page'} = 'page.inc'; my $template = HTML::Template->new(filename => 'layout.tmpl', filter => \&filter ); $template->param( title => "Something here" ); print $template->output();

I don't know whether to feel pleased or dirty ..

Steve
--

Replies are listed 'Best First'.
Re^3: Abstracting away layout details when using large HTML::Template-based sites?
by ww (Archbishop) on Dec 08, 2007 at 19:04 UTC
Re^3: Abstracting away layout details when using large HTML::Template-based sites?
by tinita (Parson) on Dec 09, 2007 at 14:24 UTC
    So suddenly my problem is reduced to including variable files! Unfortunately a similar lack of recusive support means this doesn't work: <!-- tmpl_include name='<!-- tmpl_var name='filename' -->'>
    try HTML::Template::Compiled*) - it offers TMPL_INCLUDE_VAR which includes the template file given (it also offers TMPL_INCLUDE_STRING, so that you can pass a template string into another template, but that might cost a bit of performance)
    *) disclaimer: i'm the author.
Re^3: Abstracting away layout details when using large HTML::Template-based sites?
by rhesa (Vicar) on Dec 09, 2007 at 15:11 UTC
    I would also suggest HTML::Template::Compiled, but your filter solution is pretty nice too. You can work around the ENV variable by building a filter based on the variable, using an embedded sub:
    sub mk_include_filter { my $page = shift; return sub { my $text_ref = shift; $$text_ref =~ s/###/$page/g; }; } my $template = HTML::Template->new(filename => 'layout.tmpl', filter => mk_include_filter('page.i +nc') );

      Thanks for that; I fiddled a couple of times and couldn't quite work out why it was failing. Your solution works properly ++.

      Steve
      --