Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Injecting local variables into a template

by MistaMuShu (Beadle)
on Feb 06, 2008 at 05:23 UTC ( [id://666473]=perlquestion: print w/replies, xml ) Need Help??

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

Hello Monks!

After a long hiatus from the site, I'm back again :)

I've been toying with a side pet project for publishing HTML files. What I'm trying to achieve is similar to what ActionView, and other templating tools do.

In publish.pl, let's say I have a subroutine 'layout' that has local variables $headline, $body, $url. Within this sub, I'd like to call another script 'article.layout.pl', but with the local variables $headline, $body, and $url available to the script. 'article.layout.pl' would then use these variables to print out the final layout.

In publish.pl

sub layout { ... my ($headline, $body, $url); ... # call article.layout.pl ??? article.layout.pl {$headline, $body, $url}; }

In article.layout.pl

print <<HEADER ... HEADER print $title; print $body; print $url; print <<FOOTER ... FOOTER

I realize I could use TemplateTookit to achieve this, but I was hoping to learn how to call mess with perl scoping in general.

Thanks fellow monks! It's good to be back.

Replies are listed 'Best First'.
Re: Injecting local variables into a template
by hipowls (Curate) on Feb 06, 2008 at 05:45 UTC

    You could look to see how Template::Stash does it. Besides the POD there are comments in the code describing how each function works.

Re: Injecting local variables into a template
by ikegami (Patriarch) on Feb 06, 2008 at 06:53 UTC

    For starters, your my usage is wrong.
    my $headline, $body, $url;
    means
    (my $headline), $body, $url;
    but you want
    my ($headline, $body, $url);

    The solution requiring minial change is,

    # publish.pl sub layout { local our ($headline, $body, $url) = @_; do 'article.layout.pl'; } layout($headline, $body, $url);
    # article.layout.pl our ($headline, $body, $url); print("$headline, $body, $url\n");

    Update: Just to be clear, I recommend against using my solution (and wfsp's). I think you're going to spend way more time avoiding using a real template system than actually switching over. The sooner you switch, the easier and quicker it will be. My solution is a quick fix in case you already have your "templates" written that way and this needs to be done "yesterday". Otherwise, I think switching to a templating system would be faster, even in the short run.

Re: Injecting local variables into a template
by wfsp (Abbot) on Feb 06, 2008 at 06:13 UTC
    One way is to put your sub into a module and import the sub into your script. See Simple Module Tutorial for more information.
    #!/bin/perl5 use strict; use warnings; use lib qw{local/lib}; use Article qw{article_layout}; layout(); sub layout { #... my ($headline, $body, $url) = qw{one two three}; article_layout($headline, $body, $url); }
    package Article; use strict; use warnings; use Exporter; use vars qw($VERSION @ISA @EXPORT_OK); $VERSION = 1.00; @ISA = qw(Exporter); @EXPORT_OK = qw(article_layout); sub say { print qq{$_[0]\n}; } sub article_layout { my ($title, $body, $url) = @_; print <<HEADER; header stuff HEADER say $title; say $body; say $url; print <<FOOTER; footer stuff FOOTER } 1;
    output:
    header stuff one two three footer stuff

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://666473]
Approved by wfsp
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: (3)
As of 2025-06-21 10:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.