Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

Passing array of references to Template

by packetstormer (Monk)
on Aug 23, 2011 at 18:55 UTC ( #921967=perlquestion: print w/replies, xml ) Need Help??
packetstormer has asked for the wisdom of the Perl Monks concerning the following question:


Can anyone recommend how to pass and array of array references to Template::Toolkit to be dereferenced and displayed? Function called:

sub return_values { my $dbh = FuncClass::Connect->dbh; my $query = "SELECT name,address,phone,email,account#,date from mytable where id_code = ?"; my $sth = $dbh->prepare($query); $sth->execute($_); my @return_rows; while (my @row = $sth->fetchrow_array()) { push @return_rows, \@row; } $sth->finish(); $dbh->disconnect(); return \@return_rows;
Perl script (extract of):
#!/usr/bin/perl use strict; use warnings; use CGI; my $query = new CGI; my ( $template, $user, $cookie ) = build_office_template ( { template_name => 'office/', query => $query, type => "office", } ); my $results = &return_values; my $sendoff = @$results; $template->param('results' => \@sendoff); output_html_with_http_headers $query, $cookie,
Template file:
[% FOREACH line IN results %] [% line %] [% END %]
Now, if the \@sendoff is just an array reference this will display correctly. However, because its an array of array references its not displaying anything.

Should I deference it, bind the columns and then sent it to Template? Any suggestions would be great

Replies are listed 'Best First'.
Re: Passing array of references to Template
by philipbailey (Chaplain) on Aug 23, 2011 at 19:54 UTC

    You simply need a second loop, something like this (untested):

    [% FOR line IN results %] [% FOR item IN line %] [% item %] [% END %] [% END %]

    And in answer to should I deference it, bind the columns and then sent it to Template?--no, it's not necessary, and in fact Template Toolkit does not do what one expects (or at least what I expect) if you use arrays directly, as opposed to an array ref, for arrays with one element. It's safest to always use array refs.

      Is it FOR or FOREACH? I had been trying (and having some success with FOREACH) Regardless, neither of them work!

        FOR and FOREACH are completely interchangeable. I prefer the former, but either is fine.

        I would suggest that you convince us (or yourself, at least) that $results contains what you expect, e.g. using Data::Dumper.

        Update: it occurs to me that @sendoff is never defined. Did you really run this using strict? You don't seem to need $sendoff or @sendoff at all: just write

        $template->param('results' => $results);
Re: Passing array of references to Template
by sundialsvc4 (Abbot) on Aug 24, 2011 at 12:32 UTC

    I find that putting breakdowns of complex data structures into a template can be problematic, because now we have functionally-related logic in two different places and in two different formats.   I like to address this sort of issue using closures:   code-references, passed to the template, which resolve to subs which are defined (as variables) within the routine that is calling the template.   When the template refers to the closure, that code is executed ... and, “where is ‘that code?’   Why, it’s right here.”

    Speaking very broadly here, I want there to be a very clear separation of concerns between the template – which I only want to be concerned with presentation – and the procedural logic of the calling program.   I want to very studiously avoid having one be dependent upon the other.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://921967]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2018-12-14 18:56 GMT
Find Nodes?
    Voting Booth?
    How many stories does it take before you've heard them all?

    Results (69 votes). Check out past polls.