Movable Type CMSプラットフォーム Movable Type
ドキュメントサイト

Blogブログ

MTブロックエディタで編集した内容を構造化されたデータとして取得する方法

MTブロックエディタで編集した内容は、テンプレートによる書き出しでもData APIでも基本的にはHTML形式での出力になるのですが、「JavaScriptとの連携のために構造化されたデータとして取得したい」というケースもあると思います。

この記事では、MTブロックエディタで編集した内容を構造化されたデータとして取得する方法として、以下の2つを紹介します。

  • MTBlockEditorBlocksタグを利用して、テンプレートから出力する方法
  • プラグインを利用して、データを変換してテンプレートやData APIで出力する方法

前者の方法は、MTブロックエディタの基本機能のみで実現できます。後者の方法はプラグインを利用する形になりますが、データの変換にはMTブロックエディタに含まれているライブラリを利用できるため、開発が必要になったとしても小さなコストで実現が可能です。この記事ではプラグインの実装例も含めて紹介します。

MTBlockEditorBlocksタグを利用して出力する

シンプルな構成の編集内容を対象にする場合には、MTBlockEditorBlocksタグを利用して以下のようなテンプレートでJSON形式のデータとして書き出すことができます。

<mt:Ignore>
以下はコンテンツデータのフィールドでブロックエディタを使った場合の例です。
記事やウェブページで使う場合には、 tagの指定をEntryBodyやEntryMoreに変更します。
</mt:Ignore>

<mt:SetVar name="blocks" function="undef">
<mt:BlockEditorBlocks tag="ContentFieldValue">
  <mt:SetVar name="b" function="undef" />
  <mt:SetHashVar name="b">
    <mt:Var name="type" setvar="type" />
    <mt:If name="meta">
      <mt:Var name="meta" setvar="meta" />
    </mt:If>
    <mt:Var name="__value__" setvar="content" /> 
  </mt:SetHashVar>
  <mt:SetVar name="blocks" function="push" value="$b" />
</mt:BlockEditorBlocks>
<mt:Var name="blocks" to_json="1" replace=">","\u003E" replace="<","\u003C" />

このテンプレートで、以下のような内容を書き出すことができます。(実際には改行や空白は出力されませんが、ここでは見やすいように整形しています)

[
   {
      "content" : "\u003cp\u003etest\u003c\u002fp\u003e",
      "type" : "core-text"
   },
   {
      "content" : "\u003cblockquote class=\"twitter-tweet\" data-width=\"550\"\u003e\u003cp lang=\"ja\" dir=\"ltr\"\u003e【オンラインミニセミナー本日開催👩‍💻】\u003cbr\u003eセキュリティやコンプライアンス管理の徹底を求められる企業サイト。でも高価なハイエンドCMSはコストが合わない...そんなケースにおすすめの「Movable Type SmartSync Pack」を徹底解説。短時間ですのでお気軽にご参加ください💁‍♀️\u003ca href=\"https:\u002f\u002ft.co\u002fYuBldvJmOY\"\u003ehttps:\u002f\u002ft.co\u002fYuBldvJmOY\u003c\u002fa\u003e\u003c\u002fp\u003e&mdash; シックス・アパート株式会社 (@sixapartkk) \u003ca href=\"https:\u002f\u002ftwitter.com\u002fsixapartkk\u002fstatus\u002f1349521164503171076?ref_src=twsrc%5Etfw\"\u003eJanuary 14, 2021\u003c\u002fa\u003e\u003c\u002fblockquote\u003e\u003cscript async src=\"https:\u002f\u002fplatform.twitter.com\u002fwidgets.js\" charset=\"utf-8\"\u003e\u003c\u002fscript\u003e",
      "type" : "sixapart-oembed",
      "meta" : {
         "providerName" : "Twitter",
         "maxwidth" : "640",
         "url" : "https:\u002f\u002ftwitter.com\u002fsixapartkk\u002fstatus\u002f1349521164503171076",
         "width" : 550
      }
   }
]

プラグインを利用して出力する

カスタムブロックを利用したサイトでもっと深い階層まで含めた構造を取得したいケースでは、プラグインを利用する方法がおすすめです。プラグインの場合にはPerlでプログラミングをする必要がありますが、MTブロックエディタのプラグインにはMT::BlockEditor::Parserというデータの変換に利用できるライブラリが含まれているので、これを使うとそれほど多くないコードで変換の処理を書くことができます。

MT::BlockEditor::Parserを使ったプラグインのサンプルがmt-plugin-MTBlockEditorCustomFormatにあるので、これ以降はこのプラグインを題材にして説明をしていきます。

MT::BlockEditor::Parserで変換されたデータを確認する

MTBlockEditorCustomFormatプラグインを使うと以下のようなテンプレートで、変換された生のデータを確認できます。

