Blue Eyed Devil wrote:
> Maybe other people can think of other uses for this to where maybe the
> developers of TT would consider implementing this relatively simple feature.
Hi Milan,
It may be a relatively simple feature, but implementing it is decidedly
non-trivial :-)
It's not possible in TT2 without hacking a new parser grammar (see
parser/Parser.yp in the TT2 dist) and/or a new Template::Directives.
Even then, I think you would be very limited in what you can do.
The lack of flexibility in the TT2 parser is one of the main things to change
in TT3. I've completely re-written the parser (several times, actually) to
provide much greater flexibility in a) the range of languages that it can
parse, and b) what you can do with the output that it generates.
The TT3 parser compiles the template to an AST (Abstract Syntax Tree). The
usual modus operandi for TT2 is to compile templates to Perl code. You
achieve that in TT3 by having a Perl generator walk the AST and convert it
to Perl code. However, the TT3 AST tree is also directly executable (i.e.
given any AST node, you can call $node->value($context) to evaluate it in a
given context) so you don't need to convert it to Perl if you don't want to.
Once you've got the parsed template in AST form, you can do pretty much
anything you like with it. For example, you can transform it to a target
language (e.g. Perl, Parrot, Javascript, etc), you can pretty-print it as HTML
for debugging, or you can analyse it to trace static dependencies on
variables, templates, etc. Now, you can't trace all dependencies because of
the dynamic nature of TT wrt to variables (e.g. foo.$var) and templates
(INCLUDE "example/$file"), but you can locate the static resources referenced
in a template (and recursively, any templates that it depends on) and at the
very least detect the use of dynamic resources and track what variables
they rely on (e.g. 'var' in 'foo.$var' and 'file' in 'example/$file'. So you
can certainly get a useful 90% of the way there (or 100% if you don't use
dynamics).
I haven't implemented this last bit yet, but it's next on my TODO list (well,
OK, it's actually item #3, but close enough). I'm planning to implement a
partial evaluation method for the AST node that will evaluate those parts of
the tree that it can and leave the rest unresolved. Something like this:
use Template v3; # RSN
# fetch a template
my $template = Template->template('example.tt3');
# partially process template
$template->partial( name => 'Arthur Dent', site => $my_site );
# now all 'name' and 'site' references have been resolved (except any
# like 'site.$thing' where we haven't got a 'thing' yet)
As a side-effect, performing a partial evaluation will also detect the use
of any variables, templates or other resources that can't be resolved yet
(the free variables, or more generally, free resources).
The end result is that templates will be able to tell you what parameters
they're expecting to be fed. You could then prompt a user to enter values for
these variables, for example. Something like this:
# see what variables are left to be filled
my @free_vars = $template->free_var_names;
# prompt the user to provide values
my $vars = { };
foreach my $var (@free_vars) {
$vars->{ $var } = prompt("$var: ");
}
# now process template
print $template->expand($vars);
Does that sound like the kind of thing you're after?
Most of the parser and AST code is written, but the AST visitors and partial
evaluation are still TODO. I'm hoping to get that done in the next few weeks
but realistically, it'll be at least another month or two before there's
enough of TT3 working to play with. So although it doesn't help you much now,
it may be reassuring to know that there'll be more scope to monkey around with
the template innards in TT3.
A
_______________________________________________
templates mailing list
[email protected]
http://mail.template-toolkit.org/mailman/listinfo/templates