ComponentBlocksプラグインは、設計済のHTML/CSSコンポーネントに対応した入力フィールドを用意するためのブロックエディタです。Vue.jsを用いて開発されています。
はじめに記事モデル等で本文を記述する際に利用する「ブロック」をブロックモデルに登録します。
カラム名 | 入力内容 |
---|---|
ラベル | ブロックの名称です。ブロックエディタでブロックを選択するドロップダウンに表示されます。 |
フィールド | 入力欄を定義します。チェックボックス・ラジオボタンの選択肢やリレーションで紐付ける対象のモデルは「詳細設定」ボタンを押して設定してください。
|
繰り返しフィールド | dl要素におけるdt+dd のセット、table要素におけるth+td のセットのように同一の入力フィールドを繰り返し利用する入力欄を定義します。設定内容はフィールドと同一です。 |
マルチブロックを使用 | 繰り返しフィールドに似ていますが、コンテナ(1つの入力セット)毎に任意のブロックを追加していくことができます。入力内容が定まっていないカラムレイアウト等に使用します。これにチェックを入れた場合、フィールド・繰り返しフィールドの定義は必要ありません。代わりにマルチブロック内で利用できるブロックを指定してください。 |
テンプレート | 入力欄のカスタマイズができます。詳細はテンプレートをご覧ください。 |
methods | 独自の処理を追加できます。詳細はmethodsの追加(上級者向け)をご覧ください。 |
利用できるブロック | マルチブロック内で指定できるブロックを選択します。 |
モデル | 今定義しているブロックが利用可能なモデルを指定します。(モデルの指定を忘れるとブロックエディタのブロック選択ドロップダウンに表示されません。) |
コンポーネント名 | ブロックを識別するための名称を英数字で指定します。名称はCMS内で一意である必要があります。パスカルケース(アッパーキャメルケース)で入力してください。例えば見出しブロックの場合はHeading などと命名します。(Editor , ImageSelector , ObjectSelector , MultiBlockEdit , などは既にシステムで使用しているため設定できません。) |
ブロックエディタを使用したいモデルの編集画面を開き、block_editカラム(カラム名は任意)を追加して編集表示を「コンポーネントブロック」に設定します。記事(Entry)モデルの本文(text)カラムをリッチテキストエディタからコンポーネントブロックに変更することも可能です。プロジェクト毎に検討の上設定を行ってください。
ブロックエディタで入力したコンテンツはJSON形式で保存されています。入力フィールドで「保存されるデータ」を開くと確認できます。1ブロック1オブジェクトになっています。よって、保存されている値を取り出してfrom_json
モディファイアでJSONオブジェクトに変換した後にループするとブロックのデータを取り出すことができます。
記事のblock_editカラムにおいて見出し・テキスト・テーブルブロックを使用した場合のテンプレートを示します。
ブロック | 入力内容 | キー |
---|---|---|
見出しブロック | 見出しテキスト | text |
見出しレベル | level | |
テキストブロック | テキスト | text |
テーブルブロック | 列見出し | th |
データ | td |
<mt:entryblockedit from_json="blocks" />
<mt:loop name="blocks"><mt:ignore>blocksをループで回すとブロックのデータを1つずつ取り出すことができる</mt:ignore>
<mt:if name="type" eq="Heading"><mt:ignore>typeにコンポーネント名が入っている</mt:ignore>
<mt:ignore>見出しブロック:見出しレベルに応じてHTMLを出力</mt:ignore>
<mt:ignore>level, textはテンプレート・データ定義で入力した「キー」です</mt:ignore>
<mt:if name="level" eq="2">
<h2><mt:var name="text" escape /></h2>
<mt:elseif name="level" eq="3">
<h3><mt:var name="text" escape /></h3>
<mt:elseif name="level" eq="4">
<h4><mt:var name="text" escape /></h4>
</mt:if>
<mt:elseif name="type" eq="Text">
<mt:ignore>テキストブロック:エディタの入力内容をそのまま出力</mt:ignore>
<mt:var name="text" />
<mt:elseif name="type" eq="Table">
<mt:ignore>テーブルブロック:繰り返しフィールドの入力内容がfieldsに入っているのでループして出力</mt:ignore>
<mt:loop name="fields">
<mt:if name="__first__"><table></mt:if>
<tr>
<th><mt:var name="th" escape /></th>
<td><mt:var name="td" remove_html /></td>
</tr>
<mt:if name="__last__"></table></mt:if>
</mt:loop>
</mt:if>
</mt:loop>
user.cssを用いて任意のスタイルを適用することが可能です。Bootstrap v4のコンポーネントやユーティリティが利用できます。
例えば特定のブロックをマルチブロック内でのみ選択可能としたい場合や特定のカラムでのみ使用したい場合、JavaScriptを用いて選択肢から除外することができます。</body>
の直前で実行してください。
delete window.componentBlocks[0][0].enableBlocks.Heading;
// delete window.componentBlocks[何個目のエディタか - 1][0].enableBlocks.コンポーネント名;
またuser.cssを利用して、CSSで選択肢から隠す方法もあります。
ブロックの表示をCSSのみで希望の見た目にできない場合など、テンプレートを編集することでHTMLを変更することができます。
テンプレート入力欄の下にある「標準テンプレート」ボタンをクリックして標準テンプレートを取得した後で希望のHTMLに変更してください。MTBlockParts
タグ・MTBlockPartsFields
タグは入力フィールドに置き変えられます。(Vue.js・Bootstrapの作法を隠し編集しやすくするために独自のタグを利用しています。)
姓・名と何らかの選択肢を表示する場合の例を元に説明します。
name
属性の代わりにv-model
属性を指定しますv-model
属性値の内容はフィールド・繰り返しフィールドで定義したキーを指定します。
element.
を付けてください(プラグインの仕様によるものです)v-model.number
としてください
value
属性は:value
にしてください<div>
<label>姓 <input type="text" v-model="element.family"></label>
</div>
<div>
<label>名 <input type="text" v-model="element.given"></label>
</div>
<div>
<label><input type="radio" v-model.number="element.select" :value="1">選択肢1</label>
<label><input type="radio" v-model.number="element.select" :value="2">選択肢2</label>
</div>
下記のように<ImageSelector>
コンポーネントを配置します。field-key
には入力欄を識別するキー(フィールド・繰り返しフィールドで定義したキー)を指定します。
<ImageSelector :element="element" field-key="キーを指定" />
下記のように<ObjectSelector>
コンポーネントを配置します。model
には選択したいオブジェクトが存在するモデルを指定します。field-key
には入力欄を識別するキー(フィールド・繰り返しフィールドで定義したキー)を指定します。
<ObjectSelector :element="element" class="image" field-key="キーを指定" />
class
属性を指定することで選択可能なファイルの種類を限定できます。image
・file
・pdf
のいずれかを指定します。下記のように<Editor>
コンポーネントを配置します。強調やリンクの設定を目的としたミニマムなエディタです。:init
の内容を変更することでエディタの設定を変更できます。(詳細は「Vue integration | Docs | TinyMCE」を参照してください。)
<Editor :init="store.initTextEditor" v-model="element.text" class="form-control inline-mce text" :id="element.id" />
下記のように<MultiBlockEdit>
コンポーネントを配置します。
<MultiBlockEdit :element="element" :enableblocks="enableBlocks" />
Vue.jsのコンポーネントに記述するmethods
を追加可能です。methodsを追加する場合はテンプレートもゼロから記述する必要があります。Vue.jsで子コンポーネントから親コンポーネントのプロパティを変更することはベストプラクティスではない(「プロパティ | Vue.js」を参照)とされますが、本プロジェクトではCMSに組み込んで利用する際の簡便さを優先してプロパティを変更しています。
this.element
でアクセスできるブロックのデータは編集画面の「保存されるデータ」で確認できますが、下記のようなオブジェクトです。
{ "id":"zqtagryg", "type":"Heading", "text":"見出しテキストが入ります", "level":2 }
onBlurHandler() {
// NOTE: this.elementでブロックのデータにアクセスできる
if (this.element.fields.some(field => !field.key)) {
this.element.invalid = true;
} else {
this.element.invalid = false;
}
},
ブロックで利用したい任意のスクリプトを追加することができます。新たにPowerCMS Xのプラグインを作成し、template_sourceコールバックで下記の変数に必要なコードを追加してください。
変数名 | 内容 | 例 |
---|---|---|
component_blocks_add_script | script要素でJavaScriptをロードします。 | <script src="/path/to/foo.js"></script> |
component_blocks_custom_script | Vue.createApp() の直後(mount() より前)にスクリプトを追加できます。ここでVue.defineComponent() を利用してコンポーネントを完全に自作する場合も、管理画面でブロックの名称、フィールド・繰り返しフィールドの定義、利用可能なモデルの指定、コンポーネント名の指定は行ってください。 |
|
true
に設定することでVue.jsのプロダクションモードを無効化することができます(Vue.js devtoolsが利用可能になります)[
// 通常のブロック
{
"id":"o3uof3k0",
"type":"Heading",
"text":"サンプル見出し①", // 自身で決めたキーに入力値が保存される
"level":2 // 自身で決めたキーに入力値が保存される
},
// 増減するフィールドを持つブロック
{
"id":"1rxxugt0",
"type":"Dl",
"invalid":false,
// fieldsに入力欄のセット(例:dt+ddの入力フィールド)が入る
"fields":[
{
"id":"mhg0mhbs",
"key":"資料はありますか?", // 自身で決めたキーに入力値が保存される
"value":"はい、ございます。" // 自身で決めたキーに入力値が保存される
},
{
"id":"gpnqwswr",
"key":" 製品デモが見たい",
"value":"担当者がお伺いしてご説明いたします。"
},
{
"id":"mqk5o0fs",
"key":"どのような環境が必要ですか?",
"value":"詳細については「インストール」ページを参照ください。"
}
]
},
// マルチブロック
{
"id":"g8fu970o",
"type":"MultiBlockExample",
"useMultiBlock":true,
// containersにコンテナのデータが入る
"containers":[
{
"id":"l6rmym1x",
// コンテナ内に追加したブロックはblocksに入る
"blocks":[
{
"id":"ixomjt7b",
"type":"Heading",
"text":"1カラム目見出し",
"level":2
},
{
"id":"vuqjzlao",
"type":"Text",
"text":"<p>テキストが入ります。</p>"
}
]
},
{
"id":"hh43n1vp",
"blocks":[
{
"id":"rv3ct3x4",
"type":"Heading",
"text":"2カラム目見出し",
"level":2
},
{
"id":"6ua2hypf",
"type":"Text",
"text":"<p>テキストが入ります。</p>"
}
]
}
]
}
]