Travis Basevi wrote:
 > Yes, I know that solution,

Sorry, I totally missed that in your original message.

 > but lets say the text comes from a database
 > or some other source rather than being hardcoded in the template. Is
 > there a more general/correct solution than something along the lines of:
 >
 > b.replace('_err_', a.replace('$','\$'));

Ah, I see.  I thought that was easy work for $50 million!

I think Dave's got it right in terms of counting the backslashes.

     b.replace('_err_', a.replace('$','\\\$'));

But I would be inclined to add a custom virtual method that does it all
in Perl space.  I typically use '.format' for this kind of thing:

     package My::Template;
     use base 'Template';

     sub new {
         my $class   = shift;
         my $self    = $class->SUPER::new(@_);
         my $context = $self->context;

         $context->define_vmethod(
             item => format => sub {
                 sprintf($_[1], $_[0])
             }
         );

         return $self;
     }

     package main;
     my $tt = My::Template->new(...);
     ...etc...

Then you can write:

     [% a = 'this problem will cost me $50 million to fix';
        b = 'WARNING: %s';
        a.format(b);
     %]

I recall going to add this as a core virtual method at some point in
the past, but I couldn't decide if it made more sense as b.format(a)
or a.format(b).  I guess I must have stalled before reaching any
decision.

Now that I look at it again, I think it makes more sense as b.format(a),
otherwise you're limited to only one argument.  But for that matter, it
should probably just be called .sprintf

     [%  format = "hello %s, the time is %s on %s";
         format.sprintf(username, time, date)
     %]

Then the implementation is even simpler:

     $context->define_vmethod(
         item => format => sub {
             sprintf(shift, @_)
         }
     );

The other possibility is to use the existing format filter.

     [% a | format(b) %]

But be warned that it's a line-oriented filter so if your 'a' has any
newlines in it then the filter will be applied to each line:

     [% a = "Oh Noes!\nThis will cost me $50 million to fix";
        b = "WARNING: %s";
        a | format(b);
     %]

This will output:

     WARNING: Oh Noes!
     WARNING: This will cost me $50 million to fix

HTH
A

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

Reply via email to