ホーム > perl > Template::Stash::Filters(TTのStashで複数のfilterを実行)

Template::Stash::Filters(TTのStashで複数のfilterを実行)

  • 投稿者: chiba
  • 2007/6/18 月曜日 2:23:32
  • perl

前回のエントリーでTemplate::Stash::EscapeHTMLByCaseというのを作ったわけですが、こうやっていろいろStashで対応しようとすると、Template::Stash::ForceUTF8も使ってるから使えない~とかが発生する。

というのも、TTのSTASHは一つのObjectしか渡せないからだ。これには多分いろいろ理由があって、Template::Stash::Contextのようにgetのアルゴリズム自体に手を入れてる場合どうすんの?ってことだからだと思う。

ただ、EscapeHTMLByCaseやForceUTF8なんかのように単にfilterを掛けたいだけであれば繋げたい。

というわけでTemplate::Stash::Filters作ってみました。

package Template::Stash::Filters;

use strict;
use Template::Config;
use base ($Template::Config::STASH);
our $VERSION = '0.01';

sub get {
    my ($self, @args) = @_;

  PRE_PROCESS:
    foreach my $filter (@{$self->{FILTERS}}) {
        if (!$filter->can('pre_process')) {
            next PRE_PROCESS;
        }
        $filter->pre_process(@args);
    }

    my $var = $self->SUPER::get(@args);

  FILTER:
    foreach my $filter (@{$self->{FILTERS}}) {
        if (!$filter->can('filter')) {
            next GET;
        }
        $var = $filter->filter($var);
    }

    return $var;
}

1;

__END__

Template::Stash::XXX系のモジュールを再利用できたらいいんだろうけど、$self->SUPER::getをhackする方法が分らなかったのでFilter実装モジュールも車輪の再発明。

Template::Stash::Filters::EscapeHTMLByCase

package Template::Stash::Filters::EscapeHTMLByCase;

use strict;
our $VERSION = '0.01';

use base qw(Class::Accessor);
__PACKAGE__->mk_accessors(qw(is_raw));

sub pre_process {
    my ($self, $args) = @_;

    if (is_this_raw(@{$args})) {
        $self->is_raw(1);
        strip_raw_specifier($args);
    }
    else {
        $self->is_raw(0);
    }

}

sub filter {
    my ($self, $var) = @_;

    if ($self->is_raw || ref $var) {
        return $var;
    }

    return html_filter($var);
}

sub html_filter {
    my $text = shift;
    for ($text) {
        s/&/&/g;
        s/</&;t;/g;
        s/>/&gt;/g;
        s/"/&quot;/g;
    }
    return $text;
}

sub is_this_raw {
    my @args = @_;

    if (ref $args[0] ne 'ARRAY') {
        return 0;
    }

    if ($args[0]->[0] ne 'RAW') {
        return 0;
    }

    return 1;
}

sub strip_raw_specifier {
    my $args = shift;

    splice @{$args->[0]}, 0, 2;
}

1;

pre_processを活用してます。

Template::Stash::Filters::ForceUTF8

package Template::Stash::Filters::ForceUTF8;

use strict;
our $VERSION = '0.01';

use base qw(Class::Accessor);
use Encode;

sub filter {
    my ($self, $var) = @_;

    return $var if ref $var;

    Encode::_utf8_on($var) unless Encode::is_utf8($var);
    return $var;
}

1;
__END__

で、使い方はこんな感じ


use Template;
use Template::Stash::Filters;
use Template::Stash::Filters::EscapeHTMLByCase;
use Template::Stash::Filters::ForceUTF8;

my $template = Template->new({
    STASH => Template::Stash::Filters->new(
        FILTERS => [
            Template::Stash::Filters::ForceUTF8->new,
            Template::Stash::Filters::EscapeHTMLByCase->new,
        ],
    ),
});

うーん、newへの引数が無いモジュールばっかなのでTemplate::Stash::Filters::がうっとうしいなぁ。useするのも面倒だし勝手にuseしちゃう方式つくってみるかなぁ。

まぁまた時間があったときにでも。

はてなブックマーク - Template::Stash::Filters(TTのStashで複数のfilterを実行)

コメント:0

コメントフォーム
入力した情報を記憶する

トラックバック:0

この記事のトラックバック URL
https://blog.everqueue.com/chiba/2007/06/18/13/trackback/
トラックバックの送信元リスト
Template::Stash::Filters(TTのStashで複数のfilterを実行) - へぼい日記 より

ホーム > perl > Template::Stash::Filters(TTのStashで複数のfilterを実行)

検索
フィード
メタ情報

ページの上部に戻る