印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
MovableType 同一カテゴリの前後ナビゲーションと自動再構築

Movable Type のウェブログには、時系列に並んだ前後の記事に移動するための、ナビゲーションメニューがついている。前後の記事の移動をカテゴリ内に限定させたいと思う人は多いようで、プラグインも複数開発されているが、記事のカテゴリが複数の場合にどうするかという問題や自動再構築に関する問題がある。Ruby site: 複数Categoryなページめくりの再構築(修正) は、この問題を見事に解決している。

■ ■ ■

カテゴリ内をページ移動するためのプラグインは次の2種類がある。

chez sugi: 前後のエントリーをカテゴリー内だけにする では、EntryCategoryLinks プラグインの使い方が紹介されている。そこで指摘されている通り、カテゴリ内の1つ前の記事は再構築されない。したがって、1つ前の記事からのリンクは更新されないという問題がある。

PreviousNextInCategory プラグインでも同様の問題がある。さらに、一歩踏み込んだ問題としては、複数のカテゴリが設定されている場合、リンクを辿っているうちに別のカテゴリに移ってしまう場合がある。先の EntryCategoryLinks プラグインでは、主カテゴリの前後リンクしか作れないためこの問題は起こらない。ただ、不便ではある。

Ruby site さんは、この2つの問題を

することで解決している。

Ruby site: 複数Categoryなページめくりの再構築(修正) での MT.pm の修正はよく考えられていて、同じカテゴリの1つ前の記事を探す際に、「同じカテゴリの記事であっても、直前の場合は除く」として最適化されている。

このサイトでの導入事例は以下の通り。

PreviousNextInCategory プラグインをインストールする (phil ringnalda dot com: Previous and next in category)。

PreviousNextInCategory プラグインに一部手を加える (Ruby site: 複数Categoryなページめくり より)。赤字部分を追加する。

sub _hdlr_entry_previous_in_category {
...
    my $cat = $e->category
                    or return '';
   if ($ctx->stash('category') ne '') {$cat = $ctx->stash('category');}
    my $prev = $e->previous(1);
...
}

sub _hdlr_entry_next_in_category {
...
    my $cat = $e->category
                    or return '';
   if ($ctx->stash('category') ne '') {$cat = $ctx->stash('category');}
    my $next = $e->next(1);
...
}

MTPath/lib/MT.pm に赤色部分を追加 (Ruby site: 複数Categoryなページめくりの再構築 から一部書き換えているが、やっていることは同じ)。赤字部分を追加する。

    return 1 unless $param{BuildDependencies};

   my $cats = $entry->categories;
# previous
    for my $cat (@$cats) {
        my $prev = $entry->previous(1);
        if ($prev && !$prev->is_in_category($cat)){
            do {
                $prev = $prev->previous(1);
            } while ($prev && !$prev->is_in_category($cat));
            if ($prev) {
               $mt->_rebuild_entry_archive_type(Entry => $prev,
                   Blog => $blog,
                   ArchiveType => 'Individual')
                   or die $mt->errstr;
            }
        }
# next
        my $next = $entry->next(1);
        if ($next && !$next->is_in_category($cat)){
            do {
                $next = $next->next(1);
            } while ($next && !$next->is_in_category($cat));
            if ($next) {
               $mt->_rebuild_entry_archive_type(Entry => $next,
                   Blog => $blog,
                   ArchiveType => 'Individual')
                   or die $mt->errstr;
            }
        }
    }


    ## Rebuild previous and next entry archive pages.

ただし、この修正を行うと、PreviousNextInCategory プラグインが使用されているかどうかに関わらず、同じカテゴリに属す前と後の記事の自動再構築を行うようになる。プラグインの使用をやめる場合、効率を考えれば MT.pm も元に戻しておいた方がよい。プラグインで呼び出されるときだけカテゴリ内前後の再構築が行われると嬉しいのだが…。Ruby site: 複数Categoryなページめくりの再構築(プラグインありなし判定)で解決されています(トラックバックで教えてもらいました)

最後に、個別記事用のテンプレート Individual Archive Template を編集し、ナビゲーションメニューを追加する。 サイドバーに設置し、カテゴリ表示に画像を使っている。

