Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

CGI::Application/HTML::Template problem

by stonecolddevin (Parson)
on Jan 12, 2006 at 02:56 UTC ( [id://522606]=perlquestion: print w/replies, xml ) Need Help??

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

Hey gang,

I'm doing a website for my mom's puppy pillow company (http:.//www.boyosplace.com), and I'm attempting to use HTML::Template and CGI::Application to accomplish a shopping cart/store app.

What I'm running into is when I try to add the product to the cart, the item parameter isn't being coerced (am i using the correct word in this case?) into the template paramater in the TMPL_LOOP from the query string.

sub retrieve { my $self = shift; use Data::Dumper; my $q = $self->query; my $tmpl = $self->load_tmpl( "showitem.html", loop_context_vars =>1, associate => $q); $tmpl->param( product => $self->dbh->selectall_arrayref(q[SELECT ima +ge, price, description, serial FROM product WHERE id=?], { Slice => { +} }, $q->param('item') )); return $frm->build_page( { title => "Boyo's Place: " . $self->dbh-> +selectrow_array(q[SELECT name FROM product WHERE id=?], { Slice => {} + }, $q->param('item') ), output => $tmpl->output } ), $q->code(Dumper +(\$tmpl)); }
<!--TMPL_LOOP name="product"--> <table width="400" border="1" cellspacing="0" cellpadding="3"> <tr> <td><!--TMPL_VAR name="image"--></td> <td align="right">Price: $<!--TMPL_VAR name="price"--></td> </tr> <tr> <td colspan="2" align="justify"><!--TMPL_VAR name="description"--></td> </tr> <tr> <td colspan="2"><a href="?mode=add_to_cart&amp;item=<!--TMPL_VAR n +ame="item"-->&amp;serialn=<!--TMPL_VAR name="serial"-->">add to cart< +/a></td> </tr> </table> <!--/TMPL_LOOP-->

I've tried using Data::Dumper to sort out the $tmpl hash...but to no avail.

Can someone help me?

meh.

Replies are listed 'Best First'.
Re: CGI::Application/HTML::Template problem
by jeffa (Bishop) on Jan 12, 2006 at 15:26 UTC

    How (Not) To Ask A Question: Only Post Relevant Code

    Please break your problem down and ask again. You seem convinced that problem has to do with your usage of HTML::Template, so write a small throw-away script* that allows you pin point the problem easier. You might discover that the error does not involve HTML::Template, but instead CGI::App ... start small.

    * People got tired of rewriting these throw away scripts they use to test code and starting writing Test Suites to keep them from pulling their hair out over debugging Big Balls of Mud, BTW. ;)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Thanks very much jeffa...i've modified it to what i think is appropriate. what test suites would you recommend?
      meh.

        That's a start, but try breaking it down even further into a command line script that only uses DBI and HTML::Template:

        use strict; use warnings; use HTML::Template; use DBI; my $id = shift || 42; my $dbh = DBI->connect( ... ); my $tmpl = HTML::Template->new(filehandle => \*DATA); my $product = $dbh->selectall_arrayref(q{ SELECT image, price, description, serial FROM product WHERE id = ? }, {Slice => {}}, $id); # i think it's better to use a variable instead of # passing the results from the query directly to the # $tmpl->param method (easier debugging) $tmpl->param(product => $product); print $tmpl->output; __DATA__ <tmpl_loop product> image: <tmpl_var image> price: <tmpl_var price> description: <tmpl_var description> serial: <tmpl_var serial> </tmpl_loop>
        Look into the CPAN test suites for more about that. Test::More, Test::Simple, etc.

        jeffa

        L-LL-L--L-LL-L--L-LL-L--
        -R--R-RR-R--R-RR-R--R-RR
        B--B--B--B--B--B--B--B--
        H---H---H---H---H---H---
        (the triplet paradiddle with high-hat)
        
Re: CGI::Application/HTML::Template problem
by wfsp (Abbot) on Jan 12, 2006 at 16:51 UTC
    Hi dhoss!

    Taking a cue from jeffa.

    Am I right in thinking that by "coerce" you mean using the HTML::Template "associate" option to use a parameter in the CGI query object?

    If that is the case then perhaps the following may help.

    #!/bin/perl5 use strict; use warnings; use CGI::Carp qw( fatalsToBrowser ); package main; my $webapp = App->new(); $webapp->run(); package App; use base 'CGI::Application'; use CGI; sub cgiapp_get_query { my $self = shift; # initilise the query object # with some params my $q = CGI->new( { 'test' => 'test page', 'greeting' => 'Hi there!', } ); return $q; } sub setup { my $self = shift; $self->start_mode('test'); $self->run_modes([qw|test|]); } sub test{ my $self = shift; my $html; { local $/; $html = <DATA>; } my $tmpl_obj = $self->load_tmpl( \$html, associate => $self->query, ); return $tmpl_obj->output(); } __DATA__ <html> <head> <title><!-- TMPL_VAR NAME = TEST --></title> </head> <body> <p><!-- TMPL_VAR NAME = GREETING --></p> </body> </html>
    output:
    ---------- Capture Output ---------- > "C:\Perl\bin\perl.exe" c_app.pl Content-Type: text/html; charset=ISO-8859-1 <html> <head> <title>test page</title> </head> <body> <p>Hi there!</p> </body> </html> > Terminated with exit code 0.

    update:
    dhoss! You changed your snippet while I preparing this post :-(
    Hope this may still be of some use. :-)

      that works, but i think it's the TMPL_LOOP that's giving me troubles...i think there's something in associating it with CGI (and yes i meant associate by coerce) that the TMPL_LOOP doesn't associate it's tags with CGI...
      meh.
        I found your snippet a bit tricky to digest so I've blown some whitespace into it.

        sub retrieve { my $self = shift; use Data::Dumper; my $q = $self->query; my $tmpl = $self->load_tmpl( "showitem.html", loop_context_vars =>1, associate => $q ); $tmpl->param( product => $self->dbh->selectall_arrayref( q[ SELECT image, price, description, serial FROM product WHERE id = ? ], { Slice => {} }, $q->param('item') ) ); return $frm->build_page( { title => "Boyo's Place: " . $self->dbh->selectrow_array( q[ SELECT name FROM product WHERE id=? ], { Slice => {} }, $q->param('item') ), output => $tmpl->output } ), $q->code(Dumper(\$tmpl)); }
        I would use a lot of temp vars to simplify the code and help establish what is happening.

        e.g.

        my $arrayref = $self->dbh->selectall_arrayref( etc.... die Dumper $arrayref; # on a subsequent run my $arrayref2 = $self->dbh->selectrow_array( etc... die Dumper $arrayref2; # and even die Dumper $q->param('item');
        You need to be sure you are feeding your template loop an array of hash refs. Each hash ref will need

        item => $item_value

        in it. You may have to loop through the dbh output yourself to put that in.

        Hope that helps

Re: CGI::Application/HTML::Template problem
by kutsu (Priest) on Jan 12, 2006 at 17:55 UTC

    If you tryed to print "item" outside the template loop I bet it would print. This is because associate => $q is the same as doing $template->param(ITEM => $q->param('item')) for every param returned by cgi and TMPL_LOOPs introduce their own scope and can't use variables from outside the loop. If you set global_vars => 1 it should work.

    Btw. in order to find I simplify your code by trying it without CGI::Application:

    script: #!/usr/bin/perl use DBI; use HTML::Template; use CGI; my $q = CGI->new(); my $dbh = DBI->connect('DBI:Pg:dbname=testdb', '', ''); $dbh->{RaiseError} = 1; $aref = $dbh->selectall_arrayref( q/select foo, bar from test_table wh +ere id = ?/, { Slice => {} }, $q->param('id') ); $dbh->disconnect; my $template = HTML::Template->new(filename => 'test.tmpl', associate +=> $q, global_vars => 1); $template->param(TEST_LOOP => $aref); print $template->output(); template: id = <TMPL_VAR NAME=ID> <!--remove global_vars and only this first ID will print--> <TMPL_LOOP NAME=TEST_LOOP> <p> id: <TMPL_VAR NAME=ID> <br \> foo: <TMPL_VAR NAME=FOO> <br \> bar: <TMPL_VAR NAME=BAR> </p> </TMPL_LOOP>
      global_vars was exactly what i was looking for...thanks so much kutsu, all!!!
      meh.
Re: CGI::Application/HTML::Template problem
by markjugg (Curate) on Jan 12, 2006 at 19:06 UTC
    To address the bigger picture issue, you may also be interested in Handel, an toolkit to help with shopping carts in Perl. It integrates directly with other web frameworks, but can still be used from CGI::Application as well.
Re: CGI::Application/HTML::Template problem
by jesuashok (Curate) on Jan 12, 2006 at 05:06 UTC
    Hi

    Please have a look at the following code that will helpful for you.

    push @all_user_types, { users_list => $values, users => $values, report_for_user => $values eq $c +gi_user_type }; $html->param(user_types => \@all_user_types );


    <TMPL_LOOP NAME="user_types"> <option value="<TMPL_VAR NAME=users>" <TMPL_IF report_for_user>SEL +ECTED</TMPL_IF>><TMPL_VAR NAME=users_list></option> </TMPL_LOOP>
    that is the way we used to Build the Elements Using TMPL_LOOP.

    If that is Useful for you Please have a look.

    "Keep pouring your ideas"
      I'm not sure what this has to do with my code...did i miss something? I see no reference to my own code, nor any way to properly coerce the query string data into my template...
      meh.
        You have

        $tmpl->param( product => $self->dbh->selectall_arrayref(q[SELECT image, price, description, serial FROM product WHERE id=?], { Slice => {} }, $q->param('item') ));

        You're selecting image, price, description and serial from the data, and those are going into the products loop as named elements, with their values as was selected.

        The problem is, you're using $q->param('item') for your id, but since you're not including that as one of the values that will be available from the SQL, it isn't available for the product loop to use. CGI parameters are not automatically available to templates (though you can easily add them, though I forget the syntax off the top of my head... sorry it's 1am and I don't feel like looking it up).

        Something like this will work as well

        $tmpl->param( product => $self->dbh->selectall_arrayref(q[SELECT id as "item", image, price, description, serial FROM product WHERE id=?], { Slice => {} }, $q->param('item') ));

      Please have a look at the following code that will helpful for you. 202468746d6c2d3e706172616d28757365725f747970657320203d3e205c40616c6c5f757365725f747970657320293b20 that is the way we used to answer questions.

      If that is Useful for you Please have a look.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://522606]
Approved by muba
Front-paged by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-03-29 06:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found