Movable TypeでCSVデータからtable要素を作る方法

Movable TypeでCSVデータからtable要素を作る方法

Posted at October 18,2011 1:55 AM
Tag:[CSV, Customize, MovableType, table]

Movable Typeを使って、CSVデータからtable要素を簡単に作る方法を紹介します。このエントリーはMTQに寄せられたご質問の回答を情報展開したものです。

1.カスタマイズイメージ

次のようなカンマ区切りのCSVデータをブログ記事の本文に記述します。

h1,h2,h3,h4,h5
a1,a2,a3,a4,a5
b1,b2,b3,b4,b5
c1,c2,c3,c4,c5

このデータから次のtable要素を生成します。

<table>
<thead>
<tr><th>h1</th><th>h2</th><th>h3</th><th>h4</th><th>h5</th></tr>
</thead>
<tbody>
<tr><td>a1</td><td>a2</td><td>a3</td><td>a4</td><td>a5</td></tr>
<tr><td>b1</td><td>b2</td><td>b3</td><td>b4</td><td>b5</td></tr>
<tr><td>c1</td><td>c2</td><td>c3</td><td>c4</td><td>c5</td></tr>
</tbody>
</table>

2.カスタマイズ

CSVデータを分解するにはSplitプラグインを利用します。

Splitプラグイン

プラグインをインストールした後、次のサブテンプレートをインデックステンプレートに記述して、再構築またはプレビューを実行します。サンプルは一番外側のMTEntriesタグにidモディファイアを与えて、ブログ記事IDが「100」の本文だけを処理するようにしています。

<mt:Entries id="100">
<table>
  <mt:EntryBody split="\n" setvar="foo">
  <mt:loop name="foo">
    <mt:GetVar name="__value__" split="," setvar="bar" />
    <mt:if name="__first__">
<thead>
      <mt:loop name="bar">
        <mt:if name="__first__">
<tr>
        </mt:if>
<th><mt:GetVar name="__value__" /></th>
        <mt:if name="__last__">
</tr>
        </mt:if>
      </mt:loop>
</thead>
    <mt:else>
      <mt:if "__counter__" eq="2">
<tbody>
      </mt:if>
      <mt:loop name="bar">
        <mt:if name="__first__">
<tr>
        </mt:if>
<td><mt:getVar name="__value__" /></td>
        <mt:if name="__last__">
</tr>
        </mt:if>
      </mt:loop>
    </mt:if>
  </mt:loop>
</tbody>
</table>
</mt:Entries>

MTEntriesタグでブログ記事を読み込むだけでなく、同じインデックステンプレートにMTSetVarBlockタグでCSVデータを記述し、その変数を読み込むという方法もあります。

3.テンプレートの解説

MTEntryBodyタグで本文(CSVデータ)を取得し、splitモディファイアで改行文字(¥n)をセパレータにして分割した結果を変数fooに保持します。

<mt:EntryBody split="\n" setvar="foo">

変数fooには配列で各行のデータが保存されます。イメージは次のような感じです。

$foo[0] = 'h1,h2,h3,h4,h5'
$foo[1] = 'a1,a2,a3,a4,a5'
$foo[2] = 'b1,b2,b3,b4,b5'
$foo[3] = 'c1,c2,c3,c4,c5'

最初のMTLoopタグでこの変数fooを処理します。1回目の繰り返しでは「'h1,h2,h3,h4,h5'」、2回目の繰り返しでは「'a1,a2,a3,a4,a5'」という順で処理を行っていきます。

  <mt:loop name="foo">
    …中略…
  </mt:loop>

1回目の繰り返し処理の中で、MTGetVarタグを使って変数fooから「__value__」で値「'h1,h2,h3,h4,h5'」を取得し、その値をsplitモディファイアでカンマ文字をセパレータにして、分割した結果を変数barに保持します。

<mt:GetVar name="__value__" split="," setvar="bar" />

変数barにはカンマで区切ったデータが配列で保存されます。イメージは次のような感じです。

