MovableTypeのコンテンツデータで1対Nデータを扱った件
1対Nのデータを通常のRDBSで扱う時は、子データ側に親データのIDを持っておくのがセオリーである。
しかし、MovableTypeのコンテンツデータでは「MTContentsタグのfield絞り込みにおいて、フィールドにコンテンツデータを使っていると絞り込みができない」という性質により親データ側に子データをぶら下げるようにしないといけないのである。
以下、ChatGPTにまとめてもらった内容。
📝 Movable Type で「講師別セミナー一覧」を表示する方法と設計の考察
🔸 質問の背景
Movable Type(MT)のコンテンツタイプ機能を使って以下のような構成をしているとします:
コンテンツタイプA:セミナー
- フィールド「登壇講師」:コンテンツタイプ「講師」への参照(複数選択可)
コンテンツタイプB:講師
- フィールド「氏名」:例「佐藤さん」
このとき、
講師「佐藤さん」が登壇しているセミナー一覧を表示できるか?
というのが主な関心でした。
✅ Movable Type の仕様上の制限
MTのリファレンスには以下のように記載されています:
コンテンツフィールドがコンテンツタイプの場合、指定されているコンテンツタイプのリンク先のフィールド値で絞り込むことはできません。
つまり以下のようなフィルタ指定はできません:
<mt:Contents content_type="セミナー" field:登壇講師.field:氏名="佐藤さん">
✅ それでも実現可能な方法(テンプレートレベル)
- 講師「佐藤さん」の コンテンツID を取得
- セミナー一覧をループし、
<mt:If name="登壇講師" contains="$佐藤ID">で判定
<mt:Contents content_type="講師">
<mt:If name="氏名" eq="佐藤さん">
<mt:SetVar name="sato_id" value="$id">
</mt:If>
</mt:Contents>
<mt:Contents content_type="セミナー">
<mt:If name="登壇講師" contains="$sato_id">
<!-- セミナー情報を表示 -->
</mt:If>
</mt:Contents>
- ❗ ただしこれは「セミナー件数 × 登壇講師数」のループになる可能性があり、大量データには非効率。
✅ より効率的な方法(Data API を使う)
/v4/sites/{site_id}/contentTypes/講師/contents?searchFields=氏名&search=佐藤→ 講師のIDを取得/v4/sites/{site_id}/contentTypes/セミナー/contents?searchFields=登壇講師&search=1234→ 登壇講師に佐藤さん(ID:1234)を含むセミナーを取得
👉 APIであればループ不要・高速に取得可能
💡 設計の見直しポイント
「講師のほうにセミナーを紐づける」のは直感的だが、MTでは逆が有利。
| 観点 | RDB的な設計 | MTで実用的な設計 |
|---|---|---|
| 1:N関係の管理 | 子(講師)に親IDを持たせる | 親(セミナー)に子IDを持たせる(複数) |
| 講師 → セミナーの逆引き | 中間テーブルで表現 | 難しい・テンプレートで非効率 |
| セミナー → 講師の参照 | 非直感的に見えるが実装容易 | ✅ テンプレートもAPIもスムーズに処理可能 |
🔁 要するに:
Movable Type のテンプレート設計では、**「出力側で参照したい方向にIDを持たせる」**のが基本設計方針。