<mt:Ignore>
ブロックエディタの内容を出力するタグに、 「convert_breaks="0" mtbe_custom_json="raw","pretty"」を付けます。
</mt:Ignore>

<mt:ContentField content_field="a_block_editor_field">
<mt:ContentFieldValue convert_breaks="0" mtbe_custom_json="raw","pretty" />
</mt:ContentField>

結果は以下のようになります。このままでも利用可能なデータではありますが、空の項目がたくさんあったり、子ブロックがある場合に親子の両方でデータを持っていたりして、やや冗長な内容にはなっています。

[
   {
      "blocks" : [],
      "meta" : {},
      "type" : "core-text",
      "content" : [
         "\u003cp\u003etest\u003c\u002fp\u003e"
      ]
   },
   {
      "blocks" : [],
      "meta" : {
         "providerName" : "Twitter",
         "url" : "https:\u002f\u002ftwitter.com\u002fsixapartkk\u002fstatus\u002f1349521164503171076",
         "width" : 550,
         "maxwidth" : "640"
      },
      "content" : [
         "\u003cblockquote class=\"twitter-tweet\" data-width=\"550\"\u003e\u003cp lang=\"ja\" dir=\"ltr\"\u003e【オンラインミニセミナー本日開催👩‍💻】\u003cbr\u003eセキュリティやコンプライアンス管理の徹底を求められる企業サイト。でも高価なハイエンドCMSはコストが合わない...そんなケースにおすすめの「Movable Type SmartSync Pack」を徹底解説。短時間ですのでお気軽にご参加ください💁‍♀️\u003ca href=\"https:\u002f\u002ft.co\u002fYuBldvJmOY\"\u003ehttps:\u002f\u002ft.co\u002fYuBldvJmOY\u003c\u002fa\u003e\u003c\u002fp\u003e&mdash; シックス・アパート株式会社 (@sixapartkk) \u003ca href=\"https:\u002f\u002ftwitter.com\u002fsixapartkk\u002fstatus\u002f1349521164503171076?ref_src=twsrc%5Etfw\"\u003eJanuary 14, 2021\u003c\u002fa\u003e\u003c\u002fblockquote\u003e\r\n\u003cscript async src=\"https:\u002f\u002fplatform.twitter.com\u002fwidgets.js\" charset=\"utf-8\"\u003e\u003c\u002fscript\u003e\r\n"
      ],
      "type" : "sixapart-oembed"
   },
   {
      "type" : "core-columns",
      "content" : [
         "\u003cdiv class=\"mt-be-columns\" style=\"display: flex\"\u003e",
         "\u003cdiv class='mt-be-column'\u003e",
         "\u003cp\u003e左カラム\u003c\u002fp\u003e",
         "\u003c\u002fdiv\u003e",
         "\u003cdiv class='mt-be-column'\u003e",
         "\u003cp\u003e右カラム\u003c\u002fp\u003e",
         "\u003c\u002fdiv\u003e",
         "\u003c\u002fdiv\u003e"
      ],
      "meta" : {},
      "blocks" : [
         {
            "meta" : {},
            "blocks" : [
               {
                  "content" : [
                     "\u003cp\u003e左カラム\u003c\u002fp\u003e"
                  ],
                  "type" : "core-text",
                  "meta" : {},
                  "blocks" : []
               }
            ],
            "type" : "core-column",
            "content" : [
               "\u003cdiv class='mt-be-column'\u003e",
               "\u003cp\u003e左カラム\u003c\u002fp\u003e",
               "\u003c\u002fdiv\u003e"
            ]
         },
         {
            "meta" : {},
            "blocks" : [
               {
                  "blocks" : [],
                  "meta" : {},
                  "type" : "core-text",
                  "content" : [
                     "\u003cp\u003e右カラム\u003c\u002fp\u003e"
                  ]
               }
            ],
            "type" : "core-column",
            "content" : [
               "\u003cdiv class='mt-be-column'\u003e",
               "\u003cp\u003e右カラム\u003c\u002fp\u003e",
               "\u003c\u002fdiv\u003e"
            ]
         }
      ]
   }
]

MTBlockEditorCustomFormatプラグインでは、生のデータを取得するだけでなく、使いやすく加工したデータを取得することもできるようになっています。

mtbe_custom_jsonに対して、rawの代わりにsimple_with_metaを指定すると、不要な項目や重複を省いて以下のような出力を得ることができます。

