http://qs321.pair.com?node_id=409316

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

Greetings esteemed monks. Is it possible to use a single template file generated with HTML::Template to display information from two separate calls to a database? I'm building a web app that needs to allow the user to view information from two separate mySQL tables on the same page for comparison purposes. The first table would display the status of available resources and the second table would display requests for the resources.

I've tried various approaches with loops on the template and subroutines in the code, but nothing has gotten even close to the double output that I need. At this point, I don't even have anything worth posting here as an example. So, before I spin my wheels futher, is this double output even possible?

If it is, any suggestions of the best way to proceed would be appreciated.

Replies are listed 'Best First'.
Re: HTML::Template-2 on one
by dragonchild (Archbishop) on Nov 21, 2004 at 04:35 UTC
    That's the beauty of using a templating system, like HTML::Template. You build your data structure within your script, then send it to the template. The template then goes ahead and displays the data any way it feels like.

    The trick I think you're missing is that the data structure you're building isn't tied to where you get the data. Let's look at an example.

    You have 5 resources. You want to display one row for each resource. The first column is the status and the second column is the last request. You will need to build an array of hashes to display everything within that TMPL_LOOP for the table. You pull your data in from each table into their own hashes. Then, you go ahead an build ANOTHER data structure, blending the two hashes from the different tables into the correct format.

    You got the extract and you got the display. You were just missing the middle piece - transformation.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: HTML::Template-2 on one
by Cody Pendant (Prior) on Nov 21, 2004 at 07:30 UTC
    I think this is a "please show your code" question.

    I have to say I don't understand why you would think it wasn't possible.

    I mean, here's the simplest possible example:

    <html><head></head><body> <tmpl_var name="stufffromtableone"> <tmpl_var name="stufffromtabletwo"> </body></html>
    And the perl would basically go:
    $x = getstufffromtableone(); $y = getstufffromtabletwo(); $template->param( stufffromtableone => $x ); $template->param( stufffromtabletwo => $y );

    So, if you know how to do that, the problem must be with some kind of data structure, loop etc.



    ($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss')
    =~y~b-v~a-z~s; print

      I'd like to a add a piece of example code to what Cody Pendant said:

      my $table_tmpl = new HTML::Template filename => 'table.tmpl'; my $result = new HTML::Template filename => 'comparison_page.tmpl' +; my ($first, $second); $table_tmpl->param(data => get_table_data(key => 'first')); $first = $table_tmpl->output; $table_tmpl->param(data => get_table_data(key => 'second')); $second = $table_tmpl->output; $result->param(first => $first, second => $second); print $result->output;

      That's a common pattern -- to generate several pieces of HTML using one template and different data and then insert these pieces into final output template.

        Your code suffers from the dreaded "Indirect Object Syntax" - something to avoid. In legacy code it can be excused, but not in example code.

        --
        edan

Re: HTML::Template-2 on one
by edan (Curate) on Nov 21, 2004 at 09:14 UTC

    If I understand you correctly, you just need to set 2 different array_ref parameters in your HTML::Template object, and then have 2 TMPL_LOOPs in your template. Pseudo-code to illustrate:

    # in your script.pl my $tbl1_array_ref = $dbh->selectall_arrayref($sql_tbl1, {Slice=>{}}, @bind_values); my $tbl2_array_ref = $dbh->selectall_arrayref($sql_tbl2, {Slice=>{}}, @bind_values); $tmpl_obj->param( TABLE1_DATA => $tbl1_array_ref ); $tmpl_obj->param( TABLE2_DATA => $tbl2_array_ref ); <!-- in your template.tmpl --> <TMPL_LOOP TABLE1_DATA> <TR><TD><TMPL_VAR ESCAPE=HTML COLUMN1></TD></TR> <!-- yada yada yada --> </TMPL_LOOP> <TMPL_LOOP TABLE2_DATA> <TR><TD><TMPL_VAR ESCAPE=HTML COLUMN1></TD></TR> <!-- yada yada yada --> </TMPL_LOOP>

    HTH

    --
    edan

      You have code duplication :) I'd do the same in this way:

      <!-- in template.tmpl --> <TMPL_LOOP TABLE1_DATA> <TMPL_INCLUDE table.tmpl> </TMPL_LOOP> <TMPL_LOOP TABLE2_DATA> <TMPL_INCLUDE table.tmpl> </TMPL_LOOP>
      <!-- in table.tmpl --> <TR><TD><TMPL_VAR ESCAPE=HTML COLUMN1></TD></TR> <!-- yada yada yada -->