htmlperltemplate-toolkit

Perl Multidimensional Hash in Template Toolkit


I have the following perl multidimensional hash that is passed from Dancer to Template Toolkit as a hash reference. I am having trouble figuring out how to display it in Template Toolkit.

$VAR1 = {
          'TylerMontgomery(2022)' => {
                                   'so' => 1,
                                   'bb' => 1,
                                   'rbis' => 0,
                                   'atbats' => 7,
                                   'runs' => 2,
                                   'hits' => 2
                                 },
          'ChaseLangan(2022)' => {
                                     'runs' => 4,
                                     'hits' => 4,
                                     'atbats' => 5,
                                     'bb' => 0,
                                     'rbis' => 2,
                                     'so' => 1
                                   },
          'BryceJones(2021)' => {
                            'hits' => 2,
                            'runs' => 2,
                            'atbats' => 4,
                            'bb' => 1,
                            'rbis' => 4,
                            'so' => 1
                          },
          'WillGrimes(2021)' => {
                                   'bb' => 0,
                                   'rbis' => 0,
                                   'so' => 1,
                                   'runs' => 1,
                                   'hits' => 2,
                                   'atbats' => 3
                                 },
};

I am able to interate the hash within my perl code with the following:

    foreach my $name (sort keys %season) {
        printf "%-27.27s", "$name: ";
        foreach my $stat (sort keys %{ $season{$name} }) {
            printf "%-12.12s", "$stat: $season{$name}{$stat} ";
         ## cal. avg
        $season{$name}{AVG} = $season{$name}{hits} / $season{$name}{atbats};
        }

   
    printf "%4s %.3f\n", "avg:", $season{$name}{AVG};
}

What I have tried so far for displaying it seems to be somewhat off the mark. Any help would be greatly appreciated.

 <table style="width:100%; line-height:40px;">   
        <% FOREACH Season = Season %>
        <tr>
          <td width="5">Season.key <% Season.key %></td> 
          <td width="5">Season.val <% Season.value %></td>
          <td width="5">Season.val.atbats <% Season.value.atbats %>
          <td width="5">Season.val.hits <% Season.value.hits %>  
        </tr>   
        <% END %>   
      </table>

What ends up getting displayed on web page:

HASH(0xabd1ef4)HASH(0xabd1ef4)
Season.key  Season.val  Season.val.atbats   Season.val.hits 

Solution

  • FOREACH iterates over an array. Iterate over the array returned by hash.keys.

    <% FOREACH id IN payload.keys %>
       <% season = payload.$id %>
       <p><% season.runs %></p>
       <p><% season.atbats %></p>
    <% END %>
    

    Full code:

    use Template qw( );
    
    my %seasons = (
            'TylerMontgomery(2022)' => {
                'so' => 1,
                'bb' => 1,
                'rbis' => 0,
                'atbats' => 117,
                'runs' => 2,
                'hits' => 2
            },
            'ChaseLangan(2022)' => {
                'runs' => 4,
                'hits' => 24,
                'atbats' => 5,
                'bb' => 0,
                'rbis' => 2,
                'so' => 1
            },
            'BryceJones(2021)' => {
                'hits' => 2,
                'runs' => 2,
                'atbats' => 4,
                'bb' => 2,
                'rbis' => 4,
                'so' => 1
            },
    );
    
    
    my $tt = Template->new({
       START_TAG => '<%',
       END_TAG   => '%>',
    });
    
    my $template = <<'__EOS__';
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <!-- head definitions go here -->
        <meta charset="utf-8">
      </head>
      <body>
        <div class="container" style="margin-top:20px;">
          <% FOREACH id IN seasons.keys %>
          <% season = seasons.$id %>
          <p><% season.runs %></p>
          <p><% season.atbats %></p>
          <% END %>
        </div>
      </body>
    </html>
    __EOS__
    
    $tt->process(\$template, {
       title   => 'Get Softball Season Stats',
       seasons => \%seasons,
    })
       or die($tt->error);
    

    Output

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <!-- head definitions go here -->
        <meta charset="utf-8">
      </head>
      <body>
        <div class="container" style="margin-top:20px;">
    
    
          <p>4</p>
          <p>5</p>
    
    
          <p>2</p>
          <p>117</p>
    
    
          <p>2</p>
          <p>4</p>
    
        </div>
      </body>
    </html>
    

    Note: Don't use season for both the collection and the individual seasons. I used better variables names, and you should adjust your data to match.