Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number

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
[Discipulus]: so my 'less' usage sounded not so correct? 'fewer' was more appropriate? i take a note too
Discipulus $ENV{PAGER}='fewer '
[Corion]: Discipulus: Hahahaa! ;)
[Corion]: This would be a great April fools joke, since it certainly makes sense to show fewer pages on screen :)
[marioroy]: greetings all
[Corion]: Hi marioroy!
[Corion]: I'm slowly thinking that IP::CloudHoster is a bad name. The module started out as a module to identify whether an IP address comes from a cloud hoster like AWS (or Google GCE, or Linode), but now I also added ...
[Corion]: ... a way to verify that an IP is the GoogleBot crawler. Maybe I should rename it to IP::HostInformatio n or IP::ServiceInforma tion or something like that...
[Corion]: The main idea is to use this module in a web log analyzer to highlight (real) users and flag for example hammering from AWS or GoogleBot (or UAs claiming to be GoogleBot)

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (12)
As of 2018-01-23 09:18 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (242 votes). Check out past polls.