On 10/28/18 4:45 PM, Rick T wrote:
As a novice in perl I realize that it’s a bit presumptuous for me to attempt references and complex data structures. But I had a need and gave it a shot — a failing shot. I’ve been fiddling with my failure, almost mindlessly, all weekend; now I need some help.

Below is the template segment I am trying to populate with data, and following it is the segment of code that attempts to call it. The output I get in my browser is persistently empty, with every instance of [% %] being replaced with banks.



i have many small comments as well as a larger idea that you try Template::Simple instead. it allows for arrays (such as you have) of hashes to be used without any looping code in the template itself. in fact it doesn't support any logic in the template as that should always been in perl IMNSHO. it is cleaner, faster and more flexible to organize data in perl than to do it in a template.
start HTML ------------
<table>
[% FOREACH course IN courses %]
<br><br>
<h2 id="[% course.cat_abbr %]">[% courses.category %]</h2><br><br>

i was confused by the courses.category there. it should be course.category as courses has only hashes and no values in it.

i don't see how you are making a table for each category. it seems to be one for each data row. but that is a different problem. nut i see that these are all checkboxes so that make work.
<table> <caption> [% course.caption %] </caption>
<!-- LEVEL 4 -->
<tr style="background-color: Plum">
  <td>L4 (HN)</td>
  <td><input type="checkbox" name="course_file"
             value="[% course.title %]_q1l4v[% courses.version %]"> 1-4</td>

my ( $cat_abbr, $category, $title, $caption, $version ); # for Template
my ( @courses, $string ); # for calculating
while ( my $line = <DATA> ) {

do your chomp here as it is clearer to chomp the line instead of the last field on the line.
    ( $cat_abbr, $category, $title, $version ) = split /\t/, $line;

declare those variables there and not earlier. they are only used inside the loop.
    chomp $version;
    $caption = $title;
        $caption =~ s{_|\-}{ }xmsg;     # replace _ and - with space
use // for regexes without any use of / inside. also that regex is better as a character class [_-]. the - doesn't need to be escaped in a regex but only inside a char class. and if - is the first or last char in a char class (as i showed) it doesn't need escaping.

and even better, replacing single chars is best done with the tr/// op. that would be tr/-_/ /

        $caption =~ s{\b(\w)}{\U$1}g;   # impose simple titlecase
        $caption = "$caption" . ' (version ' . "$version" . ')';
better as:

            $caption .= "(version $version)" ;

    push @courses,
        {
            cat_abbr => $cat_abbr,
            category => $category,
            caption  => $caption,
            title    => $title,
            version  => $version,
        }
you didn't end that statement with a ;. it is legal as ; are really statement separators and that is the last statement in the loop block. still it is good style to always end statements with ;


}

my %list = (list => \@courses);

# Call Template Toolkit
local $| = 1; # auto flush buffer
my $path = "/big/dom/x$server/www/templates";
my $tt = Template->new(
    {INCLUDE_PATH => "$path"}

don't quote single variables like that. it isn't needed, it is slower due to an extra copy and it could be a bug if you pass a reference that gets converted to a string.
);
my $input = 'course_catalog.tt';
my $vars = \%list;
you don't need $vars. you can just pass \%list to the call.
print "Content-Type: text/html\n\n";
$tt->process($input, $vars)
    or die $tt->error();


if i have the spare time, i will post how to do this with template::simple.

uri

Reply via email to