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

I would like to take data from a table, modify it, then send it to a template (using HTML::Template) to display.

Let's say I have a text field, and I would like to censor/remove certain words (curses for example) before sending it to the template to be displayed on screen.

Example:
Contents of table row:
id = 33
author = John Doe
Text = Old McDonald had a farm

Word I want removed: McDonald, farm

I'm guessing I would somehow have to loop through the hashes keys, doing a substitue on the value that held the Text field, then assign the new value to the location in the hash... for each row that's called.

To get rows from table:

my $rows = $dbh->selectall_arrayref("SELECT id, post, view, author, last_updated, name, last_updated_by, stick,locked,? as misc
FROM someTable",{Columns=>{}},($misc));


The code to loop through the keys would probably be something like this... right?:

foreach $key (keys (%rows)) {
.....
}

But here's where I get lost... Does each key reference an array that holds the values from the table? Or how does it work exactly.
I know that a hash is basically indexed array, but what is it indexing in this case?

foreach $key (keys (%rows)) {
$item = $rows{$key} #what would this return?
}


What would $item now hold? A hash or array of elements? How would I modify them, and send the modified version to a template? I'm just trying to figure out how everything is glued together, so that I can take it apart, modify it, then glue it all back together again :-)


Basically, could someone possibly show me some sample code of pulling rows of data from a table, modifying elements of each row of the data taken from the table (for instance, if you wanted to format the date or time, or if you want to add commas to a number or something), then send the updated version of the rows to a template using HTML::Template to be displayed?


Thanks for all the help guys, I'm learning as I go, and I appreciate any help you guys might be able to offer :-)


Steny
  • Comment on Modifying data in a hash before sending to template

Replies are listed 'Best First'.
Re: Modifying data in a hash before sending to template
by tachyon (Chancellor) on May 16, 2004 at 23:18 UTC

    I would suggest pulling the data from the DB as a hashref. There is a good HTML::Template and DBI example doing just this at HTML::Template Tutorial. To modify the data you would just loop through it:

    my $ref = $sth->fetchall_hashref('key_field'); for my $key( %$ref ) { $ref->{$key}->{some_field} = modify( $ref->{$key}->{some_field} ); } # pass modified hash to HTML::Template sub modify { my $val = shift; # modify val return $val; }

    cheers

    tachyon

Re: Modifying data in a hash before sending to template
by sacked (Hermit) on May 17, 2004 at 04:39 UTC
    Data::Dumper will show you the structure of the data returned by selectall_arrayref as used above:
    use Data::Dumper; die Dumper $rows; __DATA__ $VAR1 = [ { 'locked' => 'no', 'stick' => 'quux', 'last_update' => '2004-05-17 00:24:28', 'name' => 'qux', 'post' => 'foo', 'author' => 'baz', 'last_updated_by' => 'joe', 'view' => 'bar', 'id' => '1' } ];
    This data is suitable for use as a <TMPL_LOOP> in a template prepared for HTML::Template. It is a reference to an array of hashes. Each hash holds the data from one record in your dataset. The keys of the hash are the table columns specified in your SELECT statement.

    To remove profanity from each record's "post" field, you can use something like the following:
    use Regexp::Common 'RE_profanity'; + foreach my $row ( @$rows ) { # $row is a hash reference containing the # data from a single record $row->{post} =~ s/$RE{profanity}/[censored]/g; } + use Data::Dumper; die Dumper $rows; __DATA__ $VAR1 = [ { 'locked' => 'no', 'stick' => 'foobar', 'last_update' => '2004-05-17 00:33:55', 'name' => 'post with curses', 'post' => 'some [censored] [censored] words', 'author' => 'values', 'last_updated_by' => 'jack', 'view' => 'other', 'id' => '2' } ];
    See the pod for Regexp::Common for an explanation of $RE{profanity} and other regular expressions it provides.

    --sacked