Blog

ブログ

MovableTypeでブログ間の任意のエントリーを関連付ける

Bのブログのエントリーに関連する、Aのブログのエントリーの一覧が表示されています

はじめての方は、ようこそいらっしゃいませ。
札幌のWebデザイナー、WebbingStudioです。
Movable Type Advent Calendar 2012の15日目のエントリーです。

このところはイベントレポートが多かったこのブログですが、ひさしぶりにこってりしたカスタマイズの話でも。

同じMovableTypeのシステム内の、イベントを掲載しているブログ(仮にAとします)のエントリーを、他のブログ(仮にBとします)の、更新担当者が指定したエントリーに関連付けられるようにする方法をご紹介します。

プラグインを追加する

このカスタマイズには、以下のふたつのプラグインが必要となります。
前もってインストールしておいてください。

MTAppjQueryは、管理画面をjQueryでカスタマイズできるプラグイン、
Splitは、MovableTypeの変数を特定の文字列で分割して配列にできるプラグインです。

もし、MTOSを利用する場合は、AnotherCustomFieldsプラグインも必要となります。

カスタムフィールドを作成する

B(関連付けを呼び出す方)のブログに、テキストタイプのカスタムフィールドをひとつ追加します。
ベースネームは「relationEvents」とします。

MTAppjQueryのJS・CSSを変更する

次に、ウェブサイトか、A(呼び出される方)のブログに、インデックステンプレートをふたつ作成します。

テンプレートひとつめ

テンプレート名 MTAppjQuery.user.js
出力ファイル名 ★MovableTypeまでのパス★/mt-static/plugins/MTAppjQueryjs/user.js
公開方法 手動

内容は以下の通りとします。
Aのブログのエントリータイトルを、マルチチェックボックスの項目として呼び出しています。

(function($){

$.MTAppMultiCheckbox({
    basename: 'relationevents',
    label:    '<mt:Entries blog_ids="★AのブログのID★" glue="," lastn="0"><$mt:EntryTitle encode_js="1"$></mt:Entries>',
    custom:   1,
    debug:    0
});


})(jQuery);

テンプレートふたつめ

テンプレート名 MTAppjQuery.user.css
出力ファイル名 ★MovableTypeまでのパス★/mt-static/plugins/MTAppjQuery/css/user.css
公開方法 手動

内容は以下の通りとします。マルチチェックボックスを整形します。

@charset "UTF-8";

#customfield_relationevents-field .mcb-container .mcb-label {
	display: -moz-inline-box;
	display: inline-block;
	vertical-align: middle;
	margin: 0 2em .5em 0;
}

この通りにテンプレートを作成・再構築すると、MTAppjQueryプラグインの設定用ファイルを上書きすることになります。

テストエントリーを書く

Bのブログにテストエントリーを書きます。
Aのブログの記事を選択できるようになっているはずです。

関連エントリーリストを追加する

Bのブログの、エントリーアーカイブテンプレートの任意の場所に、以下のコードを追加します。
再構築すると、関連エントリーへのリンク一覧が表示されます。

<div class="related">
	<h2>関連イベント</h2>
<$mt:relationEvents setvar="relationid"$>
<$mt:var name="relationid" split=",","relationhash"$>
<mt:If name="relationhash[0]">
	<ul>
<mt:loop name="relationhash">
<mt:Entries blog_ids="5" lastn="0">
<$mt:EntryTitle setvar="currenttitle"$>
<mt:If name="currenttitle" eq="$__value__">
		<li><$mt:EntryDate format="%Y年%m月%d日"$> | <a href="<$mt:EntryPermalink$>"><$mt:EntryTitle encode_html="1"$></a></li>
</mt:If>
</mt:Entries>
</mt:loop>
	</ul>
<mt:Else>
<p>関連しているイベントはありません。</p>
</mt:If>
<!--/.related --></div>

リスト内では、以下のような処理をしています。

  1. カスタムフィールドの値を変数「relationid」に代入
  2. Splitプラグインで配列「relationhash」に変換
  3. Aのブログのうち、配列の各項目とエントリータイトルが一致する記事のみを表示
  4. 配列のひとつ目が存在しない場合は、指定がなかったとみなす

補足

このカスタマイズは、ダイナミック・パブリッシングにも対応していますが、Aのブログのすべてのエントリーから絞り込んでいるため、Aのブログのエントリーがとても多いと再構築が遅くなってしまいます。
また、全く同じタイトルのエントリーが追加される可能性がある場合は、タイトルを条件にすることはできません。

その場合は、以下の方法にすると、若干処理速度を軽減できます。

  • タグを条件に絞り込む
  • labelオプションを使って、エントリーIDを入力させる
  • PHPを併用して絞り込む(スマートじゃないですが)

大規模なサイトの場合は、素直にカスタムオブジェクトで関連付けができる、PowerCMSを使うのが無難ですw

参考記事