MTAppjQuery v1.10.0 で追加された MTAppAssetFields と MTAppJSONTable を組み合わせて、画像数が可変で、ドラッグアンドドロップで並べ替えができる画像ギャラリーを作る方法をご紹介します。
本日公開した「 MTAppjQuery v1.10.0 」では、textarea
をMT標準のファイルアップロードのフィールドに変更することができる MTAppAssetFields
というメソッドを追加しました。
この MTAppAssetFields
と 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);
このコードを適用すると、下図のようになります。
設定したオプションの中の 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%;
}
上記で作成した image
というセルの textarea
に MTAppAssetFields
を適用します。
下記のように 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
に適用し、何度か「行を追加」ボタンをクリックした状態が下図になります。
実際に画像をアップロードして、記事を保存した状態が下図になります。 MTAppAssetFields
は Movable Type 標準装備の画像のアップローダーを利用します。
このとき、元のフィールド(ここでは「概要」欄の 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
を適用したフィールドには、画像の id
や filename
などの情報を持つ 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
を適用した 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
: 画像のURLthumbnail
: 管理画面に表示されるサムネイルの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>
このように、 MTAppJSONTable
と MTAppAssetFields
を組み合わせれば、1つのフィールドで可変数の画像を管理することができます。もうカスタムフィールドをいくつも作る必要はありませんね。
慣れるまでは複雑かもしれませんが、上記のコードをコピペしながら利用してみてください。
以上です。