Movable Type/第6回MTプラグイン勉強会 - グローバルフィルターを使ったエントリー内変数の再構築時置換、再構築呼び出し http://www.ark-web.jp/sandbox/wiki/333.html

Movable Type/第6回MTプラグイン勉強会 - グローバルフィルターを使ったエントリー内変数の再構築時置換、再構築呼び出し

第6回はグローバルフィルターを使ってエントリー内に独自に定義した変数を再構築時に置換する方法、また、再構築をプラグインから呼び出す方法をとりあげます。A-Formではエントリー内に埋め込んだ変数(<!--aform001-->など)を再構築時に定義したフォームに置き換えるのに使っています。

[edit]

動画(Ustream)

勉強会の模様をアップしました。

Live .TV show provided by Ustream

Ustreamのチャンネルはこちら。
http://www.ustream.tv/channel/mt%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E5%8B%89%E5%BC%B7%E4%BC%9A

[edit]

ご感想・ご質問など

ご感想、ご質問などあればお気軽にどうぞ。頂けるととても励みになります。


[edit]

勉強会で解説したプログラムコードのダウンロード

fileQuote.zip

単に対象のファンクションタグの出力を‘’で囲むだけのプラグインです。
グローバルフィルターの実装例としてご参考ください。

[edit]

ネタ

[edit]

日時

[edit]

グローバルフィルターを使って再構築時にエントリー内の独自変数を置換する

グローバルフィルターを使って再構築時にエントリー内の独自変数を置換します。グローバルフィルターを使うため、エントリーの保存の際にも定義した置換処理が走ります。

[edit]

グローバルフィルター作成の基礎的なこと

グローバルフィルターはプラグインの一種(または一機能)として実装します。フィルタープラグインの一種です。(Six Apart - 技術情報提供ブログ: プラグイン開発のためのファーストステップ

グローバルフィルタープラグインの作成方法はSix Apart - 技術情報提供ブログ: フィルター プラグインの開発に詳説されています。ここでは、技術情報提供ブログの方法とは少し変えてMT::Pluginのregistryメソッドを利用して、グローバルフィルターを定義する方法をとりあげます。

MT::Plugin->registryを使ったグローバルフィルターの定義は次のようになります。

sub init_registry {
    my $plugin = shift;
    $plugin->registry({
        tags => {
            modifier => {
                属性名 => ハンドラ(関数リファレンス),
            },
        },
    });
}

例えば、MTテンプレートのファンクションタグ(何らかの文字列を出力するタグ)に属性quote="1"を指定すると出力する文字列全体を‘と’で囲むフィルターを作る場合、
属性名 quote 、ハンドラを _quote_strとするとregistryは

sub init_registry {
    my $plugin = shift;
    $plugin->registry({
        tags => {
            modifier => {
                quote => &_quote_str,
            },
        },
    });
}

sub _quote_str {
    # $textにフィルターを適用する文字列
    # $argに属性の値(quote="1"なら1)
    # $ctxにMT::Template::Contextオブジェクト
    # がそれぞれ渡される。
    my ($text, $arg, $ctx) = @_;

    # クォートした文字列を返す
    return '‘' . $text . '’';
}

となります。

これで、「ブログ記事の詳細」テンプレートなどで、例えば

<$MTEntryBody$>

<$MTEntryBody quote="1"$>

とすると、エントリー本文の箇所をMTが生成する時にこのグローバルフィルターが呼ばれて、エントリー本文を‘と’で囲んだ値にして返します。
この例ではquoteに指定する値で処理は分岐していないので、

<$MTEntryBody quote=""$>

といった指定でもフィルターは動作します。

[edit]

エントリー内変数の置換

エントリー内変数の置換は、グローバルフィルターのハンドラ内で置換処理を実装するだけです。
例えば、

<!-- Hello -->

というフォーマットの変数を定義して、これを「こんにちは」に変換するには、属性名 jp_hello、ハンドラ _jp_helloとすると次のようになると思います(動作未検証)。

sub init_registry {
    my $plugin = shift;
    $plugin->registry({
        tags => {
            modifier => {
                jp_hello => &_jp_hello,
            },
        },
    });
}

sub _jp_hello {
    my ($text, $arg, $ctx) = @_;

    $jp_hello_str = 'こんにちは';
    $text =~ s/<\!-- Hello -->/$jp_hello_str/og;
    return $text;
}

このようにグローバルフィルターで置換処理を行うメリットは次の通りです。

[edit]

再構築をプラグインから呼び出す

$app->rebuild_theseメソッドを使います。

http://www.movabletype.org/documentation/man/MT/App/CMS.html#%24app-%3Erebuild_these(%5C%25rebuild_set%2C_%25options)

my @entry_ids = qw(2 4 10);  # 再構築するエントリーIDを指定
my %param = map { $_ => 1 } @entry_ids; # ハッシュに変換
app->rebuild_these( \%param, how => NEW_PHASE ); # 再構築実行

how => NEW_PHASEを渡すことで再構築中の表示が返されます(rebuilding.tmplが直ちに読み込まれて返されます)

A-Formでは以下のように、rebuild_new_phaseというモードに再構築したいidと戻り先のmodeを指定してアクセスさせています。

        my $return_arg = $app->uri_params('mode' => $return_mode, 'args' => \%return_args);
        $return_arg =~ s/^\?//;
        return $app->redirect(
            $app->uri(
              mode => 'rebuild_new_phase',
              args => { id => \@ids, return_args => $return_arg }
            )
        );

rebuild_new_phaseモードはrebuild_theseを呼び出します。

これによって、

  1. エントリーにA-Formの変数<!-- aformXXX -->をグローバルフィルターで読み込み
  2. 埋め込まれているA-FormのIDを取得し、A-Formと埋め込み先のエントリーの関連を保持するMT::AFormEntryモデルからこのA-Formが埋め込まれている他のエントリーIDを取得する
  3. 取得したエントリーIDをrebuild_new_phaseにidパラメータで渡すことで、このA-Formが埋め込まれているエントリーを全て再構築する。
    という処理を行っています。
[edit]

次回予定

次回は(まだちょっと未定ですが)、国際化の方法、またはregistryメソッドのリファレンス一通り見ることを行いたいと思います。registryメソッドの場合は長くなると思いますので、2〜3回にわけるかもしれません。

投稿者進地 | パーマリンク | コメント(0)

| append.gif

tag: Movable TypeMTMTMTPlugin勉強会A-Form


添付ファイル: fileQuote.zip 519件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-06-27 (金) 11:18:45 (4182d)

アークウェブのサービスやソリューションはこちら