プラグインから管理画面を変更する手段を提供することで、より高度なプラグインの作成が可能となります。
しかし、現在日本語では殆どドキュメントが用意されていない状況です。
興味本位でちょっと調べてみたところ、こんなことも出来るのか、という使い勝手の良い部分が、知られずに埋もれていると感じたので、まとめておきます。後でチョコチョコと追記するかもしれません。
妙に堅い説明口調になってしまったのは、何ででしょうね。。。
ちなみに、3.3前後のmtのプロジェクト名は、全てアニメのトランスフォーマーのロボットの名前から取られているそうです ;-)
3つのコールバック
主に以下のコールバックを利用することで、管理画面の変更が行えます。
- AppTemplateSource
- AppTemplateParam
- AppTemplateOutput
それぞれのコールバックでは、実行されるタイミング、および渡される引数が異なるため、目的に応じて使い分けます。引数などの詳細はMovable Type オブジェクト・リファレンス - MT::Appの「コールバック」の項を参照してください。
Movable Typeの管理画面は、HTML::Templateモジュールを利用して出力されています。ある程度踏み込んだ作業を行う場合、HTML::Templateモジュールについての知識も必要になるでしょう。
AppTemplateSource
管理画面のテンプレートを直接変更することが出来ます。実行されるのはHTML::Templateがテンプレートタグのパースを行う前なので、単純な文字列置換のほかにも、HTML::Templateのタグを直接書き換えることも可能です。
TMPL_INCLUDEで読み込まれるテンプレートについては、注意が必要です。AppTemplateSourceコールバックの実行ルーチンは、HTML::Templateのfilterとして登録されるので、TMPL_INCLUDEによって新たにテンプレートが読み込まれる都度、実行されます。
HTML::Template - CGI スクリプトから HTML テンプレートを使うための Perl モジュール
filter - このオプションはテンプレートファイルに対するフィルタを指定します。フィルタは HTML::Template がテンプレートファイルを読み込んだ後、テンプレートタグのパーズを開始する前に呼び出されるサブルーチンです。
(中略)
指定されたフィルタは TMPL_INCLUDE でファイルが読み込まれる度にメインのテンプレートファイルと同様に適用されます。
しかし、filter内でコールバックの判定と実行が行われるため、variant(ポイント以降の部分。この場合はファイル名)が指定されているコールバックは、その段階で「今回実行する必要がないコールバック」と判定されてしまい実行されません。その結果、たとえば
MT->add_callback('MT::App::CMS::AppTemplateSource.list_blog', 9, $plugin, \&transform_routine);として登録したコードは、list_blog.tmplファイル内部でインクルードされるheader.tmplに対しては実行されません。header.tmplのインクルードの際にコールバックされるのは、AppTemplateSource.headerに登録したコールバックや、variant無しでAppTemplateSourceに登録したコールバックです。
この仕様により、list_blog画面でのみheaderのテンプレートに変更を加える、ということは実現が難しくなっています。もしHTML::Templateによるテンプレートの展開が終了した後でも実現可能な作業ならば、迷わず「AppTemplateOutput」を使うべきでしょう。
管理画面の全てのページにスタイルシートやjavascriptを追加する場合にも、このコールバックを利用するとちょっと便利です。headerテンプレートには「<MT_HEAD:STYLE>」「<MT_HEAD:SCRIPT>」という、スタイルシートとjavascriptをhead要素内に追加するためのプレースホルダーが用意されています。具体的には、以下のサブルーチンを呼び出すことで、これらプレースホルダーの位置に任意の内容を挿入出来ます。
- tmpl_prepend
tmpl_prepend($tmpl, $section, $id, $content);
プレースホルダーの先頭に$contentで指定した文字列を追加します。- tmpl_replace
tmpl_replace($tmpl, $section, $id, $content);
プレースホルダー全体を$contentで指定した文字列で置き換えます。- tmpl_append
tmpl_prepend($tmpl, $section, $id, $content);
プレースホルダーの先頭に$contentで指定した文字列を追加します。- tmpl_select
tmpl_select($tmpl, $section, $id);
プレースホルダーの現在の内容を返します。
$tmplには、テンプレートの内容へのリファレンスを指定する必要があります(AppTemplateSourceから渡される$tmpl変数をそのまま渡せばよいです)。
$sectionと$idの組み合わせによってターゲットとなるプレースホルダーを指定します。mt-3.34では、$sectionに文字列「HEAD」、$idには文字列「STYLE」または「SCRIPT」という組み合わせが利用可能です。他には、やはりheaderテンプレートで「TOPNAV」「BLOGMENU」という組み合わせも利用できそうです(未確認)。将来的には、他にもプレースホルダーが追加されるのかもしれません。
例えば、管理画面の背景に何らかの画像を表示させたい場合、次のようなコードになります。
MT->add_callback('MT::App::CMS::AppTemplateSource', 9, $plugin, \&change_background);
sub change_background {
my ($eh, $app, $tmpl) = @_;
my $contents = 'body { background-image: url(http://www.example.com/some_image.gif); }';
$app->tmpl_append( $tmpl, 'HEAD', 'STYLE', $contents);
}
なお、最終出力に対してカスタマイズを行うAppTemplateOutputでは、プレースホルダーがすでにテンプレートから削除されているため、これらのサブルーチンは利用できません。
AppTemplateParam
HTML::Templateに渡されるパラメータに対して、追加や変更を行うことが出来ます。
例えば、管理画面の右上にあるクイックサーチ部分はパラメータで表示、非表示を切り替えているため、以下のようなコードで表示を抑制することが出来ます。
MT->add_callback('MT::App::CMS::AppTemplateParam', 9, $plugin, sub{ $_[2]->{quick_search} = 0 });
とはいえ、既存のパラメータについては、あまり多くの変更の余地は無いかもしれません。このコールバックは、(AppTemplateSourceコールバックと組み合わせて、)プラグインで独自にHTML::Templateのタグを追加する場合などに、より大きな威力を発揮するでしょう。
AppTemplateOutput
最終的に出力されるHTMLに対して変更を行うことが出来ます。HTML::Templateのタグはすべて展開済みとなっているため、正規表現による置換を行う場合には注意が必要です。