Skip to content

Japanese plugin dev 4 3

uehatsu edited this page May 13, 2011 · 18 revisions

Transformerプラグインの開発

はじめに

MT利用していると「管理画面のここを変更したい」「管理画面の使わない箇所を削除してしまいたい」などの欲求が出てくると思います。

そこで今回はTransformerプラグインによる管理画面の表示内容変更について解説します。

Transformerプラグインとは?

Transformerプラグインは名前のとおり「実際の管理画面をトランスフォーム(変身)させることで表示を変更する」ものです。

Transformer用のフックポイントがあるので、コールバックを使って管理画面を変身(修正、追加、削除)させます。

Transformerプラグインの開発

仕様

  • ブログ記事、ウェブページともエディット画面で「続き」ボタンを消す
    • 「お客様から自分が必要無いな機能を外してほしい」と言われたと仮定
  • DOM ID=keywords の次にURLを記入できる欄を追加する
    • URL欄が空白の場合は"http://www.example.com/"を入力する
    • URL欄は表示だけで、保存、修正などできなくてよい(あくまで表示例)

config.yaml

id: MyPlugin13
key: MyPlugin13
name: <__trans phrase="Sample Plugin Transformer">
version: 1.0
description: <__trans phrase="_PLUGIN_DESCRIPTION">
author_name: <__trans phrase="_PLUGIN_AUTHOR">
author_link: http://www.example.com/about/
doc_link: http://www.example.com/docs/
l10n_class: MyPlugin13::L10N

callbacks:
    MT::App::CMS::template_source.edit_entry: $MyPlugin13::MyPlugin13::Transformer::hdlr_template_source_edit_entry
    MT::App::CMS::template_output.edit_entry: $MyPlugin13::MyPlugin13::Transformer::hdlr_template_output_edit_entry
    MT::App::CMS::template_param.edit_entry: $MyPlugin13::MyPlugin13::Transformer::hdlr_template_param_edit_entry

解説

config.yamlで注目するのはcallbacks以下の3行です。

  • MT::App::CMS::template_source.(テンプレート名): $(プラグイン名)::(Perlモジュール名)::(ハンドラ関数)
    • template_source は処理前のテンプレートを変更するためフックポイントです。
    • テンプレートは $MT_DIR/tmpl/cms の中にあり、設定系は conf_xxx.tmpl 、 一覧系は list_xxx.tmpl 、新規・修正系は edit_xxx.tmpl のようになっています。今回はブログ記事(entry)の修正なので edit_entry.tmpl となりますが、拡張子を取った物( edit_entry )がテンプレート名になります。
  • MT::App::CMS::template_output.(テンプレート名): $(プラグイン名)::(Perlモジュール名)::(ハンドラ関数)
    • template_output は処理後のテンプレートを変更するためフックポイントです。
    • テンプレート名は 。上記と同じ理由で edit_entry となります。
  • MT::App::CMS::template_param.(テンプレート名): $(プラグイン名)::(Perlモジュール名)::(ハンドラ関数)
    • template_param は値を代入したり、DOMベースでの文字列の挿入などを行うフックポイントです。
    • テンプレート名は 。上記と同じ理由で edit_entry となります。

MyPlugin13/Transformer.pm

package MyPlugin13::Transformer;
use strict;

sub hdlr_template_source_edit_entry {
    my ($cb, $app, $tmpl_ref) = @_;
    my $old = <<EOF;
                        <div class="tab" mt:command="set-editor-extended" mt:tab="extended">
                            <label><a href="javascript:void(0);"><__trans phrase="Extended"></a></label>
                        </div>
EOF
    $old = quotemeta($old);
    $old =~ s!(\\ )+!\\s+!g;

    my $new = "";

    $$tmpl_ref =~ s!$old!$new!;
}

sub hdlr_template_output_edit_entry {
    my ($cb, $app, $tmpl_str_ref, $param, $tmpl) = @_;

    # do something
}

