テンプレートエンジンの移行 Changing Template Engine YAPC::Asia 2010 Tokyo Takatsugu Shigeta
@comewalk #sixapartkk #typepad
Q. Have you used any template engine?
Q. Which engine?
HTML::Template Template  Text::MicroTemplate Tenjin MENTA::Template Mojo::Template MTML Text::ClearSilver Text::Xslate
Migrating from HTML::Template to Template Toolkit
HTML::Template
<TMPL_VAR NAME=foo> TMPL_VAR, TMPL_IF, TMPL_UNLESS, TMPL_ELSE, TMPL_LOOP, TMPL_INCLUDE
  use  HTML::Template; my   $tmpl   = HTML::Template-> new (filename =>  'sample_html_template.tmpl' ); $tmpl ->param( 'home' ,  '/home/shigeta' ); $tmpl ->param( 'path' ,  'path/to' ); say   $tmpl ->output;
  <body> My Home Directory is  < TMPL_VAR   NAME = HOME > <br /> My Path is set to  < TMPL_VAR   NAME = PATH > </body>
Template Toolkit
[% foo %] GET, IF, UNLESS, ELSE, FOR, INCLUDE (and others )
  use  Template; my   $tmpl  = Template-> new ; my   $vars  = {      'home'  =>  '/home/shigeta' ,      'path'   =>  'path/to' , }; my   $output ; $tmpl ->process( 'sample_template_toolkit.tt' ,  $vars ,  \$output ); say  $output;
  <body> My Home Directory is  [% home %] <br /> My Path is set to  [% path %] </body>
History
 
Motivation
* borrow their templates * unnecessary code on handler
borrow their templates
unnecessary code on handler sub handler {      $param->{'user_id'} = $user->id;      $param->{'blog_id'} = $blog->id;      $app->build_page(&quot;foobar.tmpl&quot;, $param); }
unnecessary code on handler sub handler {      $param->{'user_id'} = $user->id;      $param->{'blog_id'} = $blog->id;      $param->{'user_name'} = $user->name;      $param->{'blog_url'} = $blog->url;      $app->build_page(&quot;foobar.tmpl&quot;, $param); }
schedule
This graph is rough estimates :)
operations
run convert script
TMPL_VAR -> [% foo %] TMPL_IF -> [% IF %] TMPL_UNLESS -> [% UNLESS %] TMPL_ELSE ->[%  ELSE %] TMPL_LOOP -> [% FOR %] TMPL_INCLUDE -> [% INCLUDE%] MT_TRANS ->  [% |loc %]foo[% END %]
  $ converter <filename> <html>       :       : </html>
