MovableTypeの最近のブログ記事

Movable Type 4対応

| コメント(0)

Movable Type 4(以下MT4と書く)ではエディター機能が向上したり、ブログ記事でない一般のファイル作成機能がついたり、いろいろおもしろそうだったので現在テスト公開中のベータ版を試してみることにした。

まず気がついたのが標準テンプレートの構成の変化で、従来はカテゴリーアーカイブとかメインインデックスとかテンプレートごとにほぼ完全に独立していたが、MT4では逆にここのテンプレートはパラメータの宣言と共通モジュール呼び出しだけになっていって、共通モジュールの方に実際の出力内容を記述する形だ。テンプレートでは、パラメータで分岐したり、ループをまわしたりなどプログラム言語的な柔軟な記述ができるので、共通モジュール1つをあちこちで使い回すことが可能になっている。エントリーの体裁を変えるのに、従来は関連するすべてのテンプレートを修正する必要があったが、MT4の標準テンプレートでは、モジュールだけ直せばいいのだ。

あと、従来もがんばればできたのかもしれないが、MT4では年別や月別のカテゴリーアーカイブを作る機能が標準で用意されている。これはカテゴリー内のエントリー数が異常に多いこのサイトにはとてもありがたい機能だ。今までは年ごとのサブカテゴリーにわけていたが、今度からは一括で管理することができる。

なんだかうれしくなって、まだベータ版なのに早々と移行してしまうことにした。テンプレートを新しい形にして、カテゴリーを整理して、個々のエントリーのURLも見直して、息も絶え絶えという感じになってしまったが、とりあえずいったんは移行が完了した。しかし、その時点ではベータ5を使っていたのだが、移行が完了したのとほぼ同時にベータ6がリリースされていることを発見した。バグフィックスだろうと高をくくっていたが、中をのぞいてみたらテンプレートに大きな変更があった。ベータ5までは、構成はともかく生成するファイルはMT3までと互換性がとれている形だったのだが、ベータ6でなぜか互換性がなくなっている。表示が乱れるので、泣く泣く、ベータ6にあわせてテンプレートを見直したのだった。

それ以外にも動かない機能とか整合性がとれていない箇所がいくつかあって、まだまだ正式リリースまでには紆余曲折がありそうな感じだ。一応開発元にフィードバックしておいたが、こちらの環境(Perl:5.8.8 ,DB:DBD::SQLite 1.13)では具体的に以下の障害が発生している。

  • ブログ記事一覧をカテゴリーで絞り込むとエラー←Beta7でフィックス
  • ウェブページの公開は成功するものの、実際にファイルは作成されていない。指定したファイル名が取得できてないようだ。 ←アーカイブマッピングを指定していないせいでした
  • 標準テーマのCSSで.asset-name aがdisplay:blockとして指定されている
  • base_theme.cssで主要なタグのスタイルがリセットされているがテーマ側で設定しきれていない
  • Beta7よりスタイル選択で一緒にレイアウト(2カラム or 3カラム)も指定するようになっているが、そのためテンプレートごとに別のレイアウトを選べなくなっている
  • Beta7ではテンプレートの編集画面で「テンプレートの更新」ボタンをおしても何も起きない

なお、今回の対応で各エントリーのURLが全面的にかわっているが、旧URLでアクセスした場合、新URLにリダイレクトするようにしたつもりだ。問題があれば教えてほしい。

カテゴリ内の前後のエントリーを自動的にリビルドする」で公開していたRebuildPrevNextInCategory.plにはエントリー作成直後の保存時に動作しないという問題があった。さらに、エントリー削除時にもまともに動作していなかったようだ。原因も追及せずずいぶん長い間放置してしまったいたが、hPodのhiroakiさんが原因を調べてくださり、なおかつ問題を回避した実現方法の提案までしてくださった。まずはhiroakiさんに感謝したい。

