Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

HTML::Template Alternative to output()

by amitsq (Beadle)
on Oct 09, 2017 at 15:06 UTC ( #1201010=perlquestion: print w/replies, xml ) Need Help??
amitsq has asked for the wisdom of the Perl Monks concerning the following question:

Hiya, trying to practise clean clode, i tried to separate html from perl code. Therefor i used the html::Template module, which works good so far. But i only can use "template->output()" once, else the page would get printed twice. Any idea how i could update the page, without having duplicate content showing?

not sure how much my code can help, but here a simplified version of the script using the template:

use CGI qw(:standard); use CGI::Carp 'fatalsToBrowser'; use URI::Escape; use HTML::Template; use strict; use warnings; my $q = new CGI; $| = 1; my $template = HTML::Template->new(filename => "D://...//test.html"); print $q->header(); my $onevariable = $q -> param ("web"); print $template->output(); #displays beautiful css styled headline in +grid format use ownModule; print '<p id = "any" '; ownModuleMethod(); #by responseBufferLimit="0" updates are getting wr +itten on the website, which i'd like to keep that way, so the user kn +ows, which data get processed print '</p> '; #now removing all the updates print <<_EOT_; <script language=JavaScript type=text/javascript><!-- document.getElementById('any').style.display='none'; //--></script> _EOT_ my $amount = ownModuleOtherMethod(); $template->param( AMOUNT => $amount); #now i want the results to displ +ay $template->output; #can not do that, else it would print the same cont +ent again

Replies are listed 'Best First'.
Re: HTML::Template Alternative to output()
by marto (Bishop) on Oct 09, 2017 at 15:41 UTC

    "Hiya, trying to practise clean clode,"

    Make life easy on yourself. If you're starting to write something new, don't use CGI, use something like Mojolicious::Lite (see als Tutorial). Your example is less that complete, and can't be reproduced (ownModuleOtherMethod()), if you want to update a page which has already been loaded consider using AJAX to update the page. Failing that please read How do I post a question effectively? and provide a short example which runs and demonstrates your problem.

Re: HTML::Template Alternative to output()
by Anonymous Monk on Oct 09, 2017 at 18:44 UTC

    If the screen is being updated, without being redrawn, in response to user activity, then what is happening behind the scenes is AJAX, where JavaScript code running on the browser is making asynchronous requests to the server, then updating the display ("DOM") accordingly. It is certainly possible to use a server-side template (output copied to a string, not printed ...) to prepare a block of HTML for delivery to the JavaScript client, which replaces a portion of the DOM with it, thus updating the display to include it.

    But the admonition to "make it easy on yourself" is a good one. All of this sort of thing has been done before a lot. Don't start from scratch.

Re: HTML::Template Alternative to output()
by hippo (Abbot) on Oct 11, 2017 at 08:21 UTC

    Simplest solution: Use 2 templates instead of one. Since you are essentially outputting 2 completely different fragments of HTML (the header and the final results) and at different times, why not make them 2 separate templates?

Re: HTML::Template Alternative to output() (more subs , cgi101)
by Anonymous Monk on Oct 11, 2017 at 01:36 UTC

    What a bunch of poopy answers


    You need to organize your code (make subs with meaningful names), its like 2nd day programming stuff that people forget about until a framework slaps them in the face with the requirement, but you don't have to be unconcious about it, take charge of your code, give it name, like you would a stuffed animal, it makes playtime all the more interesting

    Like this, this is you foo.cgi or

    #!/usr/bin/perl -- use strict; use warnings; use MyStuff; Main( @ARGV ); exit( 0 ); sub Main { MyStuff::RunCGI({ 'dbconfig' => { } }); ## print MyStuff::ThisPage( CGI->new({ page => 'thisone', debug=>1, +in => 'making sure this works, dev, debug'} ) ); }

    This is your

    package MyStuff; use HTML::Template; use strict; use warnings; use CGI(); sub MyStuff::RunCGI { my $q = CGI->new; my( $headers, $body ) = MyStuff::DispatchCGI( $q ); print $headers, $body; } sub MyStuff::DispatchCGI { my( $q ) = @_; my $page = $q->page || 'default'; $page = 'ajax' if $q->request_method eq 'POST' and ...; return ThisPage( $q ) if $page eq 'thisone'; return ThatPage( $q ) if $page eq 'thatone'; return AjaxPage( $q ) if $page eq 'ajax'; } sub MyStuff::ThisPage { my( $q ) = @_; my $template = HTML::Template->new ...; $template->param( foo => scalar $q->param('foo') ); ... ... return $q->headers, $template->output; } sub MyStuff::AjaxPage { my( $q ) = @_; ... return $headers, $body; }

    Your html template should include/link these two javascript files jquery.js myecho.js you can get example myecho.js from Mojolicious::Lite +and jQuery +AJAX + Mojo::Template, it uses jquery to make a http request to a url and retrieve some data from it, and update the webpage/dom/display/divtag the user sees

    more subs, cgi101, learn about the internet

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1201010]
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (8)
As of 2017-12-14 15:34 GMT
Find Nodes?
    Voting Booth?
    What programming language do you hate the most?

    Results (396 votes). Check out past polls.