印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
MovableType 再構築失敗は去年の記事が原因

テンプレートを変更した訳でもないのに,今日になって突然再構築に失敗するようになってしまった。原因は去年の記事のタイトルだった。

■ ■ ■

今日,Movable Type でメインインデックスを再構築しようとすると,見たことのないエラーで失敗するようになってしまった。テンプレートもソースも変更していないのに,突然そうなった。次のエラーメッセージが表示される。今までに見たことのないメッセージである。Perl が出しているメッセージのようだ。

An error occurred:
テンプレート 'Main Index' の作成に失敗しました:
MT::App::CMS=HASH(0x8ed1410) Bareword found where operator expected at (eval 1576) line 8, near "'2004:

環境は,Movable Type 2.661,Perl 5.8.2,関連プラグインは,Brad Choate: MTOnThisDayBrad Choate: PerlScript Plugin である。

エラーメッセージの内容で見当がつかない場合,有効なのはコマンドラインからの再構築である。それには mt-rebuild を使う (nlog(n): cron でインデックスを再構築)。mt-rebuild でメインインデックスの再構築を行った結果は次ようになった。

$ mt-rebuild.pl -mode="index" -blog_id=1 -template="Main Index"
Bareword found where operator expected at (eval 12) line 8, near "'<a href="http://nlogn.ath.cx/archives/2004_12_24.html" title="2004&#24180;12&#26376;24&#26085;"><strong>2004:</strong></a><br /><a href="http://nlogn.ath.cx/archives/000358.html" title="X'mas"
        (Missing operator before mas?)
Unquoted string "mas" may clash with future reserved word at (eval 12) line 8.
Rebuild error: Build error in template 'Main Index': Error in <MTPerlScript> tag: Error in PerlScript tag: Unrecognized character \xA4 at (eval 12) line 8.

「mas」が引用符にくくられていない旨のメッセージが表示されている。原因は,記事番号 000358 の,タイトルが「X'mas ではなく Xmas」の記事である。これはちょうど1年前の今日書いた記事である。メインインデックスには,1年前の記事を MTOnThisDay プラグインを使って表示している。これが原因である。テンプレートは次のようになっている (nlog(n): おかげさまで1周年 - 去年の今日を表示する)。

<div class="sidetitle">
On This Day
</div>
<div class="side">
<MTPerlScript>
$a = '<MTOnThisDay><MTEntries days="1"><MTDateHeader><a href="<$MTEntryLink archive_type="Daily"$>" title="<$MTEntryDate format="%x" language="jp"$>"><strong><$MTEntryDate format="%Y"$>:</strong></a><br /></MTDateHeader><a href="<$MTEntryLink$>" title="<$MTEntryTitle$>"><$MTEntryTitle$></a><br /></MTEntries></MTOnThisDay>';
if ($a =~ /\S/) { print "$a"; } else { print "no entries"; }
</MTPerlScript>
</div>

このままだと構造が分かりにくいので,概要を書くと次のようになる。

<MTPerlScript>
$a = '(MTOnThisDay の出力)';
if ($a =~ /\S/) { print "$a"; } else { print "no entries"; }
</MTPerlScript>

$a に MTOnThisDay の出力を代入し,$a が空でなかったらその文字列を表示し,$a が空だったら「no entries」を表示するようになっている。この場合分けは MTOnThisDay だけではできないので,PerlScript プラグインを使っている。

問題は,1年前の記事のタイトルが「X'mas ではなく Xmas」だったことである。アポストロフィ「'」がタイトルに含まれている。これは単一引用符でもあるので,$a に代入する文字列に単一引用符が含まれていると,文字列がそこで終わってしまう。すると,Perl はそれに続く「mas」は文字列以外として扱うために,意味を解釈できずエラーを出すことになる。このエラーが上記のエラーである。

解決方法は,「'」を単一引用符でなくせばよい。文字実体参照「&apos;」で表現すれば,HTML のソースでは「&apos;」となり,Web ブラウザでは「「'」と表示される。このように出力するには,<$MTEntryTitle$> を <$MTEntryTitle encode_xml="1"$> に書き換えればよい(Movable Typeユーザー・マニュアル: テンプレート・ タグ - グローバル・タグ・アトリビュート)。

<div class="sidetitle">
On This Day
</div>
<div class="side">
<MTPerlScript>
$a = '<MTOnThisDay><MTEntries days="1"><MTDateHeader><a href="<$MTEntryLink archive_type="Daily"$>" title="<$MTEntryDate format="%x" language="jp"$>"><strong><$MTEntryDate format="%Y"$>:</strong></a><br /></MTDateHeader><a href="<$MTEntryLink$>" title="<$MTEntryTitle encode_xml="1"$>"><$MTEntryTitle encode_xml="1"$></a><br /></MTEntries></MTOnThisDay>';
if ($a =~ /\S/) { print "$a"; } else { print "no entries"; }
</MTPerlScript>
</div>

トラックバックやコメントは他のサイトから飛んでくるので,「encode_xml="1"」をつけていたが,タイトルは自分でつけるのでこのようなことはないと思っていた。落とし穴だった。

PerlScript プラグインを使っていない場合は,このような問題は発生しない。

2006年1月28日追記:

encode_xml 属性はつけない方がいいということが分かりました。「'」は手入力で「&apos;」とした方がいいです(nlog(n): encode_xml 属性の扱いの難しさ)。

<div class="sidetitle">
On This Day
</div>
<div class="side">
<MTPerlScript>
$a = '<MTOnThisDay><MTEntries days="1"><MTDateHeader><a href="<$MTEntryLink archive_type="Daily"$>" title="<$MTEntryDate format="%x" language="jp"$>"><strong><$MTEntryDate format="%Y"$>:</strong></a><br /></MTDateHeader><a href="<$MTEntryLink$>" title="<$MTEntryTitle$>"><$MTEntryTitle$></a><br /></MTEntries></MTOnThisDay>';
if ($a =~ /\S/) { print "$a"; } else { print "no entries"; }
</MTPerlScript>
</div>
Posted by n at 2005-12-24 22:52 | Edit | Comments (0) | Trackback(0)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
Comments
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


(必須, 表示されません)


(任意, リンクされます)


Confirmation Code (必須)


Remember info (R)?