Movable Type カスタムブロック利用時の15万文字制限への対処アイディア
ども、どもども、西山です。
この記事は、Movable Type Advent Calendar 2023、15日目の記事です。
このブログでも数多く取り上げているMovable Typeのブロックエディタ、皆さん利用してますか?
私…というか弊社では、めちゃくちゃ使ってます。
ブロックエディタが利用できるようになって以降、弊社はもちろん弊社クライアントからも大好評で、ウェブサイトの運営がかなり楽しくなっています。
ただ、楽しくなるに連れ、少しづつ凝ったことをしたくなるのが人情…
今年公開になったウェブサイトでもカスタムブロックをたくさん作って、とても更新しやすいウェブサイトができました。
…といいたいところですが、実はちょっと困ったことがありました。
それが今日のテーマ「カスタムブロックの15万文字制限」の問題です。
カスタムブロックの15万文字制限とは
例えば、こんな感じのアコーディオンで開閉するコンテンツがあったとします。
この黒いバーの部分をクリック(タップ)することでアコーディオンが展開するボタンになっています。
クリックすると以下のようなカタチで開きます。
この部分はカスタムブロックで「アコーディオンメニュー」という親ブロックを作り、その中に「アコーディオンメニュー(コンテンツ)」という子ブロックを含むように作られています。
これを使って、1つのウェブページ内に複数のブロック(ここではアコーディオンメニューブロックと呼びます)を設置するウェブページを作りました。
HTMLを書こうと思うと、なかなかしんどい数(トータル38個)ですが、ブロックエディタなのでサクサクと入力が進みます。
ところが、一通り入力を終えて保存しようとしたところ、「本文と続きはあわせて15万文字以内で入力してください」とエラーが出てしまいました。
状況がよくわからないまま、ブロックを1つ削っては保存を繰り返したところ、7〜8個以上のアコーディオンメニューブロックを保存しようとしたところで、このエラーが発生することがわかりました。
全部で38個を入力しようとしているのに、ぜんぜん足りない(汗)
というか、7〜8個程度のブロックで15万文字も入力している??
そこで、素のHTMLでどれくらいの文字数になるのか確認したところ、全38個のブロックでも9.5万文字程度とわかりました。
単純計算だと、8個のブロックで2万文字程度しか保存していないのに、このエラーが出たことになります。
なにが原因かを確認していくと、1つの可能性を見つけました。
これ、なんだかわかりますか?
実はこれ、1つのアコーディオンメニューブロックを保存する際に実際に保存されているコードで、カスタムブロックの構造や、入力しているHTMLなどをJSON形式(?)で保存しているようです。
なにか適当なカスタムブロックを「コピー」して、テキストエディタ等に貼り付けると確認できると思います。
参考:ブロックエディタの機能強化を行いました(2022.07.14)
そしてよく見ると、カスタムスクリプトで加工しているHTMLがすべてエンティティされているのがわかります。
<p>北海道がんセンター</p>
↓
<!-- mt-beb --><p>北海道がんセンター</p><!-- /mt-beb -->
↓
<!-- mt-beb --><p>北海道がんセンター</p><!-- /mt-beb -->
↓
&lt;!-- mt-beb --&gt;&lt;p&gt;北海道がんセンター&lt;/p&gt;&lt;!-- /mt-beb --&gt;
おそらくカスタムブロックのプレビューを表示したり、入力内容を再編集したりするためにこのようなカタチで保存する必要があるのだと思いますが、この影響で、実際に出力したいHTMLよりもデータとして保存する文字数が増えているようです。
1つのアコーディオンメニューブロックで実際に出力したいHTMLがおよそ2,500文字であるのに対し、保存されるJSONデータはおよそ2万文字ありました。
そのため、アコーディオンメニューブロックを7つ保存した時点でJSONデータは14万文字となり、8個めで15万文字を超えることになります。
よって、15万文字制限はこのJSONの影響じゃないかなと考えました。
なんとなく原因がわかったので、カスタムブロックやカスタムスクリプトを見直すことも考えましたが、納期まで時間がない…
そこでひとまず、管理画面にHTMLコードをそのまま貼り付けることで凌ぐこととしましたが、これではせっかくのブロックエディタが活用できないので、なにか良い方法はないかと考えました。
15万文字制限を回避するアイディア
カスタムブロックの構造やカスタムスクリプトの中身を見直すことで解消できるかもと思いつつ、大幅な文字数削減にはならない気がしたので、他の方法を探していたところ、思い出したのが、MTBlockEditorBlocksタグです。
以前、このブログでも紹介したとおり、このタグを使用すると、ウェブページ内にテンプレート・モジュールを読み込むことが可能となります。
つまり今回の場合、アコーディオンメニューブロックを1つずつ下層ウェブページで登録し、親のウェブページからは下層ウェブページのHTMLを読み込む方法を考えてみました。
これなら、親のウェブページで大量のJSONデータを保存することはなくなるはずです。
手順1:下層フォルダを作成
まず、各アコーディオンメニューブロックを登録していく下層ウェブページを格納するフォルダを用意します。
今回は7つのカテゴリ(分類)が必要だったので、以下のようにフォルダを作りました。
手順2:カスタムブロックを作成
続けて、特定のフォルダに入っているHTMLを読み込むためのカスタムブロックを作ります。
先ほどの記事にあるとおり、以下のように作成しました。
手順3:ウェブページのテンプレートを編集
ウェブページのテンプレートにある<mt:PageBody />部分を以下のように書き換えます。
<mt:BlockEditorBlocks tag="PageBody">
<mt:If name="type" eq="custom-trials_module">
<mt:Include module="治験内容" folder_label="$__value__" />
<mt:Else>
<mt:Var name="__value__" replace="$dev_url","$website_path" />
</mt:If>
</mt:BlockEditorBlocks>
カスタムブロック「治験内容」を使用すると、テンプレート・モジュール「治験内容」の内容を読み込みつつ、カスタムブロックで選択したオプション名(フォルダ名)がfolder_labelにセットされます。
カスタムブロックとテンプレート・モジュールの名前は分けるべきでしたね…
手順4:テンプレート・モジュールを作成
テンプレート・モジュール「治験内容」を以下の内容で作成します。
<mt:PageID setvar="this_id" />
<mt:Pages folder="$folder_label" include_subfolders="1">
<mt:If tag="PageID" ne="$this_id">
<mt:PageBody />
</mt:If>
</mt:Pages>
このテンプレート・モジュールが読み込まれたとき、カスタムブロックで選択した「オプション名」と同じ名前の下層フォルダに含まれるウェブページの<mt:PageBody />が出力されます。
手順5:下層ウェブページにアコーディオンメニューブロックを設置
下層フォルダに格納するウェブページ(アコーディオンメニューブロックが設置されるページ)を作っていきます。
一通り下層ページを作成すると、以下のようにウェブページが出来上がりました。
手順6:親ページでカスタムブロックを設置
最後に親ページでカスタムブロック「治験内容」を使用して、テンプレート・モジュールを読み込みます。
ここでは「悪性リンパ腫」というカテゴリだけですが、同じようにそれ以外のカテゴリも作っていくと、親ページの完成となります。
親ページの文字数はどうなったか
親のウェブページでは、モジュールを読み込むためのカスタムブロック(274文字程度)のみを設置するため、全7カテゴリあっても、2,000文字程度までダイエットすることができました!
これで15万文字制限を回避できそうです。
留意点
MovableType.netでは、すべてのコンテンツをsitemap.xmlに自動出力するので、今回作成した下層ウェブページがどこからもリンクされていなかったとしても、sitemap.xmlには記載されてしまいます。
今回のBlockEditorBlocksを使ったテンプレート・モジュールの読み込みを利用するアイディア、なかなか良いんじゃないかなと思いましたが、公開予定の無いページもGoogleさんに拾われる可能性があることだけは留意が必要かなと思います。
今回は、仮に下層ウェブページにアクセスしてもナビゲーション等が通常通り表示されるので大きな問題はないと判断していますが、場合によってはこれらのページだけ、少し加工する必要があるかもしれませんね。
最後に
今回も3年前の自分のブログ記事に助けられました。
アウトプット、とても大切…(笑)
ウェブページで保存できる文字数が15万文字に制限されている理由はわかりませんが、今後、コンテンツを作っていく際に同じ状況になった場合はこのアイディアが活かせそうです。
また、今回の対応を取っていて思ったのですが、そもそそも1ページ内に38個ものアコーディオンを設置するようなケースで、カスタムブロックを38個並べるのは、機能としては良くても、編集・更新時にはなかなか厳しいです(苦笑)
カスタムブロックをよく利用されている方であればわかると思いますが、途中でどこの入力欄を使用したらいいのかが分かりにくくなることもしばしば。
…というわけで、カスタムブロック利用時は、それを操作する際のことも考えて、あらかじめ上手く設計しておきたいですね(自戒)
あと、今回はMovableType.netでのみ確認をしていますが、この15万文字制限がMovableType.netの仕様なのか、ソフトウェア版やクラウド版でも同じなのか、その辺りも気になりますね。
以上、Movable Type カスタムブロック利用時の15万文字制限への対処アイディアでした!
明日からのMovable Type Advent Calendar 2023もお楽しみください。
サムネイル画像に使用しているのは、UnsplashのAnnie Sprattが撮影した写真です。