Alan Evans wrote:
> I am new to Template Toolkit so please excuse me if I am asking a
> rudimentary question but what about a PROMPT directive that when used
> with tpage or ttree would allow dynamic content to be queried from the user.

Hi Alan,

Yes, that's something I've wanted myself from time to time.

TT2 doesn't allow you to plugin new directives, so it would require a rather
treacherous hack through the parser grammar.  To be honest, I wouldn't
recommend it - it's no fun.

TT3 is a different matter.  Adding new directives is much simpler.
Furthermore, the new TT3 architecture makes it easy to figure out what
variables are used in a template (or templates).  I was planning to add an
option to the TT3 replacements for tpage/ttree that will automatically prompt
you for missing values.

e.g. processing a template like this:

     Hello [% name %]

Would prompt you:

     Enter a value for 'name':

So the short answer is yes: something like that is in the pipeline, but it's
not here now.

> [% PROMPT suffix "Suffix" “dc=example,dc=com” %]

[...]

> I would consider implementing this myself as a plugin but I am having
> trouble figuring out where to begin.

I think the best you could hope for in TT2 would be a plugin that implements
a function that you can call to handle the prompting.  e.g.

     [% USE Prompt %]     # load Template::Plugin::Prompt

     [% Prompt("suffix", "Suffix", "dc=example.dc=com") %]

One inconvenience is that you must specify the quoted name of the variable,
e.g. Prompt("suffix", ...) rather than Prompt(suffix, ...).

The plugin init() method would need to return a closure that implements the
prompt function.  It would need to capture a reference to the stash so that
it can get/set the variable value.  Something like this perhaps (untested):

     sub init {
         my ($self, $context) = @_;
         my $stash = $context->stash;

         return sub {
             my ($varname, $prompt, $default) = @_;
             my $value = $stash->get($varname);

             unless (defined $value) {
                 print $prompt, ': ';
                 chomp($value = <STDIN>);
                 $stash->set($varname, $value);
             }
             return $value;
         }
     }

There's some more info on writing plugins here:

     http://tt2.org/docs/modules/Template/Plugin.html

> Ideally PROMT would implement the following kinds of features.
>   - allow specification of prompt text
>   - specification of a separator character e.g. PROMPT "FOO" "default"
> ">>" gives: FOO [default]>> or  PROMPT "BAR?" gives: BAR? (no extra
> separator value)
>   - allow default values to be used with empty responses
>   - selectively allow or disallow null values
>   - looping or multi-line responses e.g. "Enter a list of e-mail
> addresses, enter '.' to end input" or similar
>   - limits for looping (min 1, max 5 etc)
>   - input validation e.g. string, integer, double, regex, list of
> acceptable values

Something else that I've planned for TT3 (but not yet implemented) is a way
to declare metadata and/or assertions for variables.  Maybe something like this:

     [?  SCHEMA
            suffix = {
               type       = 'text',
               default    = 'dc=example.dc=com'
               prompt     = 'Suffix'
               min_length = 10
            }
            main = {
               # ...etc...
            }
     ?]

Or declared separately as a TT option:

     my $tt3 = Template3->new(
         schema => {
             suffix => {
                 ...
             },
             mail => {
                 ...
             },
         },
     );

The generic schema declaration can then be used to:

     * optimise the compiled templates. e.g. if the SCHEMA declares that 'user'
       is always a My::User object then we can pre-resolve user.XXX dotops
       as method calls, rather than checking the type of 'user' as runtime.

     * run pre-processing assertions to ensure that the data you've passed to
       the template conforms to the scheme (i.e. 'user' is actually a My::User
       object)

     * store any other variable metadata (like the prompt, etc) that can be
       used by ttree, tpage, etc.,

So again, that's something that's likely to appear in the future.  For now,
though, I think the TT2 plugin would be your best bet if you want to keep
everything self-contained in templates.  Otherwise, you could handle the
user prompting in a Perl script that prepares the data first and then
processes the template(s).

Cheers
A

_______________________________________________
templates mailing list
[email protected]
http://mail.template-toolkit.org/mailman/listinfo/templates

Reply via email to