Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Injecting local variables into a template

by MistaMuShu (Beadle)
on Feb 06, 2008 at 05:23 UTC ( #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, 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 '', but with the local variables $headline, $body, and $url available to the script. '' would then use these variables to print out the final layout.


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


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;
    (my $headline), $body, $url;
    but you want
    my ($headline, $body, $url);

    The solution requiring minial change is,

    # sub layout { local our ($headline, $body, $url) = @_; do ''; } layout($headline, $body, $url);
    # 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;
    header stuff one two three footer stuff

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://666473]
Approved by wfsp
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2023-03-23 05:32 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (60 votes). Check out past polls.