$bar[0] = 'h1'
$bar[1] = 'h2'
$bar[2] = 'h3'
$bar[3] = 'h4'
$bar[4] = 'h5'

次のMTIfタグでは、繰り返し処理が初回か初回でないかを判定しています。これは初回の場合はthead要素とth要素を出力し、2回目以降はtbodyとtd要素を出力させるためです。

    <mt:if name="__first__">
(thead要素とth要素を出力)
    <mt:else>
(tbody要素とtd要素を出力)
    </mt:if>

初回の繰り返しの場合は次の処理を行います。MTLoopタグでは先程カンマで分割した配列変数barを処理します。繰り返しの初回でtr要素の開始タグを出力し、MTGetVarタグで値(h1~h5)を順番に出力します。繰り返しの最後でtr要素の終了タグを出力します。

    <mt:if name="__first__">
<thead>
      <mt:loop name="bar">
        <mt:if name="__first__">
<tr>
        </mt:if>
<th><mt:GetVar name="__value__" /></th>
        <mt:if name="__last__">
</tr>
        </mt:if>
      </mt:loop>
</thead>

2回目以降の繰り返しの場合は次の処理を行います。MTIfタグで2回目の繰り返しの場合のみtbody要素を出力します。tbodyの終了タグはすべての処理の最後に出力すればよいのでここでは登場しません。

あとは先程と同様、MTLoopタグではカンマで分割した配列変数barを処理します。繰り返しの初回でtr要素の開始タグを出力し、MTGetVarタグで値(a1~a5/b1~b5/c1~c5)を順番に出力します。

    <mt:else>
      <mt:if "__counter__" eq="2">
<tbody>
      </mt:if>
      <mt:loop name="bar">
        <mt:if name="__first__">
<tr>
        </mt:if>
<td><mt:getVar name="__value__" /></td>
        <mt:if name="__last__">
</tr>
        </mt:if>
      </mt:loop>

その他、次のように最初のMTLoopで1行分のデータを別々の変数に保持してから出力するという方法もあります。こちらの方が見通しはよいですが、CSVデータの増減に柔軟に対応できるのは前述のサブテンプレートです。

<mt:Entries id="100">
  <mt:EntryBody split="\n" setvar="foo">
<table>
  <mt:loop name="foo">
    <mt:GetVar name="__value__" split="," setvar="bar" />
    <mt:loop name="bar">
      <mt:if name="__counter__" eq="1"><mt:GetVar name="__value__" setvar="data1" /></mt:if>
      <mt:if name="__counter__" eq="2"><mt:GetVar name="__value__" setvar="data2" /></mt:if>
      <mt:if name="__counter__" eq="3"><mt:GetVar name="__value__" setvar="data3" /></mt:if>
      <mt:if name="__counter__" eq="4"><mt:GetVar name="__value__" setvar="data4" /></mt:if>
      <mt:if name="__counter__" eq="5"><mt:GetVar name="__value__" setvar="data5" /></mt:if>
    </mt:loop>
    <mt:if name="__first__">
  <thead>
    <tr>
      <th><mt:GetVar name="data1" /></th>
      <th><mt:GetVar name="data2" /></th>
      <th><mt:GetVar name="data3" /></th>
      <th><mt:GetVar name="data4" /></th>
      <th><mt:GetVar name="data5" /></th>
    </tr>
  </thead>
    <mt:else>
      <mt:if name="__counter__" eq="2">
  <tbody>
      </mt:if>
    <tr>
      <td><mt:GetVar name="data2" /></td>
      <td><mt:GetVar name="data3" /></td>
      <td><mt:GetVar name="data4" /></td>
      <td><mt:GetVar name="data5" /></td>
    </tr>
    </mt:if>
  </mt:loop>
  </tbody>
</table>
</mt:Entries>

4.区切り文字について

splitモディファイアの区切り文字にはタブ(¥t)を指定することも可能です。任意の文字列を設定すれば、それがそのまま区切り文字となります。

5.注意事項

WindowsにインストールしたMTでは、splitタグによる正常な動作を確認できていません。

関連記事
zenback
人気エントリー
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)