MovableType.net用の「余白」カスタムブロックを作る


国産CMSレンタルサービス「MovableType.net」は、ASPとは思えないほど高度なカスタマイズができます。
最近ではWordPressのGutenbergのようなブロックエディタが実装され、自作ブロックの追加も可能となっています。

MovableType.netに「余白ブロック」を追加する手順を解説します。

ブロックエディタに関する資料はまだ少ないですが、これらのURLが参考になります。

余白ブロックの設計

設計に興味がない人は読み飛ばしてください。

余白は、読みやすく美しいウェブページ作りには欠かせません。WordPressにも余白ブロックがありますが、余白の大きさがピクセル単位、かつインラインスタイルになってしまうという問題があります。

リテラシが低い層の利用を想定すると仕方がないのですが、適切な余白量はサイトのデザインや目的、閲覧している端末によって異なります。静謐なブランドサイトをデスクトップで閲覧した場合では60ピクセルは少なすぎ、学校サイトをスマートフォンで閲覧した場合では100ピクセルは多すぎるのです。

つまり、出力されるHTMLにはサイズを示すクラスのみ付与し、テーマごとにCSSで調整するのが、理想的な余白ブロックの設計と考えられます。今回は、以下のようなHTMLを書き出すようにしました。

<div class="echo-mt-be-spacer is-size-(選択したサイズ)"><hr></div>

カスタムブロックを作る


それでは、実際に作っていきます。

MovableType.netのメニューに「カスタムブロック」があるので「新規」を選択します。



作成画面でブロックを作成します。「識別子」にはテーマの接頭辞を付けることをおすすめします。私が今作成しているテーマは「echo」というので、ここでは echo_spacer としています。


なお、この画面の内容は、JSON形式で読み込み・書き出しができます。こちらをダウンロードしてください(このファイルだけではブロックは完成しません)。



「ブロック」にはこのブロックをブロックエディタで追加したときに自動で挿入されるブロック、または入力欄を設定します。
余白ブロックでは「ドロップダウン」をひとつ入れて、画像のとおり設定してください。

「カスタムスクリプト」は後ほど説明します。

「コンテナ要素で包む」は、このブロックを追加したときに、エディタにdiv要素で囲んで出力するか、というものです。今回は不要なのでチェックを外します。

「ブロックの追加と削除」は、さらにこのブロックの中に他のブロック(MovableType.netのコアブロックのみ)を入れ子にできるか、というものです。これもチェックを外します。



「アイコン」はSVG形式で作ってアップロードすると、書き出したJSONファイルにコードごと入ってくれます。
コアブロックのアイコンにあわせたテイストで、WordPressをパク…インスパイアして作りました。

設定が終わったら保存します。

ブロックを追加してみる


固定ページの編集画面へ移動して、実際にエディタで追加してみます。ブロックの一覧に「余白」が増えています。

追加するとドロップダウン=select要素だけが表示されているので、サイズを適当に選んで固定ページを保存します。



この時点で公開画面では、選択した項目が文字列になって出力されるだけです。「極大」を選んだなら「極大」です。
これをゴールとするHTMLに加工していきます。

テンプレートを編集する

ページテンプレート

メニューの「デザイン>テンプレート」から、ページテンプレートの編集画面へ移動します。
Movable Typeの固定ページの本文タグは <mt:PageBody> ですが、これを以下のコードに書き換えて更新します。

<mt:BlockEditorBlocks tag="PageBody">
    <mt:If name="type" eq="custom-echo_spacer">
        <mt:Include module="カスタムブロック-余白" __spacer_size__="$__value__" />
    <mt:Else>
        <mt:Var name="__value__" />
    </mt:If>
</mt:BlockEditorBlocks>

タグの意味をざっと説明すると、ブロックのタイプが custom-+(作成したブロックの識別子) だったときに余白ブロック用のテンプレートをインクルードしています。
かつ変数 value に入力した内容(極大とか)が入っているので、それをインクルード先で変数 spacer_size として参照できるようにしています。

なお、ドロップダウンなどの入力項目が複数あると、このように変数を渡すと配列として処理されているのか、エラーになってしまいました。これではシンプルなブロックしか作れないので、ちょっと運営のシックス・アパートに聞いてみます…

余白ブロック用のテンプレート

余白ブロック用のモジュールテンプレートを新規作成します。Movable Typeはテンプレート内にインクルードタグがあり、かつ同名のテンプレートがない場合は編集画面の右側に自動で作成リンクを作ってくれます。地味に便利です。

以下の通りコードを書いて保存します。

<mt:SetVar name="__spacer_class__" value="medium" />
<mt:If name="__spacer_size__" eq="極小">
    <mt:SetVar name="__spacer_class__" value="xsmall" />
<mt:ElseIf name="__spacer_size__" eq="小">
    <mt:SetVar name="__spacer_class__" value="small" />
<mt:ElseIf name="__spacer_size__" eq="大">
    <mt:SetVar name="__spacer_class__" value="large" />
<mt:ElseIf name="__spacer_size__" eq="極大">
    <mt:SetVar name="__spacer_class__" value="xlarge" />
</mt:If>
<div class="echo-mt-be-spacer is-size-<mt:Var name="__spacer_class__" />"><hr></div>

タグの意味をざっと説明すると、さっき渡した変数 spacer_size の値が「極大」だったら、クラス「echo-mt-be-spacer is-size-xlarge」を付与したdiv要素とhr要素を出力しています。「極小」「小」「大」も同様です。どれにも当てはまらなければ「中」となります。

これで、公開画面にイメージしたHTMLが出力されます。ちなみに公開画面のCSSは以下の通りです。

.echo-mt-be-spacer hr {
  margin: 0 !important;
  padding: 0 !important;
  border: 0 none !important;
  height: 0 !important;
  opacity: 0 !important;
}

.echo-mt-be-spacer.is-size-xsmall {
  height: 10px;
}

@media (min-width: 1000px) {
  .echo-mt-be-spacer.is-size-xsmall {
    height: 15px;
  }
}

.echo-mt-be-spacer.is-size-small {
  height: 20px;
}

@media (min-width: 1000px) {
  .echo-mt-be-spacer.is-size-small {
    height: 30px;
  }
}

.echo-mt-be-spacer.is-size-medium {
  height: 30px;
}

@media (min-width: 1000px) {
  .echo-mt-be-spacer.is-size-medium {
    height: 45px;
  }
}

.echo-mt-be-spacer.is-size-large {
  height: 40px;
}

@media (min-width: 1000px) {
  .echo-mt-be-spacer.is-size-large {
    height: 60px;
  }
}

.echo-mt-be-spacer.is-size-xlarge {
  height: 60px;
}

@media (min-width: 1000px) {
  .echo-mt-be-spacer.is-size-xlarge {
    height: 90px;
  }
}

カスタムスクリプト

カスタムブロック作成画面に出てきた「カスタムスクリプト」は、編集画面のエディタ内の、作成中のブロックに対してJavaScriptやCSSを追加できます。
編集画面以外では何も起きません(おそらく)。また、作成中のブロックをひとつも使用していない場合でも何も起きません。

余白ブロックの場合は、「極大」とだけ出力されていたものをプレビューでもそれらしく表示したいです。
以下の通りコードを書きました。

<script>
document.addEventListener('DOMContentLoaded', function () {
    var
        text = document.body.textContent,
        size = 'medium';

    text = text.replace( /\s+/g, '' );

    if( text.match( /^極小/ ) ) {
        size = 'xsmall';
    } else if( text.match( /^小/ ) ) {
        size = 'small';
    } else if( text.match( /^大/ ) ) {
        size = 'large';
    } else if( text.match( /^極大/ ) ) {
        size = 'xlarge';
    }

    document.body.innerHTML = '<div class="echo-mt-be-spacer is-size-' + size + '">余白:' + text + '</div>';
});
</script>

<style>
.echo-mt-be-spacer {
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px dotted rgba( 255,0,0,.5 );
}
.echo-mt-be-spacer.is-size-xsmall {
    height: 15px;
}
.echo-mt-be-spacer.is-size-small {
    height: 30px;
}
.echo-mt-be-spacer.is-size-medium {
    height: 45px;
}
.echo-mt-be-spacer.is-size-large {
    height: 60px;
}
.echo-mt-be-spacer.is-size-xlarge {
    height: 90px;
}
</style>

各カスタムブロックは、インラインフレームでプレビューが表示されています。そのフレームのHTMLにカスタムスクリプトが作用します。つまり document.body.textContent でプレビューの内容を取得、書き換えができるのです。

改行やコメントが入っているので、除去してから先程のブロック用テンプレートと同様に条件分岐で判別してHTMLを組み立てています。



カスタムスクリプトではCSSも追加しているので、どのくらいの余白が作成されるのかが、編集画面でもわかるようになりました。
プレビュー用のインラインフレームが100pxの高さがあるらしく、「極小」などを選択すると下に変な余白ができてしまうのが残念です。

ところで、 MTBlockEditorSetCompiledHtml という関数があり、これをカスタムスクリプトで使うと、エディタの入力内容そのもの=HTMLを書き換えてしまうことができます。

MTBlockEditorSetCompiledHtml( '<div class="echo-mt-be-block-spacer is-size-' + size + '"><hr></div>', { addEditHistory: true } );

ですが、出力されるHTMLはテーマ側でコントロールした方が良いかなと思い、今回は使用していません。


以上、MovableType.netでの余白ブロックの作成手順でした。

まだまだ不明点が多いですが、カスタムブロックに関してはいろいろと可能性がありそうです。むしろコアブロックがずいぶんシンプルなので、詳細なサイト設計に対応するために自作ブロックの追加を前提としているのでは…とすら思います。