<div class="sidetitle">
Navigation
</div>
<MTEntryCategories>
<div class="side">
<a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryLabel$> カテゴリの記事一覧">
<img src ="/mticons/<$MTCategoryLabel$>.gif" border="0" width="80" height="15" alt="<$MTCategoryLabel$>" /></a>
</div>
<MTEntryPreviousInCategory>
<div class="side">
&laquo;
<a href="<$MTEntryPermalink category_type="Individual"$>" title="このカテゴリの前の記事"><$MTEntryTitle$></a>
</div>
</MTEntryPreviousInCategory>
<MTEntryNextInCategory>
<div class="side">
<a href="<$MTEntryPermalink category_type="Individual"$>" title="このカテゴリの次の記事"><$MTEntryTitle$></a>
&raquo;
</div>
</MTEntryNextInCategory>
</MTEntryCategories>

前後の記事だけでなく、前の前の記事や後の後の記事へのリンクも作りたい場合、EntryCategoryLinks プラグインに Again プラグインを組み合わせて利用するという例がある (archippella -EntryCategoryLinks Plugin-)。ただし、自動再構築等の問題はあると思われる。

Posted by n at 2004-07-20 22:23 | Edit | Comments (7) | Trackback(20)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
カテゴリーで前後
nさんのページで、カテゴリー別に前後するリンクの作り方が取り上げられてたので、久し振りに手を入れてみた。 今までカテゴリー別のページから個別記事に入っても、上にある前の記事と次の記事がカテゴリー別にならずに、全体の中の前後になっちゃうんで難儀だなあと思... Trackbacked from: ホームラン2号 at July 21, 2004 01:40
カテゴリ内の次・前リンク
前々から便利だなと思っていたカテゴリ内を渡り歩くリンクをつけることにした。 使う... Trackbacked from: Play with Weblog! at August 20, 2004 13:44
同一カテゴリー内で記事の前後移動
通常、主要なBlog・CMSツールであれば、「エントリーの前後移動」は可能なようになっている。 そして、MovableTypeの場合「同一カテゴリー内の記事」に限定しての前後移動はデフォルトでは不可能である。 そこで以下のサイトを参照し、「同一カテゴリの前後ナビゲーション... Trackbacked from: Diary::Weblog at September 23, 2004 20:57
複数Categoryなページめくりの再構築(プラグインありなし判定)
一応「複数Categoryなページめくりの再構築(修正)」にて一段落していた改造。 しかし、 nlog(n)さんの「同一カテゴリの前後ナビゲーションと自動再構築」にて、このプラグインを入れていない場合はカテゴリとしての前後のエントリの再構築をしないほーがいいってな記述が... Trackbacked from: Ruby site at September 25, 2004 04:24
カテゴリー内平行移動プラグイン
Previous and next in category(phil ringnalda dot com) 個別エントリアーカイブに同じカテゴリの前後の記事を表示させるPrevious and next in categoryプラグインを入れてみました。 同一カテゴリの前後ナビゲーションと自動再構... Trackbacked from: the meager at November 05, 2004 21:45
PreviousNextInCategoryプラグイン
複数Categoryなページめくりの再構築(プラグインありなし判定) 同一カテゴリの前後ナビゲーションと自動再構築 上記サイトを参考にPreviousNextInCategory というプラグイン... Trackbacked from: 神奈川,千葉,東京,埼玉 住宅 設計事務所 K2WORKS 一級建築士事務所 at February 01, 2005 10:22
PreviousNextInCategoryプラグイン
PreviousNextInCategoryというプラグインの導入を試みました。 作業メモとして記述しておきます。 失敗です。 個別エントリーでの再構築は出来るのですが、アーカイブ全体の再構築時にどう... Trackbacked from: 神奈川,千葉,東京,埼玉 住宅 設計事務所 K2WORKS 一級建築士事務所 at February 04, 2005 10:45
同一カテゴリの前後の記事へのリンクを表示と自動再構築
 日記の個別ページには標準のテンプレートで前後の記事へのリンクが設定されているが、カテゴリによって全く別のテーマを扱っているので、表示される記事タイトルに違和感をおぼえることも多い。例えば、「[美食] スイーツ:グラマシーニューヨークのチーズケーキ」の前... Trackbacked from: HiLOG at February 06, 2005 08:15
