MTAppjQuery v2.7.0 で追加された mtapp.multiField v2 に、独自のフィールドを追加する方法をご紹介します。思ったより簡単にできると思いますのでぜひお試しください。
こんにちは。この記事は「Movable Type Advent Calendar 2021」6日目の記事です。MTのアドベントカレンダーが始まってから、今年でついに10年連続で12月6日に投稿しています。そんな僕ももう45歳。。。
さて、気を取り直して今日は MTAppjQuery v2.7.0 で追加された mtapp.multiField v2 に独自のフィールドを追加する方法をご紹介します。
記事等に関連情報を付けるフィールドを想定してみます。入力する項目は下記のようにしてみましょう。
まず user.js
の mtapp.multiField()
の fieldBlocks
オプションに作成するフィールドの定義を追加します。
今回はrelatedContent
というハンドルのフィールドを追加します。なお、version: 2
オプションを忘れないようにしてください。
(function($){
'use strict';
mtapp.multiField({
version: 2, // 忘れないように!
label: 'マルチフィールド',
showViewRawDataButton: true,
id: 72, // 適宜変更してください。
fieldBlocks: {
relatedContent: {
type: 'relatedContent',
label: '関連コンテンツ',
data: {
relatedContentLabel: '',
relatedContentType: '',
relatedContentFile: {},
relatedContentImage: {}
}
},
},
// fieldGroups は配列
fieldGroups: [
[
'text', 'relatedContent'
]
]
});
})(jQuery);
これで、デフォルトで用意されている1行テキストの「テキスト」フィールドと、今回追加する「関連コンテンツ」フィールドの2つのボタンが表示されます。この段階では「関連コンテンツ」ボタンをクリックしても空のフィールドブロックが追加されるだけです。
ブラウザの別タブでシステムメニューを表示し、システムメニューの左サイドメニューの「デザイン > グローバルテンプレート」に移動します。
画面右上のドロップダウンリストで「テンプレートモジュール」を選択したまま「新規作成」をクリックします。
テンプレート名とテンプレート本体に VueComponents
と入れて保存します。すると、画面左上に「VueComponents」と表示されれば成功です。
VueComponents グローバルテンプレートモジュールに、関連コンテンツブロックの大枠を定義した下記の内容をコピペして保存します。
<mt:Ignore>
VueRelatedContent というコンポーネントのテンプレートを定義
「関連リンク」ボタンをクリックしたときに追加されるフィールドブロックのテンプレート
</mt:Ignore>
<script type="text/x-template" id="mf-component-relatedContent">
<div>VueRelatedContent</div>
</script>
<mt:Ignore>VueRelatedContent というコンポーネントを定義(Vue.js)</mt:Ignore>
<script>
Vue.component('VueRelatedContent', {
props: { item: Object },
template: '#mf-component-relatedContent'
});
</script>
<mt:Ignore>type: 'relatedContent' のときに上記フィールドブロックが表示されるように MTAppjQuery に追加</mt:Ignore>
<mt:SetVarBlock name="mtapp_mf_additional_fields">
<template v-else-if="fieldBlocks[item.handle].type === 'relatedContent'">
<VueRelatedContent></VueRelatedContent>
</template>
</mt:SetVarBlock>
この状態で「関連コンテンツ」ボタンをクリックすると下図のように表示されます。
ポイントは下記の項目を間違えないようにすることです。
type
で指定する値と同じものを入れる(赤)type
で指定する値の先頭に Vue
をつけてパスカルケースにする(オレンジ)v-else-if
にする(緑)VueRelatedContent コンポーネントの中身を下記のようにしてみました。
<mt:Ignore>
VueRelatedContent というコンポーネントのテンプレートを定義
「関連コンテンツ」ボタンをクリックしたときに追加されるフィールドブロックのテンプレート
</mt:Ignore>
<script type="text/x-template" id="mf-component-relatedContent">
<div>
<div class="mb-4">
<label class="d-block">リンクのラベル</label>
<input type="text" class="form-control" v-model="item.data.relatedContentLabel">
</div>
<div class="mb-4">
<label class="d-block">リンクのタイプ</label>
<select class="custom-select form-control" v-model="item.data.relatedContentType">
<option value=""></option>
<option value="link">リンク</option>
<option value="file">ファイル</option>
<option value="image">画像</option>
</select>
</div>
<div class="mb-4" v-if="item.data.relatedContentType === 'link'">
<label class="d-block">URL</label>
<input type="url" class="form-control" v-model="item.data.relatedContentUrl">
</div>
<div class="mb-4" v-else-if="item.data.relatedContentType === 'file'">
<label class="d-block">ファイル</label>
<VueInnerAsset
:id="[item.id, 'relatedContentFile'].join('-')"
:item="item"
:storage="item.data"
:handle="'relatedContentFile'"
:fieldBlock="fieldBlocks['asset']" />
</div>
<div class="mb-4" v-else-if="item.data.relatedContentType === 'image'">
<label class="d-block">画像</label>
<VueInnerAsset
:id="[item.id, 'relatedContentImage'].join('-')"
:item="item"
:storage="item.data"
:handle="'relatedContentImage'"
:fieldBlock="fieldBlocks['image']" />
</div>
</div>
</script>
<mt:Ignore>VueRelatedContent というコンポーネントを定義(Vue.js)</mt:Ignore>
<script>
Vue.component('VueRelatedContent', {
props: { item: Object, version: Number, fieldBlocks: Object },
template: '#mf-component-relatedContent'
});
</script>
<mt:Ignore>type: 'relatedContent' のときに上記フィールドブロックが表示されるように MTAppjQuery に追加</mt:Ignore>
<mt:SetVarBlock name="mtapp_mf_additional_fields">
<template v-else-if="fieldBlocks[item.handle].type === 'relatedContent'">
<VueRelatedContent :item="item" :version="version" :fieldBlocks="fieldBlocks"></VueRelatedContent>
</template>
</mt:SetVarBlock>
これで下図のような動きのフィールドが出来ました。
このフィールドで保存されるデータは下記のようになります。
{
"items":[
{
"data":{
"relatedContentLabel":"今日のリンク(リンク)",
"relatedContentType":"link",
"relatedContentFile":{},
"relatedContentImage":{},
"relatedContentUrl":"https://tinybeans.net"
},
"handle":"relatedContent",
"id":"WeL3y80d"
},
{
"data":{
"relatedContentLabel":"今日のリンク(ファイル)",
"relatedContentType":"file",
"relatedContentFile":{
"id":"71",
"url":"/relatedcontent/0319119334403d04dda975cc67a14decbff4d9f2.pdf"
},
"relatedContentImage":{}
},
"handle":"relatedContent",
"id":"GrRur7Oy"
},
{
"data":{
"relatedContentLabel":"今日のリンク(画像)",
"relatedContentType":"image",
"relatedContentFile":{},
"relatedContentImage":{
"id":"72",
"url":"/relatedcontent/08b069c7e6eb73c62ea7ead0d948399e93ddfd80.jpg",
"thumbnail":"/relatedcontent/assets_c/2021/12/08b069c7e6eb73c62ea7ead0d948399e93ddfd80-thumb-120xauto-72.jpg"
}
},
"handle":"relatedContent",
"id":"hHspx1CK"
}
],
"version":2,
"ts":1638749765476
}
以上となります。
細かい解説は、、、必要でしたらサポートにお問い合わせください!
今後はもう少しオリジナルフィールドを楽に追加出来るようにしていきたいと思っています。