Adding custom statement to TT generated code

miyagawa on 2007-05-08T08:21:22

Investigating the UTF-8 on/off performance issues for work. Template::Stash::ForceUTF8 does utf8_on calls to all stash variables, which could be crucial to perfomance to the large-scale site like ours.

Looking through TT source code, I came up with the simple hack to add 'use encoding "utf-8"' to the generated code by TT. This solves the utf-8 bytes and string concatination (auto-upgrades from latin-1), and could be a good example to add custom perl statement to the TT generated code in general.

use Template;
use Template::Parser;
my $tt = Template->new({
    PARSER => Template::Parser->new({
        FACTORY => "Template::Directive::WithEncoding"
    }),
});
 
package Template::Directive::WithEncoding;
use base 'Template::Directive';

sub template { my $self = shift; my $code = $self->SUPER::template(@_); return qq(use encoding "utf-8";\n$code); }


Similary you can write the following code to do array push, instead of string concatination for each TT statement and do join the array at last. I'm skeptical how this technique could be useful in Perl, as compared to JavaScript or Python, where string concatination is slower than array expansion.

use Template;
use Template::Parser;

$Template::Directive::OUTPUT = 'push @output, ';

my $tt = Template->new({ PARSER => Template::Parser->new({ FACTORY => "Template::Directive::ArrayPush", }), });

package Template::Directive::ArrayPush; use base 'Template::Directive';

sub template { my $self = shift; my $code = $self->SUPER::template(@_);

# @output stuff $code =~ s|^sub {|sub {\n my \@output;|; $code =~ s|(return \$output;\s*\}\s*)$|return join '', \@output;\n}|;

return $code; }