Movable Typeに追加した独自オブジェクトをダイナミックパブリッシングで出力する方法
Movable Typeに追加した独自オブジェクトをダイナミックパブリッシングで出力する方法を紹介します。
このエントリーは「Movable Typeに独自オブジェクトを追加する方法」の続きで、「Event」プラグインで「mt_event」というテーブルを定義し、定義したテーブルのデータに対してMTEventsタグとMTEventTitleタグを定義し、ダイナミックパブリッシングで次のテンプレートグの内容を出力できるようにします。
<mt:Events>
<$mt:EventTitle$>
</mt:Events>
1.プラグインの構成
ダイナミックパブリッシング用のプラグインを作成するには、元記事の1項に示したディレクトリ構成に「php」ディレクトリを追加し、その配下に赤色で示した3つのファイルを追加します。
plugins
└ Event
├ config.yaml
├ lib
│ └ MT
│ └ Event.pm
└ php
├ class.mt_event.php
├ block.mtevents.php
└ function.mteventtitle.php
追加した3つのファイルの意味は次の通りです。
- class.mt_event.php:mt_eventテーブルの定義
- block.mtevents.php:ブロックタグMTEventsの実装
- function.mteventtitle.php:ファンクションタグMTEventTitleの実装
ファンクションタグは定義しているフィールドに応じて適宜追加してください。
また、スタティックパブリッシング用として、config.yamlにテンプレートタグの定義が必要です。詳細は6項を参照してください。
2.class.mt_event.php
class.mt_event.phpでダイナミックパブリッシング用に動作するようテーブルを定義します。
<?php
require_once("class.baseobject.php");
class Event extends BaseObject
{
public $_table = 'mt_event';
protected $_prefix = "event_";
protected $_has_meta = true;
}
ADODB_Active_Record::ClassHasMany(
'Event', 'mt_event_meta',
'event_meta_event_id');
?>
新しく追加したEventクラスはBaseObject(class.baseobject.php)を必ず継承してください。
class Event extends BaseObject
{
}
$_tableにテーブル名を定義します。
public $_table = 'mt_event';
$_prefixにテーブルのプレフィックスを定義します。
protected $_prefix = "event_";
$_has_metaにメタテーブルの有無を定義します。
protected $_has_meta = true;
最後にメタデータを利用する場合の設定を行います。
ADODB_Active_Record::ClassHasMany(
'Event', 'mt_event_meta',
'event_meta_event_id');
3.block.mtevents.php
block.mtevents.phpに次の内容を設定します。
<?php
function smarty_block_mtevents($args, $content, &$ctx, &$repeat) {
$localvars = array('event', '_events', '_events_counter', 'blog_id');
if (!isset($content)) {
$ctx->localize($localvars);
$args['blog_id'] = $ctx->stash('blog_id');
if (isset($args['blog_id'])) {
$blog_filter = 'and event_blog_id = ' . intval($args['blog_id']);
}
$where = "1 = 1
$blog_filter
order by event_title";
require_once('class.mt_event.php');
$event = new Event;
$events = $event->Find($where);
$ctx->stash('_events', $events);
$counter = 0;
} else {
$events = $ctx->stash('_events');
$counter = $ctx->stash('_events_counter');
}
if ($counter < count($events)) {
$event = $events[$counter];
$ctx->stash('event', $event);
$ctx->stash('_events_counter', $counter + 1);
$repeat = true;
} else {
$ctx->restore($localvars);
$repeat = false;
}
return $content;
}
?>
ダイナミックパブリッシングのブロックタグの基本的な構造は上記と同じですが、今回は独自オブジェクトなので、MTに実装されているfetch系のAPIの代わりに、追加したクラス定義をそのまま利用します(以下の部分)。
$args['blog_id'] = $ctx->stash('blog_id');
if (isset($args['blog_id'])) {
$blog_filter = 'and event_blog_id = ' . intval($args['blog_id']);
}
$where = "1 = 1
$blog_filter
order by event_title";
require_once('class.mt_event.php');
$event = new Event;
$events = $event->Find($where);
下から3行目で定義したクラスclass.mt_event.phpを読み込みます。
require_once('class.mt_event.php');
Eventオブジェクトを作成します。
$event = new Event;
Eventオブジェクトに対してFind()を実行します。Findはclass.mt_event.php継承したBaseObjectに定義されたAPIで、このAPIでデータベースのデータを取得します。
$events = $event->Find($where);
Findのパラメータには、SQLとなる変数$whereを設定します(1~7行目)。
$args['blog_id'] = $ctx->stash('blog_id');
if (isset($args['blog_id'])) {
$blog_filter = 'and event_blog_id = ' . intval($args['blog_id']);
}
$where = "1 = 1
$blog_filter
order by event_title";
ここではblog_idとevent_titleでソートするように設定しています。この部分は必要に応じて適宜変更してください。
4.function.mteventtitle.php
function.mteventtitle.phpに次の内容を設定します。
<?php
function smarty_function_mteventtitle($args, &$ctx) {
$event = $ctx->stash('event');
return $event->event_title;
}
?>
コンテキストからstashに保存されたeventを取得します。
$event = $ctx->stash('event');
取得した$eventには1レコード分のデータが入っているので、あとはフィールドを指定して返却すればOKです。
return $event->event_title;
他のフィールド用のファンクションタグを作る場合は、ファイル名と関数名を変更し、以下の赤色部分を該当するフィールド名にしてください。
return $event->event_title;
5.メタデータについて
元記事で追加したテーブルにはメタデータを使う定義をしていないので、メタデータを使っていない場合は、ADODB_Active_Record::ClassHasManyの3行の設定は不要です。
ADODB_Active_Record::ClassHasMany(
'Event', 'mt_event_meta',
'event_meta_event_id');
また、$_has_metaもfalseを設定しておくといいでしょう。
protected $_has_meta = false;
なお独自テーブルでメタデータを利用する設定を行うには、lib/MT/Event.pmに次の1行を追加してください。
…前略…
datasource => 'event',
primary_key => 'id',
meta => 1,
…後略…
メタデータを定義していないのにADODB_Active_Record::ClassHasManyの定義を行って、ダイナミックパブリッシングでアクセスすると次のようなエラーが出力されるので注意してください(mt-config.cgiにDebugMode 1を設定)。
ページが見つかりません。
<p><b>Error:</b> pdo error: [-1: Invalid table name: mt_event_meta] in ADODB_Active_Record::UpdateActiveTable(0, 0) <br></p><pre>#0 /home/user/htdocs/mt/php/extlib/adodb5/adodb-active-record.inc.php(496): adodb_throw() #1 /home/user/htdocs/mt/php/extlib/adodb5/adodb-active-record.inc.php(390): ADODB_Active_Record->Error('pdo', 'ADODB_Active_Re...', -1, 'Invalid table n...', 0, 0, Object(ADODB_pdo)) #2 /home/user/htdocs/mt/php/extlib/adodb5/adodb-active-record.inc.php(136): ADODB_Active_Record->UpdateActiveTable('Invalid table n...', 'UpdateActiveTab...') #3 /home/user/htdocs/mt/php/extlib/adodb5/adodb-active-record.inc.php(200): ADODB_Active_Record->__construct(false) #4 /home/user/htdocs/mt/php/extlib/adodb5/adodb-active-record.inc.php(230): ADODB_Active_Record->hasMany('mt_event_meta') #5 /home/user/htdocs/mt/plugins/Event/php/class.mt_event.php(14): ADODB_Active_Record::ClassHasMany('mt_event_meta', 'event_meta_even...', 'ADODB_Active_Re...') #6 /home/user/htdocs/mt/plugins/Event/php/block.mtevents.php(18): require_once('/home/user/htdocs...') #7 /home/user/htdocs/mt/website/blog/templates_c/%%B2^B21^B21484EB%%mt%3A247.php(12): smarty_block_mtevents('Event', 'mt_event_meta', 'event_meta_even...') #8 /home/user/htdocs/mt/php/extlib/smarty/libs/Smarty.class.php(1265): include('/home/user/htdocs...') #9 /home/user/htdocs/mt/php/mt.php(650): Smarty->fetch(Array, NULL, Object(MTViewer), true) #10 /home/user/htdocs/mt/website/blog/mtview.php(5): MT->view('mt:247', '4;/mt/fi...') #11 {main}</pre>
6.スタティックパブリッシングの対応
5項までの設定ではテンプレートにMTEventsタグを設定した時点で「タグがみつかりません」というエラーになります。
これはconfig.yamlにテンプレートタグの定義を行っていないためです。
よってconfig.yamlにテンプレートタグの定義を行います。たとえば、lib/Event/Tag.pmに実装するのであれば次のように記述し、lib/Event/Tag.pmにhdlr_eventsとhdlr_event_titleを実装する必要があります。
id: Event
name: Event
description: This is event object.
version: 1.00
schema_version: 1.0
object_types:
event: MT::Event
tags:
block:
Events: $Event::Event::Tags::hdlr_events
function:
EventTitle: $Event::Event::Tags::hdlr_event_title
ただし、スタティックパブリッシング用の拡張テンプレートタグの実装が必要ないのであれば、以下の赤色部分のように記述しておくとよいでしょう。
id: Event
name: Event
description: This is event object.
version: 1.00
schema_version: 1.3
object_types:
event: MT::Event
tags:
block:
Events: sub {}
function:
EventTitle: sub {}
7.参考サイト
この記事は以下のスライドを参考にさせて頂きました。ありがとうございました。
Phpで作るmovable typeプラグイン from Yuji Takayama
- Movable Typeのプラグインで管理画面のローカライズを行う方法
- Movable Typeに独自オブジェクトを追加する方法
- Movable Typeの一覧画面にリストアクションを追加する
- Movable TypeのプラグインオブジェクトをPerlで作成するときのバリエーション
- Movable Typeのプラグインファイル構成について