Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
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 examining the Monastery: (2)
As of 2024-06-20 21:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.