Blog

ブログ

「第2回 Movable Type勉強会 in Hokkaido」に参加しました

「第2回 Movable Type勉強会 in Hokkaido」に参加してきました。
MovableType拡張のベンダーで知られるスカイアークさんの主宰で、プラグイン開発等の書籍を多数執筆している藤本壱さんが講師です。

MovableTypeはお仕事でよく使っている割に、PHPベースでないこともあって最近の仕様や拡張の方法などよくわかっていません。
いい機会なので基礎の基礎を勉強しました。

内容

  1. プラグインの作り方についての講演(藤本さん)
  2. 簡単なプラグインを作ってみる
  3. プラグイン制作時にセキュリティ面で気を付けなければいけないこと(スカイアーク技術部さん)
  4. Perlでの画像縮小と縮小形式についての話(@techno_nekoさん)
  5. Perlが書けなくても管理画面カスタマイズができるよ!という話(@usa2jpさん)

プラグインの「どのような独自タグを追加するか」「どのタイミングでフックするか」という定義は、以前だと、Perlのプログラム内に直接宣言する仕様になっていたのですが、最近ではYAML形式での簡単な記述が可能になりました。

また、HTML・MTMLで作ったナビゲーションを管理画面のダッシュボードに差し込むようなカスタマイズも、YAML形式で定義できるようになったので、Perl言語を全く知らなくてもなんとかなるようです。

しかし、MovableTypeのコアはセキュリティ面がかなり微妙らしく、外部入力を求めたり、不特定多数に正式配布する場合はプログラム側でしっかり処理のチェックをしておかないと、簡単にXSSCSRFなどの外部攻撃の餌食になってしまう可能性があるそうです。
ただ、こういったチェックの重要性についてはWordPressでも他のCMSでも同じことと言えるでしょう。

プラグインを作ってみた

ハンズオンでは、「対象となる値の全角を半角に/半角を全角に変換する」グローバルモディファイアを追加するプラグインを作ってみました。

プラグイン制作の正式な技術情報はこちらを参照してください。

config.yamlファイルを作る

まず、プラグインを格納する「ConvartCharWidth」ディレクトリを作り、直下に以下のように記述した「config.yaml」ファイルを作成・保存しました。

name: ConvartCharWidth
id: ConvartCharWidth
author_name: Hajime Fujimoto
author_link: http://www.h-fj.com/blog/
description: Modifier of converting character width.
plugin_link: http://www.h-fj.com/blog/mt5plgdoc/convartcharwidth.php
doc_link: http://www.h-fj.com/blog/mt5plgdoc/convartcharwidth.php
version: 1.00
tags:
  modifier:
    conv_width: $ConvertCharWidth::ConvertCharWidth::Plugin::convert_width

「version」の行までは「このプラグインは何なのか」という情報です。
それ以降の行で

  • タグを追加
  • タイプはグローバル・モディファイアで
  • $プラグイン名::ハンドラ名と結びつける

という定義をします。

尚、YAML形式は改行やインデントの判定がシビアなので、最後を改行しなかったり、インデントに間違ってタブを使ったりすると、あとでアップロードしたときにMovableTypeの管理画面が真っ白になってしまいます。

私はPerlが書けないので、$プラグイン名::ハンドラ名の法則がぶっちゃけ全然わかりませんwwwディレクトリ構造と、スクリプト内で書いた一行目の内容が結びつけられているらしいですが。

実際の処理を書く

次に、「lib」>「プラグイン名(ここではConvertCharWidth)」という二階層のディレクトリを追加し、その中に、以下のようにスクリプトを書いた「Plugin.pm」を保存しました。

package ConvertCharWidth::Plugin;

use strict;
use utf8;

sub convert_width {
    my ($text, $arg, $ctx) = @_;

    if ($arg eq 'a') {
        $text =~ tr/A-Za-z0-9/A-Za-z0-9/;
    }
    elsif ($arg eq 'A') {
        $text =~ tr/A-Za-z0-9/A-Za-z0-9/;
    }
    return $text;
}

1;

出力してみる

プラグインができたら、アップロードして「システム」メニュー(ウェブサイトやブログじゃないです)のプラグイン一覧へ行ってみると、冒頭のスクリーンショットのようにプラグインが追加されています。

それを確認した後、新規テンプレートを作って、こんな風に書いて試してみました。

<$mt:SetVar name="test" value="ABCABCabcabc123123"$>
<table border="1" celspacing="3" style="font-family: monospace; font-size: 24px;">
<tbody>
<tr>
<th>モディファイアなし</th>
<td><$mt:GetVar name="test"$></td>
</tr>
<tr>
<th>conv_width="A"</th>
<td><$mt:GetVar name="test" conv_width="A"$></td>
</tr>
<tr>
<th>conv_width="a"</th>
<td><$mt:GetVar name="test" conv_width="a"$></td>
</tr>
</tbody>
</table>

プラグインがうまく動作していれば、変数「test」に入った全角・半角まじりの値が、conv_widthモディファイアが「A」だと全部全角に、「a」だと全部半角になります。

私は何度やっても「a」の方がうまくいかなくて煮詰まっていたのですが、プラグインは何の問題もなく、テンプレートを書き間違えていただけでしたorz

感想

プラグイン作成はイメージしていたよりはずいぶん簡単だったのですが、ブロックタグ(ループ関係)やコンディショナルタグ(条件分岐関係)になると、かなり処理が複雑になるようです。

また、ダイナミック・パブリッシングに対応する場合、smartyの書式でPHPも併用しなければならず、WordPressやa-blog cmsと比べると、難易度は高いなーという印象です。

ダッシュボードウィジェットを追加する程度だと、ノンプログラマでもできるようなので挑戦したいところです。

おまけ

ファイル Loveプラグイン

帰宅後に、藤本さんの講演のサンプルをもとに「I love Sapporo :D」と出すだけのファンクションタグ「MT:Love」を追加する、道民しか喜ばないプラグインも作ってみたので置いておきます。