Skip to content

Instantly share code, notes, and snippets.

@anazawa
Created March 7, 2012 10:40
Show Gist options
  • Select an option

  • Save anazawa/1992461 to your computer and use it in GitHub Desktop.

Select an option

Save anazawa/1992461 to your computer and use it in GitHub Desktop.
CGI::Application で Text::MicroTemplate::Extended を使う
# 目的: CGI::Application のテンプレートエンジンを Text::MicroTemplate::Extended で置き換える
# 方法: MyApp::View::MT で HTML::Template との API の差を吸収する
# 結果: できない -> https://gist.github.com/1993446
# 参考:
# https://metacpan.org/module/CGI::Application#load_tmpl-
# https://metacpan.org/module/Text::MicroTemplate::Extended
# lib/MyApp.pm
# html_tmpl_class で load_tmpl が呼ぶコンストラクタを変更する。
sub setup {
my $self = shift;
$self->html_tmpl_class( 'MyApp::View::MT' );
$self->{__CURRENT_TMPL_EXTENSION} = q{}; # 拡張子は T::M::Extended が補完する。
return;
}
# lib/MyApp/Controller.pm
sub run_mode {
my $self = shift;
my $template = $self->load_tmpl( 'run_mode' ); # run_mode.mt が読み込まれる
return $template->render; # よく考えると @args を渡せない
}
# いまいち
sub another_run_mode {
my $self = shift;
my $template = $self->load_tmpl;
return $template->render( 'another_run_mode', @args );
}
# lib/MyApp/View.pm
package MyApp::View;
use strict;
use warnings;
use parent 'Exporter';
sub import {
my $caller = scalar caller;
$caller->add_callback(
load_tmpl => sub {
my ( $self, $ht_params, $tmpl_params ) = @_;
# Text::MicroTemplate::Extended->new に渡される
$ht_params->{use_cache} = 1;
# T::M::Extended の template_args オプションを変更する
# $ht_params->{template_args} と重複する
$tmpl_params->{c} = $self;
},
);
return;
}
1;
# lib/MyApp/View/MT.pm
package MyApp::View::MT;
use strict;
use warnings;
use parent 'Text::MicroTemplate::Extended';
use Carp;
use Scalar::Util qw(refaddr);
# load_tmpl で指定されたファイル名を保存する
my %template_of;
# load_tmpl はファイル名、ファイルハンドル、スカラー参照を受けとる。
# この方法ではファイル名しか受けつけない。
sub new {
my $class = shift;
my %option = @_;
my $template = delete $option{filename};
my $include_path = delete $option{path};
$option{include_path} ||= $include_path;
my $self = $class->SUPER::new( %option );
my $id = refaddr( $self );
$template_of{ $id } = $template;
return $self;
}
sub render {
my $self = shift;
my $template = shift || $template_of{ refaddr( $self ) };
my @args = @_;
return $self->SUPER::render( $template, @args );
}
# T::M::Extended (しかし名前が長いな) の template_args オプションを変更する。
# このメソッドがないと html_tmpl_class でこのクラスを指定できないので、
# 適当にでっちあげた。(無理矢理たるゆえん)
sub param {
my $self = shift;
my @data = @_;
my $args = $self->template_args;
if ( @data ) {
if ( @data == 1 ) {
return $args->{ $data[0] };
}
elsif ( @data % 2 == 0 ) {
%{ $args } = ( %{ $args }, @data );
return;
}
else {
croak 'Odd number of elements passed to param().';
}
}
return keys %{ $args };
}
sub DESTROY {
my $self = shift;
delete $template_of{ refaddr( $self ) };
$self->SUPER::DESTROY( @_ );
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment