📒

MTブロックエディタのカスタムブロックで出力タグを独自のHTMLにカスタマイズする方法

2022/09/07に公開

はじめに

MT ブロックエディタを使っていて、 MT が出力する固定の HTML タグを利用して HTML を組み込むのが面倒で、任意の HTML タグに当て込むことはできないだろうかと思って調べたらできたので記録しておく。

MT ブロックエディタの使い方をなんとなく理解していないとわからないと思うので、 MT ブロックエディタが分からない人は以下の公式のページを見ると何となく分かるかも。

https://movabletype.github.io/mt-block-editor/

MTブロックエディタとは

MovableType7 に標準で搭載されているブロックエディタとは別もの。

シックス・アパート社が提供する公式プラグイン。

元々 MovableType.net で提供していた機能のようだけど、使い勝手が良いからなのか、ソフトウェア版の MovableType でも利用できるようにプラグインとして提供されている。

繰り返し入力項目などの実装の際に利用すると便利なので、案件ではたまに利用している。

https://www.movabletype.jp/documentation/mt7/admin-guide/manage-site/mt-blockeditor/

https://github.com/movabletype/mt-plugin-MTBlockEditor

今回の例で利用する MT ブロックエディタのカスタムブロックのフィールド設定

項目名 フィールドタイプ class名
所属 テキスト affiliation
役職 テキスト position
氏名 テキスト name
詳細 テキスト (複数行) description
画像 画像 image

上記の設定に加え、親の div タグの class 属性に wrapper を付与する設定を追加。

MTブロックエディタの出力タグをカスタマイズする

自分の場合、コーディングは他者が実装して MT への取り込みは自分が担当するといったことが多いため、実装された HTML に対して MT のコードを埋め込んでいく形になる。

だけど、 MT ブロックエディタのカスタムブロックは、カスタムスクリプトの設定をせずにそのままカスタムブロックの内容を出力すると、固定の HTML タグが吐き出されてしまう。
親の div タグを指定したり、 class 属性を付与したりと微調整できるけど、 MT ブロックエディタを利用する場合は MT が吐き出すタグに合わせてコーディングする必要があるので、結構面倒くさく、デザインによっては対応できないことがある。

そこで、 MT ブロックエディタのカスタムスクリプトの機能を利用すると、任意の HTML タグの構造に置き換えることができる。
以下にカスタムスクリプト利用前と利用後の出力タグイメージを記載する。

カスタムスクリプト利用前の出力タグイメージ

<!-- MT が静的ファイルに出力する際、固定の HTML 形式で出力してしまう -->
<div class='wrapper'>
    <p class="affiliation">所属テキスト</p>
    <p class="position">役職テキスト</p>
    <p class="name">氏名テキスト</p>
    <p class="description">詳細分テキスト詳細分テキスト詳細分テキスト詳細分テキスト詳細分テキスト。<br/><br/>詳細分テキスト詳細分テキスト詳細分テキスト。</p>
    <p class="image">
      <img src="..." alt="" width="500" height="500" class="asset asset-image" style="max-width:100%;height:auto;display:block"/>
    </p>
</div>

カスタムスクリプト利用後の出力タグイメージ

<!-- 任意の箇所にブロックエディタで入力したテキストを出力できるため、自由に HTML タグを組める -->
<div class="speaker">
  <div class="speaker-info">
    <div class="speaker-img"><img src="..." width="100%" /></div>
    <div class="speaker-member">
      <p class="speaker-member-affiliation">所属テキスト</p>
      <p class="speaker-member-name"><span>役職テキスト</span>氏名テキスト</p>
    </div>
  </div>
  <div class="speaker-description">
    <p>詳細分テキスト詳細分テキスト詳細分テキスト詳細分テキスト詳細分テキスト。<br>詳細分テキスト詳細分テキスト詳細分テキスト。</p>
  </div>
</div>

カスタムブロック設定からカスタムスクリプトの設定を登録する

上記のイメージのように、カスタムブロックの出力タグを任意の HTML タグに置き換えたい場合は、 MT ブロックエディタのカスタムブロック設定から行う。

設定ページに移動したら、カスタムスクリプトという入力項目があるので、そこに設定を記載する。

今回カスタムスクリプトに設定するコードの全文は以下の通り。

<style>
  .speaker {
    width: 500px;
    margin: auto;
    padding: 20px;
    background-color: #eee;
  }
  .speaker-info {
    display: flex;
    flex-wrap: wrap;
    gap: 25px;
  }
  .speaker-img {
    width: 100px;
  }
  .speaker-member {
    flex-grow: 1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }
  .speaker-member > * {
    width: 100%;
  }
  .speaker-member-name span {
    font-size: 0.7rem;
    margin-right: 5px;
  }
  .speaker-description {
    margin-top: 15px;
    padding: 10px;
    font-size: 0.8rem;
    line-height: 1.7;
  }
</style>

<script>
  document.addEventListener("DOMContentLoaded", () => {
    if (document.body.dataset.hasCompiledHtml) { return; }

    // カスタムブロックの入力項目データを取得
    const affiliation = document.querySelector('.affiliation').textContent;
    const position = document.querySelector('.position').textContent;
    const name = document.querySelector('.name').textContent;
    const description = document.querySelector('.description').innerHTML;
    const image = document.querySelector('.image img').getAttribute('src');

    // 今回反映する HTML を文字列リテラルで記載
    const output = `<div class="speaker">
        <div class="speaker-info">
          <div class="speaker-img"><img src="${image}" width="100%" /></div>
          <div class="speaker-member">
            <p class="speaker-member-affiliation">${affiliation}</p>
            <p class="speaker-member-name"><span>${position}</span>${name}</p>
          </div>
        </div>
        <div class="speaker-description">
          <p>${description}</p>
        </div>
      </div>`;

    // 反映
    MTBlockEditorSetCompiledHtml(output, true);
  });
</script>

カスタムスクリプトへの記述ポイント

style ブロック

カスタムスクリプトに style ブロックを作成して CSS を設定すると、管理ページのカスタムブロック表示エリアでも、表示を整えることができる。

実際に公開されるレイアウトで確認できると使い勝手も良いのでおすすめ。

style による調整なしの場合

style で調整した場合

document.body.dataset.hasCompiledHtml について

よく分からない!
公式には以下のように記載されている。
なにか分かったら追記します。

「出力されるHTML」で表示された場合には「document.body.dataset.hasCompiledHtml」の値が真になります。

任意の HTML を当て込む

任意の HTML タグを文字列リテラルで作成し、 MTBlockEditorSetCompiledHtml() の第1引数に渡すと、 MT が再構築した際に出力する HTML データと、管理画面のカスタムブロックのプレビュー上に反映される。

カスタムブロック内で入力した各項目の入力データを取得するには、カスタブロックの各入力項目に設定した class 名を利用して Javascript で取得する。

ここらへんはただの Javascript なので、取得したい情報などは色々応用効くと思う。

// テキストだけの場合はこっち
const affiliation = document.querySelector('.affiliation').textContent;
// HTML も取得したい場合はこっち (複数行テキストなどで br タグが入ってる場合など)
const description = document.querySelector('.description').innerHTML;

入力項目のデータを取得したら、任意の HTML タグを文字列リテラルで構築して、 MTBlockEditorSetCompiledHtml() の第1引数に渡して実行する処理を記載する。

const output = `<div class="speaker">
<div class="speaker-info">
  <div class="speaker-img"><img src="${image}" width="100%" /></div>
  <div class="speaker-member">
    <p class="speaker-member-affiliation">${affiliation}</p>
    <p class="speaker-member-name"><span>${position}</span>${name}</p>
  </div>
</div>
<div class="speaker-description">
  <p>${description}</p>
</div>
</div>`;

MTBlockEditorSetCompiledHtml(output, true);

まとめ

このように任意の HTML タグを利用できると、 HTML の組み込みの際に MT の出力形式を考慮しなくてよくなるので、 HTML コーディングもかなり楽になると思う。

とくに自分の場合は他者に HTML を組んでもらい、 MT の組み込みを担当することがほとんどなので、この機能があるのは大変助かる。

Discussion