さて、それをヒントに、今回あらためてRebuildPrevNextInCategory.plを作成し直した。エントリー作成直後でも、削除時でも動作するはずだ。また、複数のカテゴリーに属する場合はそれら全カテゴリーの前後のエントリーを再構築するようにしている。これで、EntryCategoryLinks以外の複数カテゴリーに対応した「前後のエントリーをカテゴリー内にする」プラグインと組み合わせても使えるようになった。

ついでに、このサイトにおけるカテゴリーのポリシーについて書いておくと、基本的に1つのエントリーは閲覧者に見えるカテゴリーとしては1つのみに属するようにしている。副カテゴリーは注目記事とか、共通のデザインを適用したいとか、カテゴリー横断的にエントリーをグループ化する目的に利用している。ひとつのエントリーが複数カテゴリーに属するという形は、少なくとも静的にファイルを作成するシステムの場合は、ファイルの帰属先が1つに定まらずあまり美しくないと思うのだ。

ダウンロード

参考

MovableType最新事情

| コメント(0)

MovableTypeのカスタマイズについていろいろ書き散らしているが、一時は採用したものの、今ではもう別の方法に乗り換えたというものが案外多い。そのあたりを含めて、ここで現在のカスタマイズの状況を整理しておくことにする。

Amazonからの情報取得・表示Markdownは今では使っておらず、代わりにmt-sukeroku2を使っている。hatenaやpukiwikiの書式に準じた形式でエントリーを書くことができ、amazonへリンクするための専用の書式も用意されている。まだベータ版でいくつか不具合や物足りないところもあるが、要望を出している(HSJ.jpでしつこく相手にされないコメントを書いているssugiという人物はぼくだったりする)のでたぶん正式版では改善されるだろう。

サブカテゴリーについても若干方針を変えた。最新の年度のカテゴリーの下に並列に過去の年度をぶらさげて、トップページからアクセスできるようにしている。考えてみればその方がシンプルだ。

トラックバックスパム対策は紹介していたmt-spamstop-tbではなく、naoyaのはてなダイアリー - Movable Type で言及リンクのない TrackBack ping を弾くプラグインを最近まで使っていた。つまり、トラックバック元のエントリーにこちらのURLが含まれていなければ、自動的にはじいていたわけだ。

トラックバック送信の正当な目的には大きく2つあると思っていて、ひとつは言及したことを知らせるという目的。もうひとつは、トラックバック先のエントリーの筆者または読者に関連する有用な情報を知らせるという目的だ。この2つの目的を両方満たしているトラックバックが望ましいと思うけど、どちらか一方でも構わないとは思う。だが、心を鬼にして、1番目の目的を満たすトラックバックのみを許可していたのだった。

現在は、MovableType3.2の機能を使って、すべてのトラックバックを受け付けるものの、その場では掲載せず、後刻こちらが許可したもののみ掲載している。もちろん、掲載の基準は上記の目的のうちどちらかひとつを満たしていることだ。

ついでに、最近試そうとした、ダイナミックページについて書いておこう。ダイナミックページを使えば、ページをいちいち静的に構築しておかなくても、閲覧者がアクセスするときに動的に生成されるようになる。このサイトはエントリーの数がやたら多くて、再構築がとても時間がかかるので、動的生成はありがたい。PHPやmod_rewriteが必要で、サーバ環境に要求している敷居が高く、どこでも実現できるわけではないが、このサイトをおいているsakura.ne.jpでは平気なはずだった。ところが、いまだに動的生成ができていない原因は、プラグインだ。動的生成はPHPで動いているので、通常のPerlのプラグインではなく、同機能をPHPで実装したプラグインが必要になるのだ。簡単な機能なら実装できるし、ネットにもいくつかころがっているけど、さすがにmt-sukeroku2相当のものはなかった。それで、すっぱりとあきらめたのだった。

カジノだのポルノだのバイアグラだの海岸のゴミのように寄せてくるトラックバックスパムを毎回消してまわるのにうんざりしたので、対策をうつことにした。

見つけたのは以下のプラグイン。