$ data  =~  s! (<(/?)TMPL_([^\s>]+)([^>]*)>) ! munge($1, $2, $3, $4) !ge ; $data  =~  s! <MT_TRANS ([^>]+)> ! munge_locale($1) !ge ;
Tips
* Don't use reserved keywords * Don't use camel case variable name * Don't use underscore at first letter like _foo * MT_TRANS multi params
Don't use reserved keywords <TMPL_VAR NAME=TAGS> [% tags %]
Don't use reserved keywords <TMPL_VAR NAME=TAGS> [% tags %]          # NG [%  GET  tags %] # OK
Don't use camel case variable name <TMPL_VAR NAME=USERNAME> [% username %]    # Syntax is OK. But didn't see user name :(
Don't use camel case variable name <TMPL_VAR NAME=USERNAME> [% username %] # see the handler code $param->{ UserName } = $user->name;
Don't use camel case variable name <TMPL_VAR NAME=USERNAME> [% username %]  # NG $param->{UserName} = $user->name; [%  UserName  %]    # OK :)
Don't use underscore at first letter like _foo Any key in a hash which starts with a '_' or '.' character will be considered private and cannot be evaluated or updated from within a template. via Template::Manual::Variables
MT_TRANS multi params   [error] processing openid_login.tt: file error - parse error - openid_login.tt line 312:  unexpected end of input
MT_TRANS multi params   < MT_TRANS phrase= &quot;<a href=&quot;[_1]&quot;>[_2]</a> is the next category.&quot;  params= &quot;<$MTCategoryArchiveLink$>%%<$MTCategoryLabel$>&quot; >
sequence
 
TypePad::View::TT A wrapper class for TT which  bridges the gap between HTML::Template and Template Toolkit
  use Template; my $tmpl = Template->new; my $vars = {      'home' => '/home/shigeta',      'path' => 'path/to', }; my $output; $tmpl->process('sample_template_toolkit.tt', $vars, \$output); say $output;
  use HTML::Template; my $tmpl = HTML::Template->new(filename => 'sample_html_template.tmpl'); $tmpl->param('home', '/home/shigeta'); $tmpl->param('path', 'path/to'); say $tmpl->output;
  use  TypePad::View::TT ; my $tmpl =  TypePad::View:TT ->new(filename => 'sample_html_template.tmpl'); $tmpl->param('home', '/home/shigeta'); $tmpl->param('path', 'path/to'); say $tmpl->output;
  package TypePad::View::TT; sub new {      $self->{engine} = Template->new;  } sub param {      my ($key, $val) = @_;      $self->{var}->{$key} = $val;    } sub process {      $self->{engine}->process; } *output = \&process;
sequence [after]
 
Benchmark
compare processing speed Template:           0.0173818 HTML::Template: 0.0157874 using Time::HiRes CentOS 4.6 (64bit), Perl v5.8.9, $Template::VERSION 2.15 $HTML::Template::VERSION 2.8
in near future, Text::Xslate
  Embrace Change -  Extreme Programming
Questions?
Thank you for your attention!

Changing Template Engine

  • 1.
    テンプレートエンジンの移行 Changing TemplateEngine YAPC::Asia 2010 Tokyo Takatsugu Shigeta
  • 2.
  • 3.
    Q. Have youused any template engine?
  • 4.
  • 5.
    HTML::Template Template  Text::MicroTemplateTenjin MENTA::Template Mojo::Template MTML Text::ClearSilver Text::Xslate
  • 6.
    Migrating from HTML::Templateto Template Toolkit
  • 7.
  • 8.
    <TMPL_VAR NAME=foo> TMPL_VAR,TMPL_IF, TMPL_UNLESS, TMPL_ELSE, TMPL_LOOP, TMPL_INCLUDE
  • 9.
      use HTML::Template; my $tmpl = HTML::Template-> new (filename => 'sample_html_template.tmpl' ); $tmpl ->param( 'home' , '/home/shigeta' ); $tmpl ->param( 'path' , 'path/to' ); say $tmpl ->output;
  • 10.
      <body> MyHome Directory is  < TMPL_VAR NAME = HOME > <br /> My Path is set to  < TMPL_VAR NAME = PATH > </body>
  • 11.
  • 12.
    [% foo %]GET, IF, UNLESS, ELSE, FOR, INCLUDE (and others )
  • 13.
      use Template; my $tmpl = Template-> new ; my $vars = {      'home' => '/home/shigeta' ,      'path' => 'path/to' , }; my $output ; $tmpl ->process( 'sample_template_toolkit.tt' , $vars , \$output ); say $output;
  • 14.
      <body> MyHome Directory is [% home %] <br /> My Path is set to [% path %] </body>
  • 15.
  • 16.
  • 17.
  • 18.
    * borrow theirtemplates * unnecessary code on handler
  • 19.
  • 20.
    unnecessary code onhandler sub handler {      $param->{'user_id'} = $user->id;      $param->{'blog_id'} = $blog->id;      $app->build_page(&quot;foobar.tmpl&quot;, $param); }
  • 21.
    unnecessary code onhandler sub handler {      $param->{'user_id'} = $user->id;      $param->{'blog_id'} = $blog->id;      $param->{'user_name'} = $user->name;      $param->{'blog_url'} = $blog->url;      $app->build_page(&quot;foobar.tmpl&quot;, $param); }
  • 22.
  • 23.
    This graph isrough estimates :)
  • 24.
  • 25.
  • 26.
    TMPL_VAR -> [%foo %] TMPL_IF -> [% IF %] TMPL_UNLESS -> [% UNLESS %] TMPL_ELSE ->[%  ELSE %] TMPL_LOOP -> [% FOR %] TMPL_INCLUDE -> [% INCLUDE%] MT_TRANS -> [% |loc %]foo[% END %]
  • 27.
      $ converter<filename> <html>      :      : </html>
  • 28.
    $ data =~ s! (<(/?)TMPL_([^\s>]+)([^>]*)>) ! munge($1, $2, $3, $4) !ge ; $data =~ s! <MT_TRANS ([^>]+)> ! munge_locale($1) !ge ;
  • 29.
  • 30.
    * Don't usereserved keywords * Don't use camel case variable name * Don't use underscore at first letter like _foo * MT_TRANS multi params
  • 31.
    Don't use reservedkeywords <TMPL_VAR NAME=TAGS> [% tags %]
  • 32.
    Don't use reservedkeywords <TMPL_VAR NAME=TAGS> [% tags %]          # NG [% GET tags %] # OK
  • 33.
    Don't use camelcase variable name <TMPL_VAR NAME=USERNAME> [% username %]    # Syntax is OK. But didn't see user name :(
  • 34.
    Don't use camelcase variable name <TMPL_VAR NAME=USERNAME> [% username %] # see the handler code $param->{ UserName } = $user->name;
  • 35.
    Don't use camelcase variable name <TMPL_VAR NAME=USERNAME> [% username %]  # NG $param->{UserName} = $user->name; [% UserName %]    # OK :)
  • 36.
    Don't use underscoreat first letter like _foo Any key in a hash which starts with a '_' or '.' character will be considered private and cannot be evaluated or updated from within a template. via Template::Manual::Variables
  • 37.
    MT_TRANS multi params  [error] processing openid_login.tt: file error - parse error - openid_login.tt line 312: unexpected end of input
  • 38.
    MT_TRANS multi params  < MT_TRANS phrase= &quot;<a href=&quot;[_1]&quot;>[_2]</a> is the next category.&quot; params= &quot;<$MTCategoryArchiveLink$>%%<$MTCategoryLabel$>&quot; >
  • 39.
  • 40.
  • 41.
    TypePad::View::TT A wrapperclass for TT which  bridges the gap between HTML::Template and Template Toolkit
  • 42.
      use Template;my $tmpl = Template->new; my $vars = {      'home' => '/home/shigeta',      'path' => 'path/to', }; my $output; $tmpl->process('sample_template_toolkit.tt', $vars, \$output); say $output;
  • 43.
      use HTML::Template;my $tmpl = HTML::Template->new(filename => 'sample_html_template.tmpl'); $tmpl->param('home', '/home/shigeta'); $tmpl->param('path', 'path/to'); say $tmpl->output;
  • 44.
      use TypePad::View::TT ; my $tmpl = TypePad::View:TT ->new(filename => 'sample_html_template.tmpl'); $tmpl->param('home', '/home/shigeta'); $tmpl->param('path', 'path/to'); say $tmpl->output;
  • 45.
      package TypePad::View::TT; subnew {      $self->{engine} = Template->new;  } sub param {      my ($key, $val) = @_;      $self->{var}->{$key} = $val;    } sub process {      $self->{engine}->process; } *output = \&process;
  • 46.
  • 47.
  • 48.
  • 49.
    compare processing speedTemplate:           0.0173818 HTML::Template: 0.0157874 using Time::HiRes CentOS 4.6 (64bit), Perl v5.8.9, $Template::VERSION 2.15 $HTML::Template::VERSION 2.8
  • 50.
    in near future,Text::Xslate
  • 51.
      Embrace Change-  Extreme Programming
  • 52.
  • 53.
    Thank you foryour attention!