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

Hi, I use the following snippet to create a file using HTML::Template:
open (FILE, "$indx_tem") or die " $indx_tem: $!"; open (FILE1, ">$indx") or die "$indx: $!"; while (<FILE>) { # open the HTML template my $template = HTML::Template->new(filename => $indx_tem); # fill in some parameters in the template $template->param(Location => $Location); $template->param(Number => $Number); $template->param(word => $word); # print the template to file $template->output(print_to => *FILE1); last;
This works no problem.

However I have several of these files and I thought it would be useful to write a script to update all existing files if I make a change to the template.

I came up with the following:

print header(); open (FH, "$db") or die "$db: $!"; while (my $line = <FH>) { ($word,$time,$Number,$Location) = split "\t",$line; if ($Number) { #template open (FILE, "$indx_tem") or die "Can't open $indx_tem: $!"; #file to renew open (FILE1, ">$indx") or die "Can't open $indx: $!"; while (<FILE>) { # open the HTML template my $template = HTML::Template->new(filename => $indx_tem); # fill in some parameters in the template $template->param(Location => $Location); $template->param(Number => $Number); $template->param(word => $word); # print the template to file $template->output(print_to => *FILE1); last; } close FILE; close FILE1; print "finish$Number<br>"; } } print end_html();
Now my debugging at the end prints out all the $Number in the db so I had thought that it was going to work but alas when I checked the file it was from the old template. (When I added a new file to the database, it was created using the new template so I know that there is no mix-up with the templates).

Can anyone come to my rescue?

Replies are listed 'Best First'.
Re: using HTML::Template to update a file
by Ovid (Cardinal) on Mar 05, 2003 at 22:47 UTC

    I'm not sure exactly what you're asking, but I noticed some issues with your code, so I thought I would point them out and hopefully they'll help.

    Your first code snippet is incorrect. You open your first filehandle and iterate over it, but you don't actually use it and then you last out of it to skip the useless iteration. The code is equivalent to this cleaner (and untested) version:

    open NEW_TEMPLATE, "> $indx" or die "Cannot open ($indx) for writing: +$!"; # open the HTML template my $template = HTML::Template->new(filename => $indx_tem); # fill in some parameters in the template $template->param(Location => $Location); $template->param(Number => $Number); $template->param(word => $word); # print the template to file $template->output(print_to => *NEW_TEMPLATE);

    Your second code snippet then reduces to something like the following:

    open DB, "< $db" or die "Cannot open ($db) for reading: $!"; while (my $line = <DB>) { chomp $line; my ($word,$time,$Number,$Location) = split "\t",$line; if ($Number) { open FILE1, "> $indx" or die "Can't open $indx: $!"; # open the HTML template my $template = HTML::Template->new(filename => $indx_tem); # fill in some parameters in the template $template->param(Location => $Location); $template->param(Number => $Number); $template->param(word => $word); # print the template to file $template->output(print_to => *FILE1); close FILE1; print "finish$Number<br>"; } else { # do you need debugging if you don't use $Number? } } close DB;

    Also, it's worth pointing out that iterating over the lines in the "DB" is probably not what you want as your template will only be updated with the last line of data.

    Cheers,
    Ovid

    New address of my CGI Course.
    Silence is Evil (feel free to copy and distribute widely - note copyright text)

      Thanks Ovid for your time spent clarifying this for me.

      I understand the faults with my original script, and have corrected them accordingly.

      Another problem I had which you could not have known about is that I defined $indx too early in the script since its path is dependent upon $Number

      I now have the following script:
      use strict; use CGI ':standard'; use CGI::Carp qw(fatalsToBrowser warningsToBrowser); use HTML::Template; my $db="/path/edit/data.txt"; print header(); open DB, "< $db" or die "Cannot open ($db) for reading: $!"; while (my $line = <DB>) { chomp $line; my ($word,$time,$Number,$Location) = split "\t",$line; if ($Number) { my $indx = "/path/pages/$Number/index.html"; open FILE1, "> $indx" or die "Can't open $indx: $!"; # open the HTML template my $template = HTML::Template->new(filename => $indx_tem); # fill in some parameters in the template $template->param(Location => $Location); $template->param(Number => $Number); $template->param(word => $word); # print the template to file $template->output(print_to => *FILE1); close FILE1; print "finish$Number<br>"; } } close DB; print end_html();
      This seems to function well and all my files are now brought up to date when I make a change to the template file.

      Thanks once again for your help