プラグインによるテーマフレームワークの拡張
Movable Type 6 はサポートが終了したバージョンです。最新版のマニュアルはこちら を参照して下さい。
プラグイン作者向けの テーマ フレームワークの拡張方法を説明します。
テーマ フレームワーク と テーマ パッケージ
テーマ パッケージ とは
Movable Type で利用できる状態のテーマのデータです。テーマをプラグインで定義するか、あるいは themes ディレクトリに配置します。
テーマ フレームワーク とは
Movable Type がテーマ パッケージのデータを入出力するための仕組です。プラグイン作者は、テーマ フレームワークを拡張することで、自分のプラグインのデータを、テーマ パッケージから利用できます。
テーマ パッケージ の各項目は、テーマ エレメントとして定義されています。このテーマ エレメントの読み込みと書き出しは、インポータと エクスポータ によっておこないます。プラグイン作者は、独自のインポータ と エクスポータ を実装することで、テーマ パッケージに含めるテーマ エレメントのデータ構造を拡張できます。
インポータ と エクスポータ
インポータは、Movable Type がテーマ エレメントを利用するために必要です。
エクスポータは、Movable Type の管理画面からテーマをエクスポートするときに必要です。したがって、既存のウェブサイトやブログからテーマをエクスポートしない場合には、実装する必要はありません。
インポータの仕様をドキュメントなどで詳しく解説することで、エクスポータを実装せずともテーマ作者が、テーマ エレメントを テーマ パッケージに 手書きで含めることが可能です。
インポータ と エクスポータの追加方法
インポータは、レジストリに加えて、Perl のルーチンを用意する必要があります。以下をプラグインに追加します。
- インポート処理をおこなう、Perl で書かれたサブルーチンを用意する。
- 上記のハンドラコードを、Movable Type に登録するレジストリ エントリーを用意する。
レジストリへの登録
以下の yaml コードは、レジストリへの登録例です。
theme_element_handlers:
my_element_handler:
label: My Element Handler
importer:
import: $MyPlugin::MyPlugin::Theme::apply
info: $MyPlugin::MyPlugin::Theme::info
validator: $MyPlugin::MyPlugin::Theme::validator
exporter:
params: custom_fields_export_ids
component: my_plugin
condition: $MyPlugin::MyPlugin::Theme::condition
template: $MyPlugin::MyPlugin::Theme::template
export: $MyPlugin::MyPlugin::Theme::export
インポータ
インポータとテーマ エレメントは対になります。ウェブサイトあるいはブログにテーマを適用するときに、Movable Type はテーマに含まれるすべてのテーマ エレメントについて、対応するインポータを探して、処理を実行します。具体的なデータの処理は、インポータ側に実装します。
もしインポータが見つからない場合は、そのテーマ エレメントが必須であれば、処理を中止してユーザーにエラーを通知します。必須では無いときは次のテーマ エレメントの処理に移りテーマの適用を続行します。
import
テーマを適用する Perl のサブルーチンを指定します。引数として、3 つのオブジェクトが渡されます。
- 適用するテーマ エレメント
- テーマ エレメントを含むテーマ全体
- テーマを適用する(多くの場合は作成されたばかりの) MT::BlogまたはMT::Website のインスタンス
テーマ エレメント および テーマ全体は、それぞれ MT::Theme::Element と MT::Theme クラスに bless されたオブジェクトとして引き渡されます。
以下は、ブログの各種設定を埋め込んだ テーマ エレメントを、MT::Blog クラスに適用するインポータの例です。
sub my_importer {
my ( $element, $theme, $obj_to_apply ) = @_;
my $data = $element->data;
if ( ref $obj_to_apply ne MT->model('blog') ) {
return $element->errtrans('this element cannot apply for not blog object.');
}
my $blog = $obj_to_apply;
for my $conf ( keys $data ) {
if ( $blog->has_column($conf) ) {
my $value = $data->{$conf};
$blog->$conf($value);
}
}
return 1;
}
info
Movable Type がテーマの内容を解析するためのサブルーチンです。テーマを適用したときに、何が起こるかをユーザーに伝えるメッセージを表示します。
sub info {
my ($element, $theme, $blog) = @_;
my $item_count;
## analyse the $element and set some value for $item_count
return sub {
MT->translate(
'[_1] items would be added to your blog.',
$item_count,
);
};
}
validator
現在のブログの状態をテストし、テーマ エレメントの読み込みが可能かを判断するサブルーチンを指定します。
sub validator {
my ( $element, $theme, $obj_to_apply ) = @_;
my $conflict;
## validate $obj_to_apply is okay to apply $element.
if ( $conflict) {
return $element->error(
MT->translate(
'Conflict has occured!',
)
);
}
return 1;
}
エクスポータ
params
テーマをエクスポートするときに、オプション設定画面で使用するパラメータ一の名前を指定します。Movable Type はこの値をもとに、エクスポート設定を保持します。複数のパラメータを利用する場合、Array_ref で指定してください。
component
エクスポートしたデータを、インポートするインポータの ComponentID を指定します。
template
エクスポートのオプション設定画面の出力サブルーチンを指定します。
sub export_template {
my $app = shift;
my ( $blog, $setting ) = @_;
$setting = { some_setting => 'default' }
if !defined $setting;
my $param = $setting->{some_setting};
my %param = (
param_for_tmpl => $param,
);
return $app->load_tmpl(
'include/my_export_screen.tmpl',
¥%param,
);
}
export
実際のエクスポート処理を行うサブルーチンを指定します。
sub export {
my $app = shift;
my ( $blog, $setting ) = @_;
my $export_data = {};
## do copy some data from $blog to $export_data
return $export_data;
}
export サブルーチンではハッシュリファレンスをリターンするようにしてください。この戻り値が、エクスポートされたテーマ エレメントの data 要素として格納されます。
finalize
エクスポート処理の後に実行するサブルーチンを指定します。ここで指定したサブルーチンは、テーマのデータ構造が問題無く作成され、エクスポート処理用のテンポラリーディレクトリを確保した後に呼び出されます。ファイルコピーのような、テーマへの直接の操作をおこなうことができます。
sub finalize {
my $app = shift;
my ( $blog, $theme_hash, $tmpdir, $setting ) = @_;
my $success = 0;
## some work for $tmpdir
return $success ? 1 : 0;
}
condition
テーマをエクスポートするウェブサイトあるいはブログで、エクスポートハンドラが利用可能かどうかを判定するサブルーチンを指定します。たとえば、カテゴリが存在しないブログでは、カテゴリのエクスポートオプションを表示しないように判定します。
sub condition {
my ( $blog ) = @_;
# show export option if blog has at least one template.
my $tmpl = MT->model('template')->load(
{ blog_id => $blog->id },
{ limit => 1 },
);
return defined $tmpl ? 1 : 0;
}
テーマのバージョン管理
テーマ パッケージ と インポータ には、各々 2 つのバージョン管理設定があります。
- テーマ パッケージ
- schema_version
- min_importer_version
- インポータ
- min_schema_version
- max_schema_version
min_schema_version <= schema_version <= max_schema_version
テーマ パッケージの schema_version が、インポータ の min_schema_version 以上、かつ max_schema_version 以下の場合は、正常に処理が行われます。
schema_version < min_schema_version
ひとつの問題は、プラグインがバージョンアップして、インポータが古いテーマを適用することが出来なくなった場合です。
インポータの min_schema_version よりも、テーマ パッケージの schema_version の方が低い場合、Movable Type はテーマ エレメントが必須であれば処理を中止してユーザーにエラーを通知します。必須では無いときは次のテーマ エレメントの処理に移りテーマの適用を続行します。
ただし、プラグイン作者はテーマの schema_version を確認して適切な代替値を入力するなど、出来得る限り下位互換性を確保することが推奨されます。
max_schema_version < schema_version
インポータの max_schema_version よりも、テーマ パッケージの schema_version が大きい場合も考えられます。最新のプラグインでエクスポートされたテーマを、古いバージョンのプラグインでインポートしようとした場合が考えられます。
この場合は、テーマ作者がテーマ パッケージで指定した min_importer_version を利用します。Movable Type は、テーマを利用するためには、プラグインをアップグレードする必要があることをユーザーに伝え、テーマの適用を続行または中止します。
推奨される設定
以下のようなバージョンの設定が推奨されます。
- テーマ パッケージ
- schema_version
テーマ作成時の最新バージョンを指定します。 - min_importer_version
テーマ作成時に、このテーマが古いインポータをロードできない場合は、ロード可能なインポータのバージョンを指定します。
- schema_version
- インポータ
- min_schema_version
インポータ作成時に、このインポータが古いテーマをロードできない場合は、ロード可能なテーマの schema_version を指定します。 - max_schema_version
インポータ作成時の最新バージョンを指定します。
- min_schema_version
最も良いのは、常に後方互換性を保つことです。インポータがすべてのバージョンのテーマ パッケージを読み込めれば、テーマ パッケージの schema_version と、インポータの max_schema_version に最新のバージョンを書くだけで問題ありません。