tohokuaikiのチラシの裏

技術的ネタとか。

MovableTypeでコンテンツデータのフィールドにコンテンツデータを指定している時にMTテンプレートで展開する方法

コンテンツデータ、便利ですね。

何が便利かって、コンテンツデータの中にコンテンツデータをフィールドとして指定できるからツリーが作れちゃう。

だけど、これをMTテンプレートで展開する時はちょっと工夫が必要です。

注意点1:1対Nのデータ構造だけど、親の方に子を登録しておかないといけない。

こちらを参照 tohokuaiki.hateblo.jp

注意点2:テンプレートで展開する際にMT:Contentsタグはそのまま使えない。

親階層で展開中のMT:Contentsタグの中で展開すれば配慮してくれるやろー…って、そんなわけはない。

      <mt:Contents content_type="3">
        "year": <mt:ContentField content_field="年度"><mt:ContentFieldValue encode_json='1'></mt:ContentField>
      </mt:Contents>

こんな感じで展開すると当然のことながら全てのcontent_type=3のコンテンツデータが展開される。 idアトリビュートで絞り込む必要がある。

ということで、コンテンツデータ内にコンテンツデータを持つ場合の展開例

コンテンツデータの定義

こんな感じです。

・セミナー(コンテンツデータ1)
┣会場(テキスト)
┣会費(テキスト)
┗講師(コンテンツデータ)複数可

・講師(コンテンツデータ2)
┣名前(テキスト)
┗年齢(テキスト)

めざすHTML出力

こんな感じにしたい

<ul>
  <li>
    <h3>セミナータイトル1</h3>
    <p>セミナー会場(セミナー料金:円)</p>
    <h4>講師</h4>
    <ul>
      <li>加藤(63)</li>
      <li>佐藤(44)</li>
      <li>伊藤(55)</li>
   </ul>
  <li>
  <li>
    <h3>セミナータイトル2</h3>
    <p>セミナー会場(セミナー料金:円)</p>
    <h4>講師</h4>
    <ul>
      <li>鈴木(58)</li>
      <li>佐久間(43)</li>
   </ul>
  <li>
</ul>     

MTテンプレート

使用するプラグイン

これを入れておいてください。 https://www..jp/blog/2015/10/gethashvar.htmlwww..jp

https://github.com/alfasado/mt-plugin-get-hash-var

作ったMTテンプレート

<ul>
<mt:Contents content_type="1">
<mt:SetVarBlock name="teacher_ids"><mt:ContentField content_field="講師" glue=","><mt:ContentID></mt:ContentField></mt:SetVarBlock>
<mt:SplitVar name="teacher_ids" glue=",">
  <li>
    <h3><mt:ContentField content_field="セミナータイトル"><mt:ContentFieldValue></mt:ContentField></h3>
    <p><mt:ContentField content_field="セミナー会場"><mt:ContentFieldValue></mt:ContentField><mt:ContentField content_field="セミナー料金"><mt:ContentFieldValue></mt:ContentField>:円)</p>
    <h4>講師</h4>
    <ul>
      <mt:Loop name="teacher_ids">
      <mt:Contents content_type="2" id="$__value__">
      <li><mt:ContentField content_field="名前"><mt:ContentFieldValue encode_json='1'></mt:ContentField><mt:ContentField content_field="年齢"><mt:ContentFieldValue encode_json='1'></mt:ContentField></li>
      </mt:Contents>
      </mt:Loop>
   </ul>
  <li>
</ul>
</mt:Contents>

ポイント

要は、親(セミナー)コンテンツデータから子(講師)コンテンツデータのIDだけを抜き出して、それを配列に収めてまたループするという方法。

技術要素 説明
<mt:SetVarBlock> フィールドの複数値をカンマ区切りID列として一旦格納
<mt:SplitVar> + <mt:Loop> そのID列を擬似配列としてループ展開
<mt:Contents id="$__value__"> 動的に関連コンテンツデータを1件ずつ呼び出し
<mt:Unless name="__last__">,</mt:Unless> JSONフォーマット整形のためのカンマ制御
<mt:ContentsHeader> / <mt:ContentsFooter> JSON配列の [, ] をラップに使う

いやー、こんなんもっと簡単な方法を提供してくれておらんのかな?コンテンツデータ内にコンテンツデータとか簡単にループ回したいやん。