導入は簡単で、プラグインディレクトリにmt-spamstop-tb.plというファイルを置くだけだ。これで以下のようなトラックバックをシャットアウトすることができる。

  • 概要に'<a>'というタグが含まれる。
  • ブログ名またはタイトルが空白
  • URLのブラックリスト(mt-spamstop-tb.plの末尾に記述する)にマッチする。

最初の仕様は若干微妙だが、少なくともこれまできたまともなトラックバックにhtmlのタグが含まれていたことはない(逆にスパムにはほとんど含まれている)のでまず問題ないだろう。

導入してからも相変わらずトラックバックスパムがきているのでおかしいなと思ったら、間違えて同じ人が作成したコメントスパム用のプラグインをいれてしまったことが判明。なんたる間抜け。上記の記事も直しました。

サブカテゴリー

| コメント(0)

このサイトでは、あるカテゴリーのエントリー数が400を越えてしまうので、年ごとに別々のカテゴリーをたてていた。だがそうするとカテゴリー数が増えてみにくくなってしまう。ジレンマだ。どうしようかと考えているときに知ったのが、MovableType 3.1ではサブカテゴリーというカテゴリー間の階層構造が導入されるというニュースだ。

この実装を担当しているのは、David Raynesという現在Subcategoriesというプラグインを開発している人なので、その仕様がそのままとりこまれると考えてよさそうだ。先取りして試してみることにした。

最初に考えたのは、全体を束ねるスーパーカテゴリーを新設して、その下に年ごとのカテゴリーをぶらさげる方法だ。だが、それだとスーパーカテゴリーの下にはひとつもエントリーが作成されないということになる。MovableTypeでは直下にひとつもエントリーが存在しないと、カテゴリーアーカイブは正常に作成されないのだ。もちろん無理矢理エントリーをいれることはできるが美しくない。

そこで考えたのが、ある年のカテゴリーを翌年のカテゴリーの下にどんどんぶらさげていく方法。つまり、2003年のカテゴリーは2004年のサブカテゴリーとなり、2002年のカテゴリーは2003年のカテゴリーのサブカテゴリーとなる。MainIndexからは最上位、つまり最新の年のカテゴリーアーカイブにリンクをはり、各カテゴリーアーカイブでは、自分以下のサブカテゴリーすべてとひとつ上位のカテゴリーのアーカイブにリンクをはる。この方法の利点は、年がかわってカテゴリーがふえても、作り直すカテゴリーアーカイブは直近のひとつだけでいいことだ。

MainIndexテンプレートのカテゴリー一覧は次のように記述している。

<MTTopLevelCategories>
  <a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryCount$>"><$MTCategoryLabel$></a>
</MTTopLevelCategories>

カテゴリーアーカイブテンプレートの親子関係のリンクは次のように記述している。

<MTHasParentCategory>
  <h2>親カテゴリー</h2>
  <ul>
    <MTParentCategory> 
      <li>
        <a href="<$MTCategoryArchiveLink$>"><MTCategoryLabel></a>
      </li>
    </MTParentCategory>
  </ul>
</MTHasParentCategory>
<MTHasSubCategories>
  <h2>サブカテゴリー</h2>
  <ul>
    <MTSubCategories> 
      <li>
        <a href="<$MTCategoryArchiveLink$>"><MTCategoryLabel></a>
      </li>
      <MTSubCatsRecurse>                  
    </MTSubCategories>
  </ul>
 </MTHasSubCategories>

Markdown

| コメント(0)

変なこだわりのせいもあるが、このところこのMovableTypeの更新が面倒で仕方なかった。面倒というより、心理的障壁が高いといった方が正確かもしれない。今、その障壁を少しでも下げるべく努力していて、その一つがカテゴリ内の前後のエントリーを自動的にリビルドするだった。

もう一つ不便に思っているのがエントリーの書式だ。普通の段落を続けるだけなら "Convert Line Breaks" でも十分だが、箇条書きや表をいれようとすると、結局「なし」にせざるを得なくなり、html でごりごり書かざるを得なかった。