<mt:ContentField content_field="a_block_editor_field">
<mt:ContentFieldValue convert_breaks="0" mtbe_custom_json="simple_with_meta","pretty" />
</mt:ContentField>
[
   {
      "content" : "\u003cp\u003etest\u003c\u002fp\u003e",
      "type" : "core-text"
   },
   {
      "meta" : {
         "maxwidth" : "640",
         "width" : 550,
         "url" : "https:\u002f\u002ftwitter.com\u002fsixapartkk\u002fstatus\u002f1349521164503171076",
         "providerName" : "Twitter"
      },
      "content" : "\u003cblockquote class=\"twitter-tweet\" data-width=\"550\"\u003e\u003cp lang=\"ja\" dir=\"ltr\"\u003e【オンラインミニセミナー本日開催👩‍💻】\u003cbr\u003eセキュリティやコンプライアンス管理の徹底を求められる企業サイト。でも高価なハイエンドCMSはコストが合わない...そんなケースにおすすめの「Movable Type SmartSync Pack」を徹底解説。短時間ですのでお気軽にご参加ください💁‍♀️\u003ca href=\"https:\u002f\u002ft.co\u002fYuBldvJmOY\"\u003ehttps:\u002f\u002ft.co\u002fYuBldvJmOY\u003c\u002fa\u003e\u003c\u002fp\u003e&mdash; シックス・アパート株式会社 (@sixapartkk) \u003ca href=\"https:\u002f\u002ftwitter.com\u002fsixapartkk\u002fstatus\u002f1349521164503171076?ref_src=twsrc%5Etfw\"\u003eJanuary 14, 2021\u003c\u002fa\u003e\u003c\u002fblockquote\u003e\r\n\u003cscript async src=\"https:\u002f\u002fplatform.twitter.com\u002fwidgets.js\" charset=\"utf-8\"\u003e\u003c\u002fscript\u003e\r\n",
      "type" : "sixapart-oembed"
   },
   {
      "type" : "core-columns",
      "blocks" : [
         {
            "type" : "core-column",
            "blocks" : [
               {
                  "content" : "\u003cp\u003e左カラム\u003c\u002fp\u003e",
                  "type" : "core-text"
               }
            ]
         },
         {
            "blocks" : [
               {
                  "type" : "core-text",
                  "content" : "\u003cp\u003e右カラム\u003c\u002fp\u003e"
               }
            ],
            "type" : "core-column"
         }
      ]
   }
]

rawやsimple_with_meta以外の指定についてはドキュメントで確認できます。

Data APIでも構造化されたデータで取得する

MTBlockEditorCustomFormatプラグインはData APIでの取得にも対応しています。フィールドの定義に、コンテンツデータであればdata_mtbe_customが、記事やウェブページであればbody_mtbe_customやmore_mtbe_customが追加されているので、fieldsパラメータに指定して取得することができます。

例えば、以下のようなリクエストを投げると、

$ curl "https://example.com/cgi-bin/mt/mt-data-api.cgi/v4/sites/1/contentTypes/1/data/1?fields=data_mtbe_custom&mtbe_custom=simple_with_meta"

以下のようなレスポンスを得ることができます。

{
  "data_mtbe_custom": [
    {
      "data": [
        {
          "content": "<p>test</p>",
          "type": "core-text"
        },
        {
          "content": "<blockquote class=\"twitter-tweet\" data-width=\"550\"><p lang=\"ja\" dir=\"ltr\">【オンラインミニセミナー本日開催👩‍💻】<br>セキュリティやコンプライアンス管理の徹底を求められる企業サイト。でも高価なハイエンドCMSはコストが合わない...そんなケースにおすすめの「Movable Type SmartSync Pack」を徹底解説。短時間ですのでお気軽にご参加ください💁‍♀️<a href=\"https://t.co/YuBldvJmOY\">https://t.co/YuBldvJmOY</a></p>&mdash; シックス・アパート株式会社 (@sixapartkk) <a href=\"https://twitter.com/sixapartkk/status/1349521164503171076?ref_src=twsrc%5Etfw\">January 14, 2021</a></blockquote>\r\n<script async src=\"https://platform.twitter.com/widgets.js\" charset=\"utf-8\"></script>\r\n",
          "type": "sixapart-oembed"
        },
        {
          "blocks": [
            {
              "blocks": [
                {
                  "content": "<p>左カラム</p>",
                  "type": "core-text"
                }
              ],
              "type": "core-column"
            },
            {
              "blocks": [
                {
                  "content": "<p>右カラム</p>",
                  "type": "core-text"
                }
              ],
              "type": "core-column"
            }
          ],
          "type": "core-columns"
        }
      ],
      "id": "7",
      "label": "be",
      "type": "multi_line_text"
    },
  ]
}

mtbe_customに指定可能な値については、MTMLの場合と同じくドキュメントで確認できます。

プラグインで拡張すると以上のように、編集内容を加工して出力することができます。MTBlockEditorCustomFormatプラグインも実質200行程度のプログラムなので、Perlでの開発が可能なプロジェクトであれば、同種のプラグインを要件にあわせて開発することも難しくないと思います。

方法の紹介は以上になります。

構造化されたデータでの出力はブロックエディタらしさを活かせるユースケースですので、要件にあわせてこのような使い方もご検討いただければと思います!

  • このエントリーをはてなブックマークに追加