Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

resolved: Converting code to use DATA filehandle instead of external templates

by Spidy (Chaplain)
on Nov 20, 2007 at 04:48 UTC ( #651848=perlquestion: print w/ replies, xml ) Need Help??
Spidy has asked for the wisdom of the Perl Monks concerning the following question:

Greetings, Fellow Monks.

I am currently working on a project where I am using HTML::Template to populate our template files with the output of our CGI scripts.

Recently, I stumbled accross the fact that you can pass an already opened filehandle in to HTML::Template's new() method.

I had the idea of converting my CGI scripts to store their templates inside themselves - using the __END__ token, like so:

#!/usr/bin/perl -w ## stuff here __END__ <html> <!--template stuff here--> </html>

However, I can't figure out how to actually pass the DATA filehandle to my "Page" module, which is what I'm using to control my templates and output.

The Page module takes a hash of parameters, one of which is the parameter "template". I would like to convert this to be the filehandle that gets passed in to HTML::Template's new() method, but cannot seem to figure out how (Currently, it's the filename that gets passed).

Does anyone know how I would pass the DATA filehandle into my module's constructor function, so that I can use it in a call to HTML::Template->new() within my module?

Thanks,

Spidy



Resolution: As it turns out, HTML::Template has a 'feature' where if you set cache => 1 when you're passing in a filehandle, it does not work.

Comment on resolved: Converting code to use DATA filehandle instead of external templates
Select or Download Code
Re: Converting code to use DATA filehandle instead of external templates
by bobf (Monsignor) on Nov 20, 2007 at 05:02 UTC

    I'm a little confused. You talk about using __END__ but then you mention passing the DATA filehandle. I assume you meant to use __DATA__ instead.

    HTML::Template's new() method can also take text as the template, it doesn't have to be a filehandle. Per the docs:

    Alternately you can use:
    my $t = HTML::Template->new( scalarref => $ref_to_template_text, option => 'value' );
    and
    my $t = HTML::Template->new( arrayref => $ref_to_array_of_lines , option => 'value' );
    These initialize the template from in-memory resources.

    It looks like you can just slurp in your template (using while( my $line = __DATA__ ) or similar) and then pass the string to HTML::Template->new().

Re: Converting code to use DATA filehandle instead of external templates
by naikonta (Curate) on Nov 20, 2007 at 06:29 UTC
    (Update, per haoess below) First of all, the DATA filehandle begins after the __DATA__ token, not __END__. Here's one example to do it.
    $ cat /tmp/html-data.pl #!/usr/bin/perl use strict; use warnings; use HTML::Template; use File::Basename; my($script, $path) = fileparse($0); # the use of load_page() is intentional my $template = load_page(\*DATA); $template->param( script => $script, path => $path, pid => $$, ); print $template->output; sub load_page { my $fh = shift; HTML::Template->new(filehandle => $fh); } __DATA__ Hi, I'm script <tmpl_var name=script>, located at <tmpl_var name=path> running with process id <tmpl_var name=pid> $ perl /tmp/html-data.pl Hi, I'm script html-data.pl, located at /tmp/ running with process id 4291
    Actually, you can also use the scalarref or arrayref options with DATA, such as,
    my $template = load_page([<DATA>]); sub load_page { my $stuff = shift; HTML::Template->new(arrayref => $stuff); }
    Or,
    local $/ = undef; my $template = load_page(\<DATA>); sub load_page { my $stuff = shift; HTML::Template->new(scalarref => $stuff); }

    Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

      First of all, the DATA filehandle begins after the __DATA__ token, not __END__
      That's not always correct. perldoc perldata says:
      __END__ behaves like __DATA__ in the toplevel script (but not in files loaded with "require" or "do") and leaves the remaining contents of the file accessible via "main::DATA".
      $ cat data_eq_end.pl #!/usr/bin/perl use warnings; use strict; print for <DATA>; __END__ 1 2 3 $ perl data_eq_end.pl 1 2 3

      -- Frank

Re: Converting code to use DATA filehandle instead of external templates
by snoopy (Deacon) on Nov 20, 2007 at 06:29 UTC
    You just need to setup a DATA block and pass through filehandle => *DATA to HTML::Template
    #!/usr/bin/perl use warnings; use strict; use HTML::Template; #------------ package Page; use base 'HTML::Template'; sub new { my $self = shift; my %args = @_; $self->SUPER::new(%args); } #------------ package main; my $template = Page->new(filehandle => *DATA) || die "Unable to open template"; $template->param(orb => 'world'); print $template->output; __DATA__ hello <TMPL_VAR orb>
Re: Converting code to use DATA filehandle instead of external templates
by GertMT (Friar) on Nov 20, 2007 at 06:33 UTC
    A post that shows how it worked for me except that the use of HTML::Template isn't how it should be as described in the comments. creating HTML table

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://651848]
Approved by bobf
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2015-07-04 20:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (60 votes), past polls