http://www.perlmonks.org?node_id=776064

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

Is there any way to access the complete stash within a Template Toolkit file? I'd like to do this: % my_process_fn('template.tt',stash) % I know this can be done with a Plugin, but can it be done more simply?

Replies are listed 'Best First'.
Re: Accessing the stash within a TT file
by ikegami (Patriarch) on Jun 30, 2009 at 15:45 UTC

    I presume you are talking about Catalyst's stash. TT doesn't know anything about Catalyst. Fortunately, Catalyst::View::TT passes the Catalyst object to TT as a variable (under the name Catalyst by default). You should be able to do [% Catalyst.stash.foo %]

    I'm just learning Catalyst now, so let me know if that doesn't work.

      "Stash" is actually a TT convention that Catalyst copied.
        Stash is actually a perl convention that TT copied :)

      Just to expand. The stash is exposed to the template at the top level (by default, in TT views, not necessarily in all views) so these are equivalent-

      [% Catalyst.stash.foo %] == [% foo %]

      And unless you're using the TT::Site view helper/generator or have modified your CATALYST_VAR yourself in your view configuration, then c will be the default Cat context/app object-

      [% c.stash.foo %] == [% foo %]

      I have mixed feelings about using Catalyst v c in the templates. It's nice to be explicit but at the same time it crowds template code and if one can get used to $r in modperl, c seems fine.

      Thanks for the response. Much appreciated.
      In this particular project, I'm not using Catalyst, just plain vanilla Template Toolkit. Would be very interested how access to the stash is accomplished under that scenario.
      I can take a look at the Catalyst s/c to see what they do. I'm curious about it being a circular ref.
Re: Accessing the stash within a TT file
by thunders (Priest) on Jun 30, 2009 at 18:04 UTC
    Yes, you can directly acess the stash from a PERL block.
    use Template; my $tt = Template->new({EVAL_PERL => 1}); my $vars = { x => [1,2,3] }; my $text = q{ [%PERL%] use Data::Dumper; print STDOUT Dumper $stash [%END%] }; $tt->process(\$text,$vars);
    output:
    $VAR1 = bless( { 'template' => bless( { '_DEFBLOCKS' => {}, '_BLOCK' => sub { "DUMMY" }, 'modtime' => 1246384891, 'name' => 'input text', '_HOT' => 1 }, 'Template::Document' ), 'global' => {}, 'inc' => sub { "DUMMY" }, 'x' => [ 1, 2, 3 ], 'dec' => sub { "DUMMY" }, 'component' => $VAR1->{'template'}, '_DEBUG' => 0, '_PARENT' => bless( { 'global' => $VAR1->{'global'}, 'inc' => $VAR1->{'inc'}, '_DEBUG' => 0, 'dec' => $VAR1->{'dec'}, '_PARENT' => undef }, 'Template::Stash::XS' ) }, 'Template::Stash::XS' );

      That being said, what exactly are you trying to do? It's already possibly to PROCESS a file from another TT file. Is there something specific you need to do that PROCESS does not do?

      If you simply need to modify existing stash variables, or add new stash variables, you could probably get away with a TT wrapper file that manipulates variables and then calls PROCESS on another tt file supplied as an argument.

Re: Accessing the stash within a TT file
by juster (Friar) on Jun 30, 2009 at 16:15 UTC

    Are you sure you can't just use the PROCESS directive to process another template file?

    The Template::Stash object appears to be accessible like this:

    my $tt = Template->new(); my $stash = $tt->context()->stash();

    Though I imagine you'd want to weaken the reference before passing it to process with weaken from Scalar::Util. The plugin might be a more elegant solution... [% PROCESS ... %] even more so.