MTAppJSONTable と MTAppAssetFields で可変数&ドラッグアンドドロップで並べ替え可能なギャラリーを作る

本日公開した「 MTAppjQuery v1.10.0 」では、textarea をMT標準のファイルアップロードのフィールドに変更することができる MTAppAssetFields というメソッドを追加しました。

この MTAppAssetFieldsMTAppJSONTable を組み合わせて使うと、画像数が可変で、ドラッグアンドドロップで並べ替えができる画像ギャラリーを作ることができます。

MTAppAssetFieldsInMTAppJSONTable03-min.png

今日はその方法を紹介します。

MTAppJSONTable を概要欄に適用

まず下記のコードを user.js に書き、「概要」欄を上記の入力欄を持つ表形式の入力欄にカスタマイズします。

(function($){
    $('#excerpt').MTAppJSONTable({
        inputType: 'textarea',
        caption: '記事の画像',
        header: {image: '画像', caption: 'キャプション'},
        headerPosition: 'top',
        headerOrder: ['image','caption'],
        footer: false,
        edit: true,
        add: true,
        sortable: true,
        clear: true,
        nest: true,
        debug: true
    });
})(jQuery);

このコードを適用すると、下図のようになります。

MTAppAssetFieldsInMTAppJSONTable01-min.png

設定したオプションの中の nest: true, は、v1.10.0 で追加したオプションで、これを設定すると、JSONTable の中の入力欄に JSON が入っている場合は、その JSON も JSONTable の JSON の中の要素として展開されます。 nest: false, だと JSON は文字列のまま展開されません(ややこしいですね・・・。ドキュメントサイトにはサンプル載せて説明しています)。

スタイルは user.css で下記のように調整しました。

#excerpt-field .jsontable-table th.image,
#excerpt-field .jsontable-table td.image {
    width: 25em;
}
#excerpt-field .jsontable-table textarea {
    height: 100%;
}

MTAppAssetFields を適用

上記で作成した image というセルの textareaMTAppAssetFields を適用します。

下記のように cbAfterBuild オプションと cbAfterAdd オプションにコールバック関数を指定します。

(function($){
    $('#excerpt').MTAppJSONTable({
        inputType: 'textarea',
        caption: '記事の画像',
        header: {image: '画像', caption: 'キャプション'},
        headerPosition: 'top',
        headerOrder: ['image','caption'],
        footer: false,
        edit: true,
        add: true,
        sortable: true,
        clear: true,
        cbAfterBuild: function(cb, $container){
            $container.find('td.image .jsontable-input').MTAppAssetFields();
        },
        cbAfterAdd: function(cb, $container){
            $container.find('td.image .jsontable-input:not(".isMTAppAssetFields")').MTAppAssetFields();
        },
        debug: true
    });
})(jQuery);

cbAfterAdd オプションの方では、 .jsontable-input:not(".isMTAppAssetFields") とすることで、 MTAppAssetFields の重複適用を防止することができます。

このコードを user.js に適用し、何度か「行を追加」ボタンをクリックした状態が下図になります。

MTAppAssetFieldsInMTAppJSONTable02-min.png

画像のアップロード

実際に画像をアップロードして、記事を保存した状態が下図になります。 MTAppAssetFields は Movable Type 標準装備の画像のアップローダーを利用します。

MTAppAssetFieldsInMTAppJSONTable03-min.png

保存される JSON

このとき、元のフィールド(ここでは「概要」欄の textarea )には、下記のような JSON が保存されます(見やすいようにインデントを整えています)。

{
  "items": [{
    "image": {
      "id": "116",
      "filename": "blog-01.jpg",
      "url": "http://(略)/blog-01.jpg",
      "thumbnail": "http://(略)/assets_c/2016/11/blog-01-thumb-240xauto-116.jpg"
    },
    "caption": "「ぱくたそ」さんからダウンロードした iMac の写真です。とても良い雰囲気です。"
  }, {
    "image": {
      "id": "117",
      "filename": "blog-02.jpg",
      "url": "http://(略)/blog-02.jpg",
      "thumbnail": "http://(略)/assets_c/2016/11/blog-02-thumb-240xauto-117.jpg"
    },
    "caption": "「ぱくたそ」さんからダウンロードした MacBook Air の写真です。相棒も使っています。"
  }, {
    "image": {
      "id": "118",
      "filename": "blog-06.jpg",
      "url": "http://(略)/blog-06.jpg",
      "thumbnail": "http://(略)/assets_c/2016/11/blog-06-thumb-240xauto-118.jpg"
    },
    "caption": "「ぱくたそ」さんからダウンロードした PHP のコードの写真です。すらすらプログラミングできるといいですね。"
  }]
}

