ブロックエディターの基本


ブロックエディターでは、テキスト、画像、ファイルなどのコンテンツを「ブロック」単位で自由に組み立てることができ、みたままの視認性と柔軟性が大幅に向上します。

主な特徴・機能

  • HTMLのコピーアンドペーストに対応

  • スラッシュコマンド

    • マウスでブロックを選択しなくても、直感的にブロック挿入ができるようになります。

  • メディア機能に対応

    • メディアから画像やファイルを挿入することが可能

    • 大元のメディアで画像を差し替えても自動でブロックエディタ側も連動

  • インライン要素にカスタムクラス

    • 設定画面で設定した任意のクラスをインライン要素に設定可能

  • ブロック要素にカスタムクラス

    • 設定画面で設定した任意のクラスをブロック要素に設定可能

  • 2カラム・3カラムレイアウトに対応

    • みたままの状態でマルチカラムレイアウトに対応

  • マークダウンに対応

    • マークダウン記法で入力すると自動的にHTMLに変換します

使用方法

編集テンプレートのカスタムフィールド例

カスタムフィールドをブロックエディタにする場合は、以下のように記述します。

記述ルール

  • <acms-block-editor> タグを使う

  • <acms-block-editor> の子孫のうち最初に見つかった <input type="hidden"> が、編集後のHTMLの格納先として自動的に使われる

  • 必ず <input type="hidden" name="xxxxx:extension" value="block-editor" /> を指定する

  • root-class でブロックエディター要素に付与されるクラス属性を設定可能

<!-- 推奨(Web Component) -->
<acms-block-editor root-class="acms-admin-form-width-full" settings="{...}">
  <input type="hidden" name="hoge" value="{hoge}">
</acms-block-editor>
<input type="hidden" name="field[]" value="hoge">
<input type="hidden" name="hoge:extension" value="block-editor" />

<!-- 旧方式(今後も動作するが非推奨。自動的に <acms-block-editor> へ変換される) -->
<div class="js-block-editor" data-target=".js-target" data-html=".js-html">
  <div class="js-target acms-admin-form-width-full"></div>
  <input type="hidden" class="js-html" name="hoge" value="{hoge}">
  <input type="hidden" name="field[]" value="hoge">
 <input type="hidden" name="hoge:extension" value="block-editor" />
</div>

表示テンプレートの出力例

ブロックエディタで編集したHTMLを出力するには、以下のように記述します。

記述ルール

  • 必ず raw (標準テンプレート)or safe_html (twigテンプレート)校正オプションを指定

{hoge}[raw] <!-- 標準テンプレートの場合 -->
{{ hoge|safe_html }} <!-- Twigテンプレートの場合 -->

基本設定

初期設定が js/config.js で設定されています。

blockEditorConfig: {
  setMainImageMark: '.js-block-editor-set-main-image',
  tableScrollableWrapperClass: 'acms-table-scrollable',
  tableScrollableClass: 'js-table-unit-scroll-hint',
  /**
    * BlockEditorコンポーネントに渡されるprops
    */
  editorProps: {
    editorProps: {
      attributes: {
        class: 'acms-entry',
      },
    },
  },
},

またeditor-props 属性でフィールド毎に設定を上書き可能です。ブロックエディターの編集領域に付与されるクラスをこのブロックエディターフィールドのみ上書きしています

<acms-block-editor
  editor-props='\{"attributes":\{"class":"custom-body-class"\}\}'
>
 ...
</acms-block-editor>

上記の例では、テンプレートエンジンに変数として解決されないようにするため、波括弧をエスケープしています。@verbatimブロックを利用することでも同様の回避が可能です。

メイン画像設定機能

メディア画像のメニューにメイン画像に設定するボタンが用意されています。このボタンを押した時に blockEditorConfig.setMainImageMark に設定されているセレクタの要素(メディアのカスタムフィールド)に、選択している画像をセットします。

メイン画像に設定ボタンを押すことにより、メイン画像に設定できます。
メイン画像に設定する

カスタムフィールド例

<div class="js-media-field">
  <div class="js-droparea" data-thumbnail="{entry_main_image@thumbnail}" data-type="image" style="width:200px"></div>
  <p class="js-text acms-admin-text-danger" style="display:none">許可されていないファイルのため挿入できません。</p>
  <div class="acms-admin-margin-top-mini">
    <button type="button" class="js-insert acms-admin-btn" data-type="image">メディアを選択</button>
  </div>
  <input type="hidden" name="entry_main_image" value="{entry_main_image}" class="js-value js-block-editor-set-main-image" />
  <input type="hidden" name="field[]" value="entry_main_image" />
  <input type="hidden" name="entry_main_image:extension" value="media" />
</div>

従来は、メディア・画像ユニットのみメイン画像に設定することができましたが、Ver. 3.2 から メディアのカスタムフィールドを、Entry_Summaryなどのモジュールで、メイン画像として出力できるようになりました。


テーブルのクラス設定

テーブルのメニューにテーブルを横スクロールして表示するように設定するボタンが用意されています。このボタンを押した時、テーブルのHTMLに設定されるクラスを設定できるようになっています。

スクロールするテーブルにするボタンを押すことで、テーブルが横スクロースされて表示できるようになります。
スクロールするテーブルにする

