I am developing an App using Perl's Catalyst framework. In trying to keep presentation logic out of my models I am looking for a way in the VIEW (template toolkit) to generate an HTML table from a given data structure. I currently use HTML::Table::FromDatabase to generate my html tables from SQL queries but this is currently in the Model. I am looking to isolate presentation logic to the View rather than have it in the model . Any advice on this would be helpful
3 Answers
This is from memory and just riffing so consider it untested. It’s a simple way to automatically iterate through columns and records.
Assumes a sub something like this with a DBIx::Class based model–
sub some_action : Local Args(0) {
my ( $self, $c ) = @_;
my $rs = $c->model("SomeTable")->search({},{rows => 10});
$c->stash( some_rs => $rs );
}
And then the matching template–
[% records = some_rs.all %]
[% RETURN UNLESS records.size %]
[% columns = records.0.columns %]
<table>
<tr>
[% FOR column IN columns %]
<th>[% column | ucfirst | html %]</th>
[% END %]
</tr>
[% FOR item IN records %]
<tr>
[% FOR column IN columns %]
<td>[% item.${column} | html %]</td>
[% END %]
</tr>
[% END %]
</table>

- 4,307
- 2
- 19
- 28
-
1Thanks Ashley. What really spurred this question was the fact that for my webApp I used HTML::Dashboard and HTML::Table::FromDatabase to generate tables from sql queries. However this logic is in the Model. In keeping with pure MVC design I am trying to separate presentation logic from my domain model and have the tables generated in the view (TT) from a datastructure stored in the stash (ref array of arrays). I was looking for a way to use HTML::Dashboard or other HTML tools within TT. (hope that makes sense) – Tony Okusanya Jun 03 '11 at 06:03
I pass the data structure (as an array of hashes) into TT and just use TT logic to build the table, with CSS classes to control the look of the table.
Simplified example of the template:
<table class="ixTable">
[% FOREACH listing = listings %]
<tr class="ixRow">
<td class="ixAddress">[% listing.address %]</a></td>
<td class="ixPrice">[% listing.listprice %]</td>
<td class="ixSqFt">[% listing.sqft %]</td>
</tr>
[% END %]
</table>

- 8,956
- 7
- 27
- 44
-
Thanks Bill I used the format you showed. What really spurred this question was the fact that for my webApp I used HTML::Dashboard and HTML::Table::FromDatabase to generate tables from sql queries. However this logic is in the Model. In keeping with pure MVC design I am trying to separate presentation logic from my domain model and have the tables generated in the view (TT) from a datastructure stored in the stash (ref array of arrays). I was looking for a way to use HTML::Dashboard or other HTML tools within TT. (hope that makes sense) – Tony Okusanya Jun 03 '11 at 06:00
Good ol' CGI.pm makes this not too difficult, but to get any real help you are going to have to show what your data structure looks like.
One potential issue is that your data may be in hashes that by their nature don't provide a column order (though database purists will tell you HTML::Table::FromDatabase is wicked and bad for encouraging select *
and assuming column order is meaningful).
HTML::Table::FromDatabase itself uses HTML::Table; you might see if that meets your needs.

- 96,171
- 6
- 121
- 214
-
Well, to be fair, the query is executed by the user beforehand, so they can just as easily `SELECT col1, col2,...` rather than just `SELECT *` to define the order. HTML::Table::FromDatabase takes the results of a query and turns them into a HTML table, as the name suggests. The examples in the docs do illustrate `SELECT *` as a simple example though, granted - perhaps I should change that to keep purists happier ;) – David Precious Oct 10 '11 at 16:23