Movable Type 技術情報
ぴろり上西
2011年05月13日
特にプラグインなどの開発中に出くわすことがあって、一般のユーザが普通に使っている分には、おそらく目にすることはないと思います。プラグインのスキーマバージョンが変更されたりすると、データベースのアップグレード処理が走ります。この時、以下のようなエラーが表示されてアップグレードが完了しない、ということがあります。
アップグレード中にエラーが発生しました [Microsoft][SQL Server Native Client X.X][SQL Server]データベースに 'mt_log_upgrade' という名前のオブジェクトが既に存在します。 at C:\vhost\mta\addons\Enterprise.pack\lib/MT/ObjectDriver/Driver/DBD/MSSQLServer.pm line 156.
これはプラグインやMTの論理エラーではなく、データベースに一時テーブルが残ってしまうことが原因です。前回のアップグレード処理の最中に、無理矢理処理を中断するなどすると、mt_xxx_upgrade という一時テーブルが残ってしまい、次のアップグレード処理時に、同名の一時テーブルを作成しようとしてエラーになることが理由です。溜まりに溜まったログなどの巨大なテーブルがある場合に発生しやすいようです。論理バグって感じですかね。
このような時には、SQL サーバに直接ログインして、問題の一時テーブル(mt_xxx_upgrade)を DROP TABLE してやれば解決します。
ぴろり上西
2011年04月22日
MT テンプレートタグの出力結果を Perl の強力な正規表現でゴニョゴニョできる regex_replace モデファイア。みなさん、活用されていますか? この記事では、この regex_replace モディファイアをより簡潔に記述し、より便利に使える小技を紹介します。
本題に入る前に、regex_replace モディファイアの実装をさらっと見ておきます。モディファイアの処理コードは、/lib/MT/Template/Tags/Filters.pm にある _fltr_regex_replace 関数です。最初に、引数の型を調べて、配列変数以外は受け付けません。次に、配列の一つ目の要素($val->[0])を検索パターンとし、配列の二つ目の要素($val->[1])を置換後パターンとしています。検索パターンについては、グローバル処理フラグは特別扱いで、e オプションはセキュリティの面から無視されます。それ以外のオプションはそのまま渡されるようです。置換後のパターンについては、ちょこっと下ごしらえもされただけで、そのまま s/// に渡されて置換後のパターンとして使われています。
もう少し、寄り道をします。regex_replace モディファイアには検索パターン文字列と置換文字列を配列で指定しますが、MT テンプレートタグでの引数の渡し方による制限があります。これは、/lib/MT//Builder.pm の compile 関数にその処理が記述されており、正規表現式を用いてテンプレートタグ中の引数部分を抽出しています。その正規表現式はかなり複雑ですが、端的に言えば「ダブルクォート文字で始まりダブルクォート文字で閉じられるまで、またはシングルクォート文字で始まりシングルクォート文字で閉じられるまでが一つの引数」ということになります。
一般に C 言語や Perl などの多くのプログラミング言語では、クォーテーションされた文字列中にクォート文字自身が含まれる場合、¥ などのエスケープ文字を用いてクォート文字をエスケープすることができますが、MT の引数処理部分では、そういったことが考慮されていません。ダブルクォート文字で始まり、次にダブルクォート文字を見つけると、エスケープの有無に関わらず、無条件で一つの引数の終わりと認識します。つまり、次のような引数指定は不正になります。
# ダブルクォート文字(")をハイフン文字(-)に置換したい
regex_replace="/"/g","-" → ダメ
# エスケープしてみる
regex_replace="/¥"/g","-" → ダメ
# エスケープが足りなかったか?
regex_replace="/¥¥"/g","-" → やっぱりダメ
この問題は以下のように記述することで回避できます。ダブルクォート文字をパラメータ指定の終端として認識されないようにするため、シングルクォート文字を用いてパラメータを指定する方法です。逆にシングルクォート文字が文字列に含まれる場合は、反対にダブルクォート文字でパラメータを指定すればOKです。
# ダブルクォート文字(")をハイフン文字(-)に置換したい
regex_replace='/"/g',"-"
しかし、この方法にも問題が残っており、パラメータ文字列にシングルクォート文字とダブルクォート文字が混在する場合には、同様の問題が発生します。そこで、以下のような記述方法をおすすめします。
<MTSetVarBlock name="regex0">/["']/g</MTSetVarBlock>
<MTSetVarBlock name="regex1">***</MTSetVarBlock>
<MTUnless regex_replace="$regex0","$regex1">"Tom and Jerry"</MTUnless>
→ ***Tom and Jerry***
検索パターンと置換パターンを一旦、変数に保持し、この変数を regex_replace の引数に渡すようにします。この方法を用いることで以下のようなメリットが考えられます。
- 文字列中にシングルクォート文字とダブルクォート文字が混在していても、regex_replace の指定でそれを意識する必要がない
- 複雑になりがちな正規表現式を分離して記述することで、メンテナンス性が向上する
- 長大な正規表現式になると、テンプレート開始タグだけで冗長になり、後続のテンプレート全体の視認性が悪くなる
- MT テンプレートタグを用いて変数展開などを行った結果を正規表現式に取込める
ぴろり上西
2011年03月18日
小粋空間さんの記事で、プラグイン オブジェクトを生成するバリエーションがいろいろと紹介されています。いずれの方法でも、プラグインとして登録でき動作するのですが、今回、その違いでハマったことがあったので情報展開しておきます。
まず、new メソッドによるオブジェクト インスタンスの生成についてですが、これは以下の二つの記述は同じ動作と考えて差し支えありません。ですので、new の位置は今回は特に気にしないことにします。実際、間接オブジェクト形式での記述では動作に違いがあるのですが、ここでは割愛します。
package MT::Plugin::MyPlugin;
my $instance1 = new MT::Plugin::MyPlugin ({...});
my $instance2 = MT::Plugin::MyPlugin->new ({...});
次に以下の二つのプラグインのソースコードです。どちらもやっていることはほぼ同じです。
- package で名前空間を宣言
- MT::Plugins のサブクラスとして宣言
- プラグインのインスタンスを生成
- MT にプラグインを追加
- MT::Plugin::init_app をオーバーライド
するだけの単純なプラグインになります。違いは、new で指定しているクラス名ですが、これらのプラグインを MT に登録すると、確かにプラグイン一覧に表示されますし、特にエラーも発生しません。何が違うのでしょうか?
### src.1
package MT::Plugin::MyPlugin;
use base qw( MT::Plugin );
my $plugin = MT::Plugin::MyPlugin->new ({...});
MT->add_plugin ($plugin);
sub init_app {
# override MT::Plugin::init_app
}
### src.2
package MT::Plugin::MyPlugin;
use base qw( MT::Plugin );
my $plugin = MT::Plugin->new ({...});
MT->add_plugin ($plugin);
sub init_app {
# override MT::Plugin::init_app
}
src.2 の方では、$plugin は MT::Plugin クラスのインスタンスであって、init_app は MT::Plugin::MyPlugin 名前空間に属します。そのため、一見正しく動作しているようですが、MT にしてみれば MT::Plugin::MyPlugin なんていうクラスは知らない訳ですから、init_app がコールバックされません。これに気がつくまで 1 時間浪費しました orz 普通にテンプレートタグを拡張するようなプラグインでは問題になりませんが、少し複雑なことをやろうとして MT::Plugin のメソッドをオーバーライドするような時に問題になります。反対に、package で宣言した名前で new しておけば、どんな場合でも問題は発生しません。
以上を踏まえてプラグインの初期化コードを書くと以下のようになるでしょうか。
### src.3
package MT::Plugin::SKR::MyPlugin;
use base qw( MT::Plugin );
my $plugin = __PACKAGE__->new ({...});
MT->add_plugin ($plugin);
- package で宣言する名前空間には会社名や自分の名前を入れる。他社製の同じ名前のプラグインがあっても名前空間が衝突しにくい。
- new に指定するクラス名は、特殊リテラル __PACKAGE__ を利用する。package 名を変更した時の変更忘れを防げる。DRY。
onagatani
2011年02月14日
最近イベント案内ばかりのながたにです。
という事で今回も個人の活動になりますがイベントのご案内をさせて頂きます。
昨年の4月から開催しているHokkaido.pmですが2/19に#4を開催します。
今回も東京からスーパーハッカーをお招きしますのでPerlを使った事がない人も是非きてください。
以下ご案内になります。
テーマ 「初心者OK! 趣味と実益を兼ねたPerlWebサービス開発」
今回は午前午後の2部制になります。
AMハンズオン(初心者向け)、atndは必要ないので直接お越しください。20名の部屋になっています。
PMテックトーク(atnd必須。午前午後でルームが違います。電光掲示板に表示されていますのでご確認下さい)
ゲストスピーカー:yusukebeさん!
「エロサイト管理者の憂鬱3 - エロくない7つの開発することについて」
午前の部(会場費1500円を参加者で割り勘。学生無料)
1・9:00 開始 初心者向けハンズオン(ハッカソン) charsbarさんのMojolicious::Liteのハンズオンあるよ!
2・11:50 撤収
3・12:00-13:00 ランチ(産業振興センター内のラウンジ 飲食は隣の商業施設で購入できます)
午後の部
参加費:700円(学生参加費無料、JPAからの講師派遣費用+会場費を割り勘で)
懇親会:3500円(2次会については希望者のみ)
学生さんはコメントに書いてください
1・13:00 - 13:30 会場設営・受付
2・13:30 - 13:40 本日の進行とかご挨拶
3・13:40 - 14:10 やまかわさん「関数型プログラミング」
4・14:10 - 14:30 いとうさん
5・14:30 - 14:35 休憩(時間調整)
6・14:35 - 14:45 keroyonnさん「未定」
7・14:45 - 14:55 aloelightさん「CPAN/便利モジュール」
8・14:55 - 15:35 charsbarさん「初心者向けセッション」
9・15:35 - 16:15 yusukebeさん「エロサイト管理者の憂鬱3 - エロくない7つの開発することについて」
10・16:15 - 16:20 休憩
11・16:20 - 16:30 LT hotwater_morningさん、techno_nekoさん
12・16:30 - 16:40 抽選会!
13・18:30 - 20:30 懇親会:春花秋灯 すすきの南5条店
今回は抽選会にJPAから頂いたYAPC Tシャツ(2009年度)をプレゼントしちゃいます!
いまの所、参加枠残り5名なのでお早めにどうぞ。
SKYARCでは個人の技術的な活動を支援する制度や社風があり、
自分も積極的にこういった活動を行っています。
勉強会やイベントに消極的な企業様もありますが活動に熱心なエンジニアの皆さんをSKYARCでは募集しております。
気になる方はrecruit@skyarc.co.jpまでお気軽にご連絡ください。
では宜しくお願いします!
onagatani
2011年02月02日
久しぶりにブログに登場しましたながたにです。
北海道では流氷が接岸するなど寒さが大変厳しくなってまいりましたが、皆さん元気ですか?
所で、先月1/26にMovableType勉強会キックオフMTG開催させて頂きました。
事前告知をほとんど行わず前日にメールで開催をお知らせする等ゲリラ的なキックオフでしたが、
十数名の方にお集まり頂きました。
弊社では昨年にも札幌産業振興センターにてMTの勉強会を一度行っているのでですが、
昨年のMTDDC Hokkaidoを機にgoogle groupを作成してみました。「google group MT勉強会」
大きなサイトでのMTの活用ノウハウやテンプレート再入門など、実践的な勉強会を行っていく予定です。
世の中には色々なCMSがありますが、興味がある方は是非ご参加ください。
第一回目の勉強会は来月中に開催予定なので、決定次第google group及びこちらで告知させて頂きます。
スピーカーをやってみたい!という人がいましたら是非google groupに書いてください!
ではでは宜しくお願いします。
<追記>
参加された皆様のエントリーをまとめます
http://solution.datacraft.co.jp/blog/2011/02/movabletypemtg.html
http://www.nekonotechno.com/nekopress/?p=998