誰を対象とした内容か?
今回の記事はプラグイン開発者を対象とした内容になります。
フィールド追加系プラグインとは?
「ブログ記事」や「カテゴリー」といったオブジェクトにデータの項目を追加して、管理画面から情報を登録したりMTタグで呼び出したりできるようにするプラグインのことです。また今回はその中でも特に機会が多いと思われる、「ブログ記事へのフィールド追加」のケースを説明をします。
ベストプラクティス?
MTの変化の流れは表から見える以上に速く、MT3系からMT4系へのインターフェイスも含めた大きな変更があったり、マイナーバージョンアップであるMT4.21からMT4.26までの間にも内部では結構な規模の大きな変更もあったりと、陰に陽に変化をしています。そんな中で、フィールド追加系のプラグインの作成の仕方にも変化が出てきているようなので、現時点(2009年9月)でのもっともスマートと思われる方法を、ベストプラクティスとしてまとめてみたいと思います。
この記事での題材
説明のための題材として、先日リリースした「Manifest」を利用します。
データベースへのカラムの追加
まずはデータベースへのカラムの追加ですが、これは簡単で、特別以前と変わっている部分もありません。config.yamlを使う場合は以下のように書くと整数カラムと文字列カラムを追加することができます。
config.yaml
38 object_types: 39 entry: 40 first_revision: 41 type: integer 42 not_null: 1 43 default: 0 44 label: First published revisions 45 party: 46 type: string 47 size: 255 48 not_null: 1 49 label: Political party 50 required: 1 51 revisioned: 1
編集画面への入力欄の追加
次に編集画面への入力欄の追加です。ここはちょっと変化のあった部分です。
MTではテンプレートの処理の前に仕掛けることのできるコールバックの仕組みが強力なので、編集画面を生成するテンプレートのtemplate_sourceやtemplate_paramにコールバックを仕掛けて、HTMLを挿入するのが主流の方法だと思います。
この方法は管理画面のあらゆる場所で利用できるので応用のきくよい方法ではあるのですが、「ブログ記事」にフィールドを追加するケースに限っては、 MT4.25からは違う方法も使えるようになりました。template_paramへコールバックを仕掛けるところまでは前述の方法と一緒なのですが、テンプレートの中で入力欄を並べるために「field_loop」という変数が追加されたので、これに手を入れることで入力欄を追加することができるようになっています。
このような感じです。
config.yaml
141 callbacks: 142 MT::App::CMS::template_param.edit_entry: $Manifest::Manifest::App::param_edit_entry
lib/Manifest/App.pm
175 push(@{ $param->{'field_loop'} }, { 176 'field_id' => 'party', 177 'lock_field' => '0', 178 'field_name' => 'party', 179 'show_field' => 1, 180 'field_label' => $plugin->translate('Party'), 181 'label_class' => 'top-label', 182 'required' => '1', 183 'field_html' => <<__EOF__, 184 <input type="text" name="party" id="party" class="full-width" value="<mt:var name="party" escape="html" \>" mt:watch-change="1" autocomplete="off" /> 185 __EOF__ 186 });
「field_loop」を使うことによりこのように(若干)簡潔に書けるようになるという点ももちろんあるのですが、もう一つ大きなメリットとして、追加したフィールドが「表示オプション」に表示され、MTの持っている並べ替え機能を利用できるようになるという点もあります。(MT5b2で確認)
またプラグインの中のHTMLの記述が減るので、この先MTの管理画面で大きな変更があったとしても自動で対応ができるか、あるいは最小限の変更で対応できるようになることも期待できます。
入力された値のバリデーション
続いて入力された値のバリデーションを行います。
MT3の頃から使えるものとして、バリデーションはオブジェクトの post_save で行うという方法があります。
post_save でチェックを行う方法は、オブジェクト自身が内容について責任を持つということで意味的にしっくりくるものではあるのですが、この方法だとエラーがあった場合にMTのエラー画面が表示され、「戻る」ボタンをクリックして戻るようなフローになります。ただ場合にこのような動作ではなく、そのまま編集画面の戻って欲しいということもあるのではないかと思います。
そのような場合にはオブジェクトではなくアプリケーションのコールバックにcms_save_filterというものがあるので、これを使うとエラー発生時に直接編集画面に戻ることができます。
config.yaml
149 cms_save_filter.entry: $Manifest::Manifest::App::save_filter
lib/Manifest/App.pm
113 sub save_filter { 114 return 1 unless &enabled(); 115 116 my ($cb, $app) = @_; 117 my $plugin = MT->component('Manifest'); 118 119 my $party = $app->param('party') || ''; 120 $party =~ s/ |\s//g; 121 122 if (! $party) { 123 return $cb->error($plugin->translate('Party is required.')); 124 } 125 126 1; 127 }
以上です。
現状のMTでフィールドを追加するプラグインを作成するとすると、このあたりがベストプラクティスと言えるのではないかと思います。
またもっとよい方法があったり、間違いや勘違いがありましたら、ご指摘を頂ければ幸です。
コメントする