hogsmill has asked for the wisdom of the Perl Monks concerning the following question:

Hi All,

Can anybody help me out pretty urgently? Thanks in advance.

Basically, to get some code out of the door this week, I need to be able to pre-process Template::Toollkit templates, i.e. create a single template consiting of all it's included files,. but not having any vars processed. This is to do with our bizzarre caching mechanism.

If I can get just this out of the door, I can start convincing them to compile templates,a nd use the proper cache!

Cheers,

Steve

Replies are listed 'Best First'.
Re: Template Toolkit "Pre-Processor"
by Corion (Patriarch) on Feb 29, 2008 at 12:49 UTC

    Most likely you can do this with the World's Simplest Templating Engine:

    use File::Slurp 'read_file'; my $template = read_file($template_name); 1 while $template =~ s/\[%\s*INCLUDE\s(.*?)\s*%\]/read_file($1)/msge; print $template;

    This will not handle include parameters and will not search different directories, but you can add that by replacing read_file by a subroutine more suited to your needs.

    Update: Corrected regular expression according to pc88mxer's comment

      A little nit... wouldn't you want (.*?) for $1?
Re: Template Toolkit "Pre-Processor"
by moritz (Cardinal) on Feb 29, 2008 at 12:50 UTC
    I don't know if Template-Toolkit offers such an option (I assume you have searched for one already, and haven't found one), but it shouldn't be very hard to do it by yourself.

    From the syntax exmples in the docs it seems you only have to parse

    [% PROCESS template var=val var=val ... %] [% INCLUDE template var=val var=val ... %]

    Since there's no tag nesting, it can be done with regexes.

    A first ad-hoc attempt, not tested:

    my $re = qr{ \[%-? # start tag \s* (?:PROCESS|INCLUDE) \s+ (\S+) # template name .*? # any parameters you're not interested in -?%\] # end tag }xs;

    Try if it matches all you need, if not refine it.

    And yes, that's only an ad-hoc solution, and wo't scale very well.

    (Update: template name is probably \S+, \w+ is too restrictive)

      To build on this solution, to properly handle passing parameters I think you need to replace

      [% INCLUDE file var1=val1 var2=val2 ... %]

      with:

      [% BLOCK _inline_file %] ...contents of file... [% END BLOCK %] [% INCLUDE _inline_file var1=val1 var2=val2 ... %]

      and the same for PROCESS directives. There can be complications if you use INCLUDE and PROCESS with BLOCK identifiers. In that case you'll have to determine if the template argument refers to a file or a BLOCK. Finally, if you include or process a template file twice you'll want to make sure you don't define the corresponding inlined block twice.

      btw, this would be an excellent question for the template toolkit list.

Re: Template Toolkit "Pre-Processor"
by stvn (Monsignor) on Feb 29, 2008 at 17:17 UTC

    You might want to look at Template::Multipass actually. It could be what you are looking for, or at least a start.

    -stvn
Re: Template Toolkit "Pre-Processor"
by olus (Curate) on Feb 29, 2008 at 13:02 UTC

    You can process the template and then save the resulting page wherever you want. Either giving it default values or not. Consider:

    use Template; my $template = Template->new({ INCLUDE_PATH => $template_path, }) || die $!; my %vars = (); my $pre_processed_template = ''; # this will get you the processed template $template->process('master_template.html', \%vars, \$pre_processed_tem +plate); # now you can save the processed page with the contents of $pre_proces +sed_template.
Re: Template Toolkit "Pre-Processor"
by Herkum (Parson) on Feb 29, 2008 at 15:18 UTC