そこで最近みつけたのが Markdownだ。このプラグインを使うと、プレインテキストの形式で入力した文章をxhtmlに変換してくれる。もちろん規則はあるのだが、覚えやすいし、自由度が高い。同種のものはほかにもいくつかあるが、変換せずに通常のテキストとして読んだときの違和感が比較的少ないのではないかと思う。たとえばリンクはこんな感じだ。

[Markdown](http://daringfireball.net/projects/markdown/)

箇条書きは以下のような感じ。

* リスト1
* リスト2

詳しくはSyntaxを参照。

なお、日本語を扱う場合、Perl5.8ならそのままで平気だが、Perl5.6では17行目の"use utf8;" という行をコメントアウトする必要がある(残念ながら Perl5.005以前では動かないと思う)。

このエントリーの内容は古いです。最新の情報はこちらを参照してください。

前後のエントリーをカテゴリー内にする」に書いた方法には欠点があって、カテゴリー内の一つ前のエントリーを(途中にエントリーを追加する場合は一つあとも)いちいち手動で更新してやらなければいけなかった。

MovableType 2.Xの時代、MovableTypeのソースを変更して自動的にリビルドする方法をいくつかのサイトで見かけたが、ソースを変更してしまうとバージョンアップのときに何かと大変だ。MovableType 3.0 になって同様なことがプラグインでできるようになっていることがわかった。見よう見まねで作ってみたので一応公開することにする。

以下の RebuildPrevNextInCategory.pl というファイルを MTのplugins ディレクトリに置くだけでOKだ。もちろん、EntryCategoryLinksと併用することを想定している(なくても動くけど意味がない)。

**追記(2004-08-05)

エントリー初期登録時にエラーになるバグがあったので修正しました。

**追記(2005-01-01)

  • 削除時にも前後のエントリーを自動でリビルドするようにしました。
  • 公開されていないエントリーは無視するようにしました。
  • versionは 1.01 にします。

**MovableType3.2対応(2005-09-20)

  • しました。

**もろもろ(2005-10-05)

  • 場合によってリビルドされないバグを修正しました。というより以前はたまたま動いていただけでした。すみません。
  • 直前、直後のエントリーの場合はMovableTypeにまかせて、このプラグインではリビルドしないようにしました。

**結局(2006-01-15)

  • どうやら初回保存のときは100%プラグインが動作しないようです。エントリーが一度も保存されていない状態だと、カテゴリーがうまく取得できないのかもしれません。当面、エントリー作成直後は未公開状態で保存してから、公開するようにしてください。
  • バージョンを1.2に戻します。

AmazonからWebサービス経由で情報取得して表示するプラグインがぼくの知る限り2つある。ひとつはMTAmazonで、もうひとつはaws.plだ。前者はそのままでは日本語は通らないが、後者は日本の方が作っているので、そのままで日本語が通る。もちろん最初は後者を使ってみた。

セットアップは簡単で、aws.plをpluginディレクトリに置くほかは、XML::Simpleというモジュールを入手して、extlib/XMLなどに置くだけでいい。

ところが、いざ記述して使おうとしたら、まるっきり無視された。どうしてかなと数時間考え込んでしまったが、わかってみれば、それもそのはず、ぼくはエントリーの方にタグを書いていたのだった。そうではなく、Movable Typeのタグはすべてテンプレートの方に書かなければいけない。

とはいうものの、それではトップページなどで決まりきったアイテムを紹介するという用途にしか使えないので、ありがたみが半減だ。エントリーの方にタグを記述できるようにするProcess Tagsというプラグインを見つけて、それを使えば、エントリーごとに個別にAmazonの情報を取得・表示できそうなのはわかったが、そんなことをするくらいなら、Webサービスを使わず、自分でWWWで検索した結果をはりつけてもそんなに手間は変わらない。やはりテンプレートに指定するのが正しい使い方だという結論に達した。

では、どう使うか?aws.plの方は、検索アイテムを外部から引数として渡すことができなそうだったので、MTAmazonを使うことにした。MTAmazonならMovale Typeの任意のタグの値を読み取って利用することができるのだ。さきほど書いたように日本語で利用するにはextlib/MTPluginsに置く、MTAmazon.pmの修正が必要だが。バージョン2.22からの修正点は以下の通り(国際化、地域化を考慮したまともな修正ではなくQuickHackだ)。

*** MTAmazon.pm.old     2002-11-06 21:41:44.000000000 +0900
--- MTAmazon.pm 2003-11-24 02:41:51.000000000 +0900
***************
*** 169,172 ****
--- 169,173 ----
          $ctx->stash('AmazonItem', $i);
          my $out = $builder->build($ctx, $tokens);
+         $out = Jcode->new($out,'utf8')->utf8;
          return $ctx->error( $builder->errstr ) unless defined $out;
          $prod .= $out;
***************
*** 368,373 ****
!   my $url = "http://xml.amazon.com/onca/xml3?t=$associateid&" .
          "dev-t=$devtoken&" .
          "$method=$search&" .
!         "mode=$line&type=$format&page=$page&f=xml";
      $url .= "&sort=$sort" if $sort;
      $url .= "&offerstatus=open" if ($method eq 'SellerSearch');
--- 369,374 ----
!   my $url = "http://xml.amazon.co.jp/onca/xml3?t=$associateid&" .
          "dev-t=$devtoken&" .
          "$method=$search&" .
!         "mode=$line&type=$format&page=$page&f=xml&locale=jp";
      $url .= "&sort=$sort" if $sort;
      $url .= "&offerstatus=open" if ($method eq 'SellerSearch');

utf8のところはそれぞれサービスに利用している文字コードを指定する必要がある。

2004年3月22日前後より、xml.amazon.com のURLでは"locale=jp"を指定できなくなったので xml.amazon.co.jp を指定するようにした。

さて、このサイトでは、以下のようにしてカテゴリーが「読書ノート」の場合のみ、エントリーのキーワードに指定された項目をAmazonで検索した結果を表示している。

<MTIfCategory name="読書ノート">
<MTAmazon method="Asin" search="[MTEntryKeywords]" >
<div class="amazon">
  <a href="<MTAmazonLink>"><img src="<MTAmazonImage>" /><div><$MTAmazonTitle$></div></a>
</div>
</MTAmazon>
</MTIfCategory>

カテゴリーで遊ぼう

| コメント(0)

Movable Typeネタの3回目はカテゴリーごとに見せ方を変える方法を紹介する。

Movable Typeの世界ではかなりの有名人らしいBrad Choateという人のSupplemental Category Tagsというプラグインを使えば、ある特定のカテゴリに属する場合のみある内容を出力し、逆に属さない場合のみ出力するといったようなことができる。

たとえば、「読書ノート」というカテゴリーに属す場合のみbook.jpgというイメージファイルを表示したいのなら、以下のようにMTIfCategoryタグを使えばよい。

<MTIfCategory name="読書ノート">
<img src="book.jpg" />
</MTIfCategory>

カテゴリーの一覧で、先頭が"_"からはじまるカテゴリーを表示させないためには、以下のようにMTIfNotCategoryを使い、pattern属性に正規表現を指定すればよい。

<MTCategories>
<MTIfNotCategory pattern="m/^_.+/">  
<li><a href=" <$MTCategoryArchiveLink$>"><$MTCategoryLabel$>( <$MTCategoryCount$> )</a></li>
</MTIfNotCategory>
</MTCategories>

ただし、このように pattern属性で正規表現を指定するには同じ Brad Choate氏作成のRegex Pluginが必要である。

このプラグインを使って主カテゴリーと副カテゴリーの指定を工夫すればかなり柔軟に表示方法のカスタマイズができると思う。

Individual Archiveのデフォルトのテンプレートでは、以下のように同じBLOG内の前後の記事にアクセスできるようなリンクが用意されている。

<div id="menu">
<MTEntryPrevious>
<a href="<$MTEntryPermalink$>">≪ <$MTEntryTitle$></a> |
</MTEntryPrevious>
<a href="<$MTBlogURL$>">Main</a>
<MTEntryNext>
| <a href="<$MTEntryPermalink$>"><$MTEntryTitle$> ≫</a>
</MTEntryNext>
</div>

うちはカテゴリーごとの独立性が高いので、同じカテゴリー内だけで前後に移動させたいと思い、いろいろ調べていたら、前回紹介したEntryCategoryLinksが見つかった。最初使い方がよくわからなかったのだが、この台湾の方のBLOGを見つけて問題解決(ちなみに中国語はちんぷんかんぷんだがこういう話題ならどうにかわかるものだ)。

このサイトではEntryCategoryLinks.plをpluginディレクトリに置いたら Movable Type の管理プログラムそのものが実行できなくなってしまったのだが、その場合、EntryCategoryLinks.plからuse warning;という行を削除する。

記述は以下の通り。全体をMTEntryPrimaryCategoryで囲むのがポイント。BLOGのMAINの代わりにカテゴリーのMAINページに飛ぶリンクを追加している。

<div id="menu">
<MTEntryPrimaryCategory>
<MTEntryPrevInCategory>
<a href="<$MTEntryPermalink$>">≪ <$MTEntryTitle$></a> |
</MTEntryPrevInCategory>
<a href="<$MTCategoryArchiveLink$>"><$MTCategoryLabel$></a>
<MTEntryNextInCategory>
| <a href="<$MTEntryPermalink$>"><$MTEntryTitle$> ≫</a>
</MTEntryNextInCategory>
</MTEntryPrimaryCategory>
</div>

ただし、この方法の欠点として、新しく追加したエントリーのカテゴリー内におけるひとつ前のエントリーは自動的には更新されないので、そのままだと「次へ」のリンクがないままになってしまう。いちいち保存して再構築してやらなければならないのがとても面倒だ。

Movable Typeで運用されているサイトの特徴として、たいてい「MovableType」というカテゴリーがあり、Movable Typeのノウハウがまとめられているということがあげられる。このサイトもその例にもれず、ここまでサイトを作り上げるのに使ったテクの数々を公開しようと思う。

まずはカテゴリー名を日本語等非アスキー文字にする方法。

単に名前をつけるだけなら日本語でもウルドゥー語でも入力することができるが、問題はファイル名だ。デフォルトではカテゴリーアーカイブのファイル名は “cat_カテゴリ名.html”となっていてカテゴリ名に日本語が含まれると、その部分は取り除かれる。つまりすべて日本語の場合は、“cat_.html”となって、そのようなカテゴリーが複数ある場合は同じファイル名となり上書きされてしまう。

解決方法は3通りある。

  1. カテゴリー名のつけかたを工夫する。カテゴリーに必ず他とかぶらないユニークなアスキー文字を含むようにする。
  2. ファイル名のテンプレートをカスタマイズし、カテゴリー名以外の属性(カテゴリーIDカテゴリーの説明)をベースに名前をつけるようにする。
  3. カテゴリー名はアスキー文字とし、カテゴリーの説明に日本語名を書いておく。表示するときはカテゴリ名ではなくカテゴリの説明を使う。

このサイトで採用したのは2番目の方法で、IDだと無意味な連番の整数になってしまうので、カテゴリーの説明の欄にアスキー文字を指定してファイル名として使っている。余計な制約がなく、手をいれる箇所が少ないのが採用した理由だ。Category Archiveのファイル・テンプレートには以下のように指定している。

<$MTCategoryDescription$>/index.html

また Individual Archiveの方も以下のようにカテゴリーごとのディレクトリの下に作成するようにしている。

<MTEntryPrimaryCategory><$MTCategoryDescription$></MTEntryPrimaryCategory>/<$MTEntryID zero_pad="6"$>.html

MTEntryPrimaryCategory はエントリーが属する主カテゴリーのコンテキストに入るためのタグで、EntryCategoryLinksというプラグインの中に含まれる(このプラグインのおいしいところは実はほかにある。それについては別途紹介予定)。エントリーが属するカテゴリーが1つなら標準の MTEntriyCategoriesを使ってもいいが、副カテゴリーを持つ場合は結合されてしまうので、こちらの方がおすすめだ。