個別アーカイブに同一カテゴリへの前後リンクを設置!
MovableType標準では個別アーカイブに<MTEntryPrevio... Trackbacked from: 21世紀のアフィリエイト通販生活 at February 11, 2005 21:07
同一カテゴリーの前後の記事へのリンク表示
MT一度壊れる前にやってた事なので、再掲載物となります nlog(n) 同一カテ... Trackbacked from: Magic White at March 03, 2005 21:35
MT 小変更
えーっと、、 以前の反省から、ちょっとした変更も書き留めておこうかと。。 たぶんすぐまた忘れると思いますが・・・(^_^... Trackbacked from: Hitorigoto? at June 25, 2005 16:18
カテゴリ内での前後記事移動
ずっとやりたかったんだけど、いざやってみると複数カテゴリに属している記事は変な表... Trackbacked from: CHICK! -MEMO- at September 30, 2005 12:50
カテゴリー内の前後移動に挑戦
MTでカテゴリーから個別アーカイブへ飛んだとき、その前後移動はエントリーの投稿順... Trackbacked from: miya.tv weblog at October 02, 2005 07:24
PreviousNextInCategoryプラグイン
カテゴリー内での、「前のエントリ」と「次のエントリ」を表示させるPreviousNextInCategoryプラグイン。... Trackbacked from: 2-mix Laboratory at October 11, 2005 18:28
寒いっす…
「個別エントリーアーカイブに複数カテゴリー用のナビゲーションをつける」カスタマイズをnlon(n)さんの『同一カテゴリの前後ナビゲーションと自動再構築』を参考に行いました。 Trackbacked from: ネコの為に鈴は鳴る。 - After☆Taste Blog - at November 01, 2005 20:24
同一カテゴリー内の前後の記事へのリンクを張る
個別アーカイブページ(各エントリ記事)にて、<MTEntryNext>や<MTEntryPrevious>タグによる投稿日付順の次/前の記事へのリンクを張るかわりに、同一カテゴリー内での次/前の記事へのリンクを張る方法を下記のサイトを参考に導入してみました。... Trackbacked from: iandeth. at November 15, 2005 03:14
同一カテゴリー内でエントリーの移動(MT3.2)
これも前々から導入したかったカスタマイズです。 同一カテゴリー内でエントリーの移... Trackbacked from: Project MultiBurst at November 18, 2005 23:33
複数カテゴリのページめくり
どうしても個別記事から、その記事が所属するカテゴリーの前後の記事へ移動させたくなった。一旦始めると止められなくなるMTいじり、、、いろいろ記事はあったが、カテゴリが複数だと難しいらしい。諦めかけたその時、なんとか、Ruby siteさんの記事 とnlog(n)さんの記事... Trackbacked from: riemagu log at November 22, 2005 05:40
全てプラグインだけで同一カテゴリ限定の前後リンク
前のエントリーで書いたカスタマイズは、どれも重要なカスタマイズだけど、特に今回詳... Trackbacked from: パソコンであれこれ。 at March 16, 2006 17:20
サイト大幅改造
あまり外見は変わっていないが、当サイトを大幅に改造した。... Trackbacked from: 野良犬の塒 at April 12, 2006 19:11
Comments

記事を参考に私のサイトでも個別記事に同一カテゴリの前後の記事へのリンクをつけるようにすることができました。
記事の最後に触れられているAgainプラグインを組み合わせて前後3つの記事へリンクするようにしているのですが、この場合に自動再構築をできるようにするにはMT.pmをどのように変更すればいいか見当がつくようであれば教えていただけないでしょうか。よろしくお願いいたします。

Posted by: yhiroaki at January 27, 2005 21:27

これはヤマカンですが…。
1つ手前が $entry->previous(1); ですから,2つ手前は $entry->previous(2); でアクセスできそうです。next についても同様です。
このくらいのヒントでどうでしょうか?

Posted by: n at January 27, 2005 22:41

ヒントありがとうございます。
エントリをどんどん手繰っていって同じカテゴリのエントリを見つけるとすると、do whileとifのところを繰り返すことになるのでしょうか。
しかし、初期設定で「my $prev = $entry->previous(1);」として1つ前のエントリを参照しているのに、while doではなく、do whileでさらに「$prev = $prev->previous(1);」ともう1つ前のエントリを参照しているように見えます。こうすると新規エントリの2つ前のエントリから評価を始めているように見えるのですが・・・。もう少しヒントをいただけないでしょうか。try&errorする勇気がなかなかわかないのです。

my $cats = $entry->categories;
# previous
for my $cat (@$cats) {
my $prev = $entry->previous(1);
if ($prev && !$prev->is_in_category($cat)){
# previous 1
do {
$prev = $prev->previous(1);
} while ($prev && !$prev->is_in_category($cat));
if ($prev) {
$mt->_rebuild_entry_archive_type(Entry => $prev,
Blog => $blog,
ArchiveType => 'Individual')
or die $mt->errstr;
}
# previous 2
do {
$prev = $prev->previous(1);
} while ($prev && !$prev->is_in_category($cat));
if ($prev) {
$mt->_rebuild_entry_archive_type(Entry => $prev,
Blog => $blog,
ArchiveType => 'Individual')
or die $mt->errstr;
}
# previous 3
do {
$prev = $prev->previous(1);
} while ($prev && !$prev->is_in_category($cat));
if ($prev) {
$mt->_rebuild_entry_archive_type(Entry => $prev,
Blog => $blog,
ArchiveType => 'Individual')
or die $mt->errstr;
}
}
# next
my $next = $entry->next(1);
if ($next && !$next->is_in_category($cat)){
# next 1
do {
$next = $next->next(1);
} while ($next && !$next->is_in_category($cat));
if ($next) {
$mt->_rebuild_entry_archive_type(Entry => $next,
Blog => $blog,
ArchiveType => 'Individual')
or die $mt->errstr;
}
# next 2
do {
$next = $next->next(1);
} while ($next && !$next->is_in_category($cat));
if ($next) {
$mt->_rebuild_entry_archive_type(Entry => $next,
Blog => $blog,
ArchiveType => 'Individual')
or die $mt->errstr;
}
# next 3
do {
$next = $next->next(1);
} while ($next && !$next->is_in_category($cat));
if ($next) {
$mt->_rebuild_entry_archive_type(Entry => $next,
Blog => $blog,
ArchiveType => 'Individual')
or die $mt->errstr;
}
}
}

Posted by: yhiroaki at January 28, 2005 23:15

「$prev = $entry->previous(1); で1つ前のエントリ,$prev = $prev->previous(1); でもう1つ前のエントリつまり2つ前のエントリを参照している」という理解は正しいです。1つ前のエントリの再構築は,Movable Type がデフォルトで行っているので,繰り返して再構築するのは無駄になります。そのため,2つ前から始めているのです。2つ前から始めて,同じカテゴリのエントリがあるまでどんどん遡ることをしています。
このヒントでいかがですか?

Posted by: n at January 29, 2005 00:59

 ヒントありがとうございます。いただいたヒントをもとに試してみます。

 現在のロジックは以下の考え方で組まれていると受け止めました。
「基本的には1つ前のエントリが同一カテゴリの場合には、あえて2つ前のエントリから同一カテゴリのエントリ(同一カテゴリの2つ前のエントリに相当)を探して再構築する必要は無いが、ロジックをシンプルにするため等の理由で、サーチ&再構築している。」

Posted by: yhiroaki at January 30, 2005 20:13

ロジックを整理すると次のようになります。特に無駄な動作はしていないと思います。

・1つ前のエントリが同一カテゴリの場合は,サーチせず,したがって再構築も行わない
・1つ前のエントリが同一カテゴリでない場合は,2つ前のエントリからサーチを始め,同一カテゴリのエントリを発見したら再構築を行う

Posted by: n at January 30, 2005 22:26

早合点で誤解していました。大変失礼しました。
でも、おかげでロジックがきちんと理解できました。ありがとうございます。

Posted by: yhiroaki at January 31, 2005 23:17
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


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


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


Confirmation Code (必須)


Remember info (R)?