Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Template Question

by Anonymous Monk
on Dec 12, 2002 at 06:29 UTC ( #219261=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks

I have a .txt file that contains HTML and variables from my program, e.g. <title>$title</title> I'm using a while loop to read in the .txt file but Im not sure how to get it to replace the variables with the values - I thought it would do it automatically, but obviously not..

Any advice would be super

Replies are listed 'Best First'.
Re: Template Question
by cjf-II (Monk) on Dec 12, 2002 at 07:17 UTC

    The simplest way would be to just switch the variables from the $varname format to <TMPL_VAR NAME=VARNAME> and use HTML::Template (see the docs for more info).

Re: Template Question
by mirod (Canon) on Dec 12, 2002 at 08:58 UTC

    An other solution is to use Text::Template:

    use Text::Template 'fill_in_file'; my $TEMPLATE= 'my.templ'; # ... my $filled_template= fill_in_file( $TEMPLATE); # I usually use the HASH option to separate variables that # go in the template from variables in the code # my $filled_template= fill_in_file( $TEMPLATE, # HASH => { title => $title, # fields => \%fields # } # ); print $filled_template;

    In the template, variables (or any Perl code) are delimited by { ... }, you can use alternate delimiters if you want (it will be a little faster but the delimiter should not appear in the embedded code), use the argument DELIMITERS => [$open, $close]:

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN" ""> <html xmlns="" lang="en-US"> <head> <title>My Kewl Page</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" +> </head> <body> <h1>{$title}</h1> <p>Field1: {$field{field1}}</p> { "<p>Field2: $field{field2}</p>" if( $field{field2} } </body> </html>
Re: Template Question
by abell (Chaplain) on Dec 12, 2002 at 08:41 UTC

    Of course there are several ways to achieve this.

    Leaving the file as-is, you could apply the substitution regex

    $line =~ s/(\$[a-zA-Z0-9_]+)/ eval ($1) /ge;

    This should work under the assumptions that you are using only scalar variables with names consisting of "standard" characters (let me be a bit sloppy about this issue) and that the $ character only appears in variable names.

    Another possibility is making up a simple template language. I like to use <:name:> for placeholders to be interpolated. If your needs are limited, you can probably hack a quite stable solution in a few minutes.

    Then, along the lines of cjf-II's suggestion, you can try one of the more complete templating solutions available on CPAN.



    The stupider the astronaut, the easier it is to win the trip to Vega - A. Tucket

Re: Template Question
by stefan k (Curate) on Dec 12, 2002 at 11:30 UTC
    I use to keep my variables on a hash and then use a very similar approach as abell (assuming that the variables are written in a Makefile-like style: $(variablename):
    foreach (keys %global_variables) { $content =~ s/\$\($_\)/$global_variables{$_}/g; }
    but with this code it is not possible to escape the variable name expansion (e.g. by putting a \) in front of the $. Since there are probably some pitfalls around it would be wise to use an exisiting templating system (btw: is there any reason that so many templating systems exist? ;-)

    Regards... Stefan
    you begin bashing the string with a +42 regexp of confusion

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://219261]
Approved by fireartist
NodeReaper gets another author to use Module::Build

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2017-11-20 00:32 GMT
Find Nodes?
    Voting Booth?
    In order to be able to say "I know Perl", you must have:

    Results (282 votes). Check out past polls.