Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Getting all used parameters from a Template::Toolkit template

by Corion (Pope)
on Mar 11, 2009 at 08:12 UTC ( #749813=perlquestion: print w/replies, xml ) Need Help??

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

I have a basic question, but so far haven't found the answer in the Template Toolkit documentation.

I want to find a list of all parameter names that are (possibly) used in a template. For example:

Name: [% user_name %] Password: [% user_pass %]

should return me a list of (say)

my @items = find_used_template_parameters($template); is_deeply \@items, [qw[ user_name user_pass ]];

You're asking why I would want something like that. This would make it very, very convenient while developing a CRUD application to have a customized template that still accomodates for new fields becoming available without requiring the HTML forms to keep up. I could introduce an additional section that lists all "user defined fields" that haven't been mentioned somewhere else in the template already. For example, let's assume that a new template parameter, user_email, became available. I would then want the following template:

Name: [% user_name %] Password: [% user_pass %] [% IF has_unused_fields('/^user_/') %] [% list_unused_fields('/^user_/') %] [% END %]

produce the following, unsightly yet functional output:

Name: Corion Password: Secret user_email:

I want list_unmentioned_parameters to list only the parameters that have not been mentioned in the template at all, presumably because the designer has not placed them in a location aesthetically pleasing. Bonus points if the calling application can provide a list of parameters that are to be checked, so not all parameters passed to the template need to be output.

I hope that this kind of template introspection is somehow possible, or at least, it would be very nice if it were so. I'm not wed to Template Toolkit, so if any other templating system provides this kind of introspection, I'm quite willing to look into it.

Replies are listed 'Best First'.
Re: Getting all used parameters from a Template::Toolkit template
by DrHyde (Prior) on Mar 11, 2009 at 10:21 UTC

    I'd look at tie()ing the \%hashref that you're passing to Template->process(), so that it keeps track for you of what has (and therefore what has not) been accessed, via the FETCH method, and makes the results available through some "magic" key, as a first cut.

    If it works (ie if TT doesn't break the tieing) then you could think about ways of tidying it up and turning the magic key into a method call on an object that wraps the tied hash. For examples of tieing and blessing at the same time, see DBM::Deep and Data::Transactional.

      This is a good idea, but I fear from the output of the Stash code in 749819 that Template::Toolkit first builds a complete (in-memory) copy of the available data in its stash and then processes the template from that. But it sure is worth a try.

Re: Getting all used parameters from a Template::Toolkit template -- try #2
by assemble (Friar) on Mar 11, 2009 at 14:05 UTC

      I was going to recommend something similar. Your real problem is that you need code that keeps track of which variables to access. I don't know if subclassing will be able to get you there though, it depends on how TT was written. If the code is structured poorly subclassing will get you no where.

Re: Getting all used parameters from a Template::Toolkit template
by jethro (Monsignor) on Mar 11, 2009 at 12:54 UTC

    Seems HTML::Template has such a thing:

    1) To return a list of parameters in the template : my @parameter_names = $self->param();
Re: Getting all used parameters from a Template::Toolkit template
by assemble (Friar) on Mar 11, 2009 at 13:29 UTC

    Update: I just re-read the post and realized this isn't what you would want, nevermind

    Another option is to shove all of your form values into a hashref and send that to TT, like this:

    my $form_fields = { user_name => 'username', user_pass => 'userpass', other_field => 'value', };

    Later on, pass this into TT as a var named 'form' or something like that. Your template code would be something like:

    [% FOREACH field IN form %] [% field.key %]: [% field.value %] [% END %]

      And how would this solution know that the template has used user_name already and not output it?

        I missed that part of the original post--it wouldn't help with what you want. Oops
Re: Getting all used parameters from a Template::Toolkit template
by Anonymous Monk on Mar 11, 2009 at 08:21 UTC

      This only tells me what variables have been passed to the template, but not what variables the template actually uses:

      #!perl -w use strict; use Template; use Template::Plugin::Stash; my $t = Template->new(); my $tmpl = <<'TMPL'; Name: [% user_name %] Password: [% user_password %] --- [% USE Stash %] [% USE Dumper %] [% Dumper.dump( Stash.stash() ) %] --- TMPL $t->process( \$tmpl, { user_name => 'Corion', user_password => 'secret +', user_email => ''}, \my $output ); print $output;


      C:\Projekte>perl -w Name: Corion Password: secret --- [% Dumper.dump( Stash.stash() ) --- C:\Projekte>perl -w Name: Corion Password: secret --- $VAR1 = { 'global' => {}, 'user_name' => 'Corion', 'user_password' => 'secret', 'user_email' => '' }; ---

      and user_email is listed there, even though it is not used in the template anywhere.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://749813]
Approved by GrandFather
Front-paged by DrHyde
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2019-10-16 17:54 GMT
Find Nodes?
    Voting Booth?