このように、 MTAppAssetFields を適用したフィールドには、画像の idfilename などの情報を持つ JSON が保存されます。

テンプレートで扱う

保存された値をテンプレートタグで扱えるようにするために json_decode モディファイアで JSON を MT のハッシュ変数に変換します。その後、設定した値を順次取り出すことになります。

ここでは、ギャラリーに登録された画像とキャプションを、シンプルな HTML で出力してみましょう。

最終的なコードは下記になります。

<mt:EntryExcerpt convert_breaks="0" no_generate="1" json_decode="1" setvar="json" />
<mt:Var name="json" key="items" setvar="items" />
<mt:Var name="items" function="count" op="--" setvar="l" />
<mt:For var="i" from="0" to="$l">
  <mt:Var name="items" index="$i" setvar="item" />
  <mt:Var name="item" key="image" setvar="image" />
  <mt:If name="i" eq="0">
    <ul>
  </mt:If>
      <li>
        <img src="<mt:Var name="image" key="thumbnail" />" alt="" /><br />
        <p><mt:Var name="item" key="caption" /></p>
      </li>
  <mt:If name="i" eq="$l">
    </ul>
  </mt:If>
</mt:For>

それでは一つずつ解説します。


「概要」欄に入った JSON を json_decode="1" で MT のハッシュに変換し、変数 json にセットします。

<mt:EntryExcerpt convert_breaks="0" no_generate="1" json_decode="1" setvar="json" />

MTAppJSONTable のデータが入っている items プロパティを変数 items にセットします。

<mt:Var name="json" key="items" setvar="items" />

items 変数は配列ですので mt:For タグで中身をループして取り出します。配列の中の最後のインデックス番号を変数 l にセットします。

<mt:Var name="items" function="count" op="--" setvar="l">

配列の要素をループで取り出します。

<mt:For var="i" from="0" to="$l">
  <mt:Var name="items" index="$i" setvar="item" />
  <mt:Var name="item" key="image" setvar="image" />
  <mt:If name="i" eq="0">
    <ul>
  </mt:If>
      <li>
        <img src="<mt:Var name="image" key="thumbnail" />" alt="" /><br />
        <p><mt:Var name="item" key="caption" /></p>
      </li>
  <mt:If name="i" eq="$l">
    </ul>
  </mt:If>
</mt:For>

ここでポイントとなるのは、 MTAppAssetFields を適用したフィールドの情報の取り出し方です。

MTAppAssetFields で保存される値の取り出し方

MTAppAssetFields を適用した textarea には下記のような JSON が保存されます。

{
  "id": "119",
  "filename": "blog-03.jpg",
  "url": "http://(略)/blog-03.jpg",
  "thumbnail": "http://(略)/assets_c/2016/11/blog-03-thumb-240xauto-119.jpg"
}

それぞれの値は下記の通りです。

  • id : 画像のID( AssetID
  • filename : 画像のファイル名
  • url : 画像のURL
  • thumbnail : 管理画面に表示されるサムネイルのURL

画像の情報がこのような JSON で保存されていますので、 MTAppAssetFields を単体で使う場合は一度 json_decode="1" で MT のハッシュ変数に変換する必要がありますが、今回のサンプルの場合は、最初に json_decode="1" で MT のハッシュ変数に変換されているますので、ここでの json_decode="1" は不要です。

したがって、ループ中のアイテム item からキー image の値を一度別の変数 image にセットし、

<mt:Var name="item" key="image" setvar="image" />

その中から必要な値を取得しています。

<mt:Var name="image" key="thumbnail" />

管理画面に表示されるサムネイルをそのまま使うのであれば thumbnail 、オリジナルの画像を使うのであれば url 、その他の情報を利用したければ下記のように id を変数にセットして、それを mt:Asset タグに渡して Asset 系のタグを利用することもできます。

<mt:Var name="image" key="id" setvar="id" />
<mt:Asset id="$id">
  <img src="<mt:AssetThumbnailURL width="150" square="1" />" alt="" />
</mt:Asset>

まとめ

このように、 MTAppJSONTableMTAppAssetFields を組み合わせれば、1つのフィールドで可変数の画像を管理することができます。もうカスタムフィールドをいくつも作る必要はありませんね。

慣れるまでは複雑かもしれませんが、上記のコードをコピペしながら利用してみてください。

以上です。

  • このエントリーをはてなブックマークに追加
Just a second...