設定

説明

初期値

blockEditorConfig.tableScrollableWrapperClass

table要素の親要素につけるクラス

‘acms-table-scrollable’

blockEditorConfig.tableScrollableClass

table要素につけるクラス

‘js-table-unit-scroll-hint’

スクロールするテーブルのHTML例

<div class="tableWrapper acms-table-scrollable">
  <table class="js-table-unit-scroll-hint" data-scrollable="true">
    <tbody>
      <tr>
        <td>...</td>
        <td>...</td>
        <td>...</td>
      </tr>
    </tbody>
  </table>
</div>

出力HTMLを囲う要素のクラス名設定

ブロックエディタで出力されるコンテンツ全体を囲む要素に、任意のクラス名を設定することができます。このクラスは管理画面のブロックエディタ編集画面に反映され、独自のスタイル調整に活用できます。

設定

説明

初期値

blockEditorConfig.editorProps.editorProps.attributes.class

コンテンツを囲う親divに設定されるクラス名

‘acms-entry’

編集画面のHTML例

<div class="js-block-editor" data-target=".js-target" data-html=".js-html">
  <div class="js-target acms-admin-form-width-full">
    <div class="acms-admin-block-editor-container">
      <div class="acms-admin-block-editor">
        <div class="acms-admin-block-editor-content" aria-expanded="false">
          <div contenteditable="true" translate="no" class="tiptap ProseMirror entry-style" tabindex="0" autocomplete="off" autocorrect="off" autocapitalize="off" aria-expanded="false">
            編集しているHTML...
          </div>
        </div>
      </div>
    </div>
  </div>
  <input type="hidden" class="js-html" name="xxxxxxxx" value="xxxxxxxxx">
</div>

設定を変更する場合

設定を変更する際は、js/config.js を直接編集しないでください
将来的なアップデートやテーマの互換性維持のため、設定の上書きはテーマ内の HTML テンプレートなどで行ってください。

例:テンプレート内での上書き方法

<script>
ACMS.Ready(() => {
  ACMS.Config.blockEditorConfig.tableScrollableWrapperClass = 'c-table__wrapper';
  ACMS.Config.blockEditorConfig.tableScrollableClass = 'c-table__scrollable';
});
</script>

画像の拡大機能の設定

画像の拡大を行うための識別子として、画像リンクの class 属性に、設定する値を設定できます。デフォルト値は js-smartphoto で、標準ではSmartPhotoを使って画像を拡大させます。

また data-group 属性にエントリーID が自動で付与されます。

他設定と違い js/config.js ではなく private/config.system.yaml で行います。

block_editor_lightbox_class: js-smartphoto

メディア画像の出力例

<a href="/path/to/sample.png?v=20250710172457" class="js-smartphoto" data-group="169">
  <img src="/path/to/sample.png?v=20250710172457" class="unit-id-169 in-view" width="1200" height="675" loading="lazy" data-mid="50" alt="xxxxxx">
</a>

<acms-block-editor> のJavaScript API

<acms-block-editor> 要素は、編集中の内容を外部のJavaScriptから参照するための最小限のAPIを公開しています。テーマ独自のJS(文字数カウンター、保存ボタンの制御、プレビュー連携など)から利用できます。

editor プロパティ(読み取り専用)

ブロックエディターが内部で使用しているリッチテキストエディター(tiptap)の Editor インスタンスを返します。エディター本体はページ読み込み後に遅延して初期化されるため、マウントが完了していない間は null を返します。

const el = document.querySelector('acms-block-editor');
console.log(el.editor); // tiptap の Editor インスタンス、または null(未マウント時)

editor から呼べる主な機能(tiptapの標準API):

メソッド/プロパティ

内容

el.editor.getHTML()

現在の編集内容をHTML文字列で取得

el.editor.getText()

プレーンテキストとして取得

el.editor.isEmpty

本文が空かどうか

el.editor.state, el.editor.on(...)

より高度な状態取得・イベント監視(tiptap公式ドキュメント参照)

注意(マウントのタイミング): editor は要素がDOMに追加された直後は null になっている場合があります。確実に値を取得したい場合は、後述の change イベントを1回受け取った後にアクセスしてください。

value プロパティは提供していません。他のカスタム要素(<acms-tag-select> 等)と異なり、編集内容全体を1つの値としてまとめて読み書きするAPIはありません。内容を取得・変更したい場合は必ず editor 経由でtiptapのAPIを使用してください。

change イベント

編集内容が変更され、フォーム送信用の hidden input への反映が完了した直後に発火します。標準の CustomEventbubbles: true のため、祖先要素でも購読できます。

document.querySelector('acms-block-editor').addEventListener('change', (event) => {
  const el = event.currentTarget;
  console.log(el.editor?.getHTML());
});

注意(発火頻度): 文字入力・書式変更のたびに発火するため、1文字ごとに何度も呼ばれます。重い処理をハンドラ内に直接書くと画面の反応が悪くなるため、debounce(一定時間操作が止まってから実行)を挟むことを推奨します。

このイベントとフォーム送信の関係: change はあくまで「変更があった」ことの通知用です。フォーム送信時に実際に送られる値は、<acms-block-editor> 内の hidden input の値そのものであり、このイベント自体は送信処理に関与しません。