sub hdlr_template_param_edit_entry {
    my ($cb, $app, $param, $tmpl) = @_;

    my $host_node = $tmpl->getElementById('keywords');
    my $innerHTML = '<input type="text" name="url_field" id="url_field" class="full-width" mt:watch-change="1" value="<mt:var name="url_field" escape="html">" autocomplete="off" />';

    my $block_node = $tmpl->createElement(
        'app:setting',
        {
            id => 'url_field',
            label => 'URL',
            label_class => 'top-label',
        }
    );

    $block_node->innerHTML( $innerHTML );
    $tmpl->insertAfter($block_node, $host_node);

    $param->{url_field} = "http://www.example.com/" if !$param->{url_field};
}

1;

解説

package MyPlugin13::Transformer;
use strict;
  • パッケージモジュール名を指定し use strict します。
sub hdlr_template_source_edit_entry {
    my ($cb, $app, $tmpl_ref) = @_;
    my $old = <<EOF;
                        <div class="tab" mt:command="set-editor-extended" mt:tab="extended">
                            <label><a href="javascript:void(0);"><__trans phrase="Extended"></a></label>
                        </div>
EOF
    $old = quotemeta($old);
    $old =~ s!(\\ )+!\\s+!g;

    my $new = "";

    $$tmpl_ref =~ s!$old!$new!;
}
  • sub hdlr_template_source_edit_entry{}
    • $cb コールバック、 $app アプリケーション情報、 $tmp_ref テンプレートのリファレンスです。
    • $old に修正したい文字列を代入します。今回は削除したい箇所(続きタブ)になります。
    • 後で利用する置換の文字列に’(‘, ’)’が入っているため、 quotemeta() に通します。
    • MT5.0とMT5.1両方に対応するため、空白文字を \s+ に入れ替えます。
    • 今回削除なので置換する文字列( $new )は空文字です。
    • テンプレートのリファレンスからテンプレートを引出し( $$tmpl_ref )、置換を行います。
    • これを行うことで「本文」タブの横の「続き」タブが消えます。
sub hdlr_template_output_edit_entry {
    my ($cb, $app, $tmpl_str_ref, $param, $tmpl) = @_;

    # do something
}
  • sub hdlr_template_output_edit_entry {}
    • この関数も template_source と同じくテンプレートの修正をしますが、 template_source が手を入れる前のテンプレートに大して行うのと違い、テンプレートの構築処理が終わった後の出力( $tmpl_str_ref )に対して修正を行います。
    • それ以外の説明は template_source と同じなので省略します。
sub hdlr_template_param_edit_entry {
    my ($cb, $app, $param, $tmpl) = @_;

    my $host_node = $tmpl->getElementById('keywords');
    my $innerHTML = '<input type="text" name="url_field" id="url_field" class="full-width" mt:watch-change="1" value="<mt:var name="url_field" escape="html">" autocomplete="off" />';

    my $block_node = $tmpl->createElement(
        'app:setting',
        {
            id => 'url_field',
            label => 'URL',
            label_class => 'top-label',
        }
    );

    $block_node->innerHTML( $innerHTML );
    $tmpl->insertAfter($block_node, $host_node);

    $param->{url_field} = "http://www.example.com/" if !$param->{url_field};
}
  • sub hdlr_template_param_edit_entry {}
    • $cb コールバック、 $app アプリケーション情報、 $param テンプレートの構築時に渡されるパラメータ、 $tmpl テンプレートオブジェクトです。
    • getElementById を使ってDOMの’keywords’のノードを検索します。
    • $innerHTML に、挿入したい文字列をセットします。
    • createElement を使って新規のノードをセットします。
    • 新規ノードに $innerHTML をセットします。
    • insertAfter($block_node, $host_node) を使って $host_node の後に $block_nodeを挿入します。
    • 最後の $param はDOMの説明とは関係ありませんが template_param の本来の使い方で、構築時のパラメータとして任意のものを渡す事ができます。
      • 例えば今回の場合、新規に追加した行に <mt:var name="url_field"> がありますので、そちらに値(http://www.example.com/)が設定されます。
      • 条件としては $param->{url_field} に値がセットされてい無い場合に値(http://www.example.com/)がセットされるように実装されています。
      • このURLはブログ記事を保存してもデータベースに値が保存されません。ブログ記事クラスの拡張や、URLクラスを作成してブログ記事の post_save で保存するなど実装方法が色々と考えられますが、今回は省略します。

DOM関連の関数

DOM関連の関数は MT::Template に実装されています。

sub getElementsByTagName {} タグ名でDOMエレメントを検索する
sub getElementsByClassName {} クラス名でDOMエレメントを検索する
sub getElementsByName {} nameでDOMエレメントを検索する
sub getElementById {} idでDOMエレメントを検索する
sub createElement {} 新規ノードを作成する
sub createTextNode {} 新規テキストノードを作成する
sub insertAfter {} 指定されたDOMエレメントの後にエレメントを挿入する
sub insertBefore {} 指定されたDOMエレメントの前にエレメントを挿入する
sub childNodes {} 指定された物の子ノードを取得する
sub hasChildNodes {} 子ノードの有無を確認する
sub appendChild {} 指定されたノードに子ノードを追加する

取得したノードの操作のために、 MT::Template::Node に関数が用意されています。

sub nodeValue {} 与えられたノードの値を取得する
sub childNodes {} 与えられたノードの子ノードを取得する
sub attributes {} ノードの属性を取得する
sub attribute_list {} ノードの属性リストを取得する
sub tag {} ノード名の設定と取得を行う
sub setAttribute {} ノードの属性を設定する
sub getAttribute {} ノードの属性を取得する
sub firstChild {} 最初の子ノードを取得する
sub lastChild {} 最期の子ノードを取得する
sub nextSibling {} 次のノードを取得する
sub previousSibling {} 前のノードを取得する
sub ownerDocument {} ノードのテンプレートオブジェクトを取得する
sub hasChildNodes {} 子ノードの有無を確認する
sub nodeType {} ノードのタイプ名を取得する
sub nodeName {} ノード名を取得する
sub innerHTML {} HTML(もしくはXTML)を挿入する
sub appendChild {} 子ノードを追加する
sub removeChild {} 子ノードを削除する
sub upgrade {} ノードをUTF8にエンコードする

ファイルの配置

$MT_DIR/
|__ plugins/
   |__ MyPlugin13/
      |__ config.yaml
      |__ lib/
         |_ MyPlugin13/
            |__ L10N.pm
            |_ L10N/
            |  |_ en_us.pm
            |  |_ ja.pm
            |__ Transformer.pm

プラグインダウンロード

MyPlugin14.zip(2.63KB)

まとめ

とっかかりは難しそうですが、管理画面で困っている場合は今回解説した管理画面の修正をしてみてはいかがでしょうか?

ただしTransformerプラグインは、MTのバージョンにより置換文字列などを修正する必要など出てくる場合がありますのでご注意ください。

プラグイン開発ガイド インデックス

  1. プラグイン開発のためのファーストステップ
  2. レジストリ、YAMLについて
  3. 環境変数について
  4. プラグインのローカライゼーションについて
  5. テストドリブンでのプラグインの開発について
  6. グローバル・モディファイアプラグインの開発について
  7. ファンクションタグ プラグインの開発について
  8. ブロックタグ プラグインの開発について
  9. コンディショナルタグ プラグインの開発について
  10. プラグインのデバッグ
  11. プラグインの設定方法
  12. コールバックとフックポイント
  13. スケジュールタスクの開発
  14. MTオブジェクトの利用方法
  15. 独自オブジェクトの作成
  16. 新規アプリケーションの作成
  17. Transformerプラグインの開発
  18. 管理画面のメニュー修正
  19. リストアクションの追加
  20. 動作モードの追加とモーダルウィンドウの表示
  21. 外部Web APIとの連携
  22. 権限とロール
Clone this wiki locally