Movable Type/第3回MTプラグイン勉強会 - MVC風アーキテクチャ実装例・続き コントローラとビュー http://www.ark-web.jp/sandbox/wiki/325.html
Movable Type/第3回MTプラグイン勉強会 - MVC風アーキテクチャ実装例・続き コントローラとビュー
第3回は前回のMVC風アーキテクチャ実装例の続きとしてコントローラ、ビューの実装を示していきます。また、実装例として管理画面に独自画面を追加する例を取り上げます。
動画(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
勉強会で解説したプログラムコードのダウンロード †
前回の勉強会で作成したモデル(MT::Product)も含まれています。
ネタ †
日時 †
- 2008/06/06(金) 10:30〜11:00
MVC風アーキテクチャによる実装例・続き †
Movable Type/第2回MTプラグイン勉強会 - A-Formの基本構造と独自モデルオブジェクトの作り方ではMT::Objectを継承して独自モデルオブジェクトの作り方を解説しました。
今回は第2回で作成したモデルオブジェクトMT::Productを利用して、商品情報の一覧画面を管理画面に追加してみます。
コントローラの作成 †
管理画面に画面を追加する場合、コントローラとしてプラグイン本体と詳細のメソッドを切り出したプラグイン独自のCMSクラスを利用します。
プラグイン本体とCMSクラスのパスは次の通りとします。
- プラグイン本体
- MT_DIR/plugins/ProductsManager/products-manager.pl
- CMSクラス
- MT_DIR/plugins//ProductsManager/lib/ProductsManager/CMS.pm
プラグイン本体に管理画面の追加を指定します。
MTの管理画面はそれぞれ__mode=[モード値]というパラメータによって表示する画面が決定されます。例えば、ブログ一覧画面だと__mode=list_blogsです。
つまり、管理画面を追加するには
- 新しい__modeパラメータの値を定義し
- その__modeパラメータを指定された際に実行するメソッド(ハンドラ)を関連付け
- ハンドラの詳細を実装する
ということになります。
1と2はプラグイン本体で次のように行います。
sub init_registry { my $plugin = shift; $plugin->registry({ 'applications' => { 'cms' => { 'methods' => { list_products => 'ProductsManager::CMS::_list_products', }, }, }, }); }
MT::Component->MT::Pluginと継承しているinit_registryメソッドをオーバーライドして、registryメソッドで独自設定をMTのグローバルレジストリにマージします。
init_registryメソッドは各プラグインがnewされる際にコンストラクタの初期化処理でコールされます。
上のコードでは__mode=list_productsが指定された場合にProductsManager::CMS::_list_productsメソッドを実行するように関連付けています。
Movable Type Registry Reference
の「How to Add a Mode to the CMS Component」に__mode追加の方法が記載されています。
How to Add a Mode to the CMS Component In addition to creating a separate application, developer can also register modes in the “cms” application. Example $registry = { applications => { 'cms' => { methods => { myapp_new-mode => sub { // my handler // }, }, }, }, };
このように関数のリファレンスを新しいモード値(myapp_new-mode)に直接バインドすることもできます。この実装例やA-Formでは管理しやすいようにハンドラを別パッケージ(ProductsManager::CMSなど)に定義しています。
※ mode値は既存の値や他のプラグインの定義したmode値とバッティングしないように、プラグイン固有の接頭辞などをつけた方がよいです。
なお、registryメソッドでは__modeの追加以外にも、メニューの追加、コールバック関数のセットなど様々な設定ができます。
次に、3のハンドラの実装を行います。
ハンドラはProductsManagerに文字列を返すように定義します。
返した文字列が、その__mode値の出力になります。
例えば、
package ProductsManager::CMS; use strict; sub _list_products { my $app = shift; return '__mode is list_products.'; } 1;
のようにすると、__mode=list_productsの出力は「__mode is list_products.」になります。ハンドラの第一引数にはMT::App::CMSオブジェクトが渡されます。
_list_productsは以下のようにします。
sub _list_products { my $app = shift; $app->{plugin_template_path} = 'plugins/ProductsManager/tmpl'; # load Products my @products = MT::Product->load(); my $products_array = []; for my $product (@products) { push(@$products_array, { 'id' => $product->id, 'name' => $product->name, 'description' => $product->description, 'available_at' => $product->available_at, 'price' => $product->price, } ); } return $app->build_page('list_products.tmpl', { products => $products_array } ); }
$app->{plugin_template_path}にはテンプレートファイルを探すディレクトリパスをセットします。その後、MT::Productオブジェクトをロードして、テンプレートで扱いやすいように商品情報をハッシュの配列にしています(各商品情報が一つのハッシュで、それを配列の形で保持した状態)。
最後に$app->build_pageメソッドでテンプレートエンジンを実行して、結果を生成します。
以下、[[Movable Type オブジェクト・リファレンス - MT::App>http://www.sixapart.jp/movabletype/manual/object_reference/archives/mt_app.html]のbuild_pageメソッドの説明より引用。
$app->build_page($tmpl_name, \%param) クライアントに送信するためのアプリケーション・ページを作成します。ページ名は$tmpl_nameで指定します。これは、有効なHTML::Templateタグを含むテンプレート・ファイルの名前でなければなりません。「\%param」は、そのテンプレートで使うためにHTML::Template::paramに渡されるハッシュ・リファレンスです。
作成に成功すると、このメソッドはクライアントに送信するページを格納したスカラー値を返します。失敗した場合にはundefを返し、エラー・メッセージは「$app->errstr」で取得できます。
ビューの作成 †
ビューとしてテンプレートファイルを用意します。
ProductsManager::CMS::_list_productsでplugins/ProductsManager/tmpl/list_products.tmplを利用するように指定していますので、これを用意します。今回は以下のように用意しました。
<p>商品一覧</p> <table border="1"> <tr> <td>ID</td> <td>商品名</td> <td>説明</td> <td>発売日</td> <td>価格</td> </tr> <mt:loop name="products"> <tr> <td><$mt:var name="id"></td> <td><$mt:var name="name"></td> <td><$mt:var name="description"></td> <td><$mt:var name="available_at"></td> <td><$mt:var name="price"></td> </tr> </mt:loop> </table>
テンプレートではMTテンプレートタグを利用できます。
このテンプレートでは、mt:loopタグを使ってbuild_pageで渡したproductsパラメータの配列を各要素単位でまわし、各配列要素のハッシュの値をmt:varタグを使って取り出しています。
MT4.xプラグイン作成/テンプレートでループを利用する方法
MTLoop | テンプレートタグリファレンス
MTVar | テンプレートタグリファレンス
次回予定 †
管理画面のメニューの追加、権限設定を予定します。
tag: Movable Type、MT、MTPlugin、勉強会、A-Form