Svelte 環境で変わったコンテンツフィールドの追加方法について - movabletype/Documentation GitHub Wiki

※ (2026/02/04 追記) Movable Type 9.1.0 より、Svelte環境においてもビルド不要でコンテンツフィールドを追加できるようになりました。詳細は こちらのページ をご確認ください。

はじめに

Movable Type 8.4.0 より、管理画面の JavaScript ライブラリを Riot.js から Svelte に切り替えることが可能になりました。この変更は、環境変数 UseRiot0 を設定することで適用できます(Movable Type 9.0 からは UseRiot 0 が初期値になり、デフォルトで Svelte が有効になります)。この切り替えに伴い、プラグインによるコンテンツフィールドの追加方法にもいくつかの変更が加わりました。

この記事では、Svelte 環境 (UseRiot 0 設定時) における新しいコンテンツフィールドの追加方法について、サンプルプラグインを通して解説します。

紹介するサンプルプラグインの概要

本記事で紹介するのは、ContentFieldTypeEmailSvelte というプラグインです。<input type="email"> を使い、メールアドレスの入力チェックを行うコンテンツフィールドを追加するプラグインになっています。テキストフィールドをベースにしており、文字数や初期値の設定も可能です。

https://github.com/movabletype/mt-sample-plugins-for-svelte/tree/main/mt-plugin-content-field-type-email-svelte

インストール方法についてはリポジトリにある README.md をご覧ください。

サンプルプラグインの各ファイルの説明

サンプルプラグインの各ファイルについて、 Svelte 環境への対応に必要な変更点を順に説明します。

plugins/ContentFieldTypeEmailSvelte/config.yaml

プラグインを登録する config.yaml です。

name: ContentFieldTypeEmailSvlete
id: ContentFieldTypeEmailSvlete
key: ContentFieldTypeEmailSvelte
version: 0.001000
description: <__trans phrase="This is a sample plugin to add a content field (Svelte version).">
plugin_link: https://github.com/movabletype/mt-sample-plugins-for-svelte
author: Six Apart Ltd.
author_link: https://www.movabletype.org/
l10n_lexicon:
  ja:
    'This is a sample plugin to add a content field (Svelte version).': コンテンツフィールドを追加するサンプルプラグイン(Svelte版)です。
content_field_types:
  emails:
    label: Email (Svelte version)
    data_type: varchar
    order: 55
    icon_class: ic_mail
    can_data_label_field: 1
    field_html: field_html.tmpl
    field_html_params: $Core::MT::ContentFieldType::SingleLineText::field_html_params
    replaceable: 1
    ss_validator: $Core::MT::ContentFieldType::SingleLineText::ss_validator
    list_props:
      emails:
        base: __virtual.string
        col: value_varchar
        terms: $Core::MT::ContentFieldType::Common::terms_text
        use_blank: 1
    options_validation_handler: $Core::MT::ContentFieldType::SingleLineText::options_validation_handler
    options_html: options_html.tmpl
    options_script: options_script.tmpl
    options:
      - label
      - description
      - required
      - display
      - min_length
      - max_length
      - initial_value

Svelte 環境では、コンテンツタイプ編集画面でコンテンツフィールドの設定内容を表示するためのテンプレートを指定する options_html が使えなくなりました。代わりに options_script にテンプレートを指定して、その中でプラグイン登録を行う処理を記載する必要があります。(ここでは Riot.js 環境でも動作させる目的で、options_html 設定も追加しています)

上記以外の設定に関しては Riot.js 環境から変更ありません。Riot.js環境とSvelte環境で共通の設定については、こちらのブログ記事で詳しく解説しています。

plugins/ContentFieldTypeEmailSvelte/tmpl/options_script.tmpl

こちらは新しく追加された options_script で指定するテンプレートです。

<script type="module">
  import { Email, mountEmailSvelte } from "<mt:var name="static_uri">plugins/ContentFieldTypeEmailSvelte/dist/email.js?v=<mt:var name="mt_version_id" escape="url">";
  ContentTypeEditor.registerCustomType("emails", mountEmailSvelte);
</script>

options_script では options_html とは異なり、テンプレートの出力が <script type="riot/tag"> で括られなくなり、Riot.js のテンプレート記述ができなくなりました。またそれに伴い、Riot.js のテンプレートを出力していた下記のタグも使えなくなっています。

  • MTApp:ContentFieldOption
  • MTApp:ContentFieldOptionGroup
  • MTApp:ContentFieldOptionScript

Svelte 環境におけるプラグインの追加は、この options_script のテンプレートにおいて JavaScript で ContentTypeEditor.registerCustomType を使って行います。

  • "emails" は追加するコンテンツフィールドのキー名です。
  • mountEmailSvelte はコンテンツタイプ編集画面で追加したコンテンツフィールド編集画面を操作する関数です。 内容としては src/emai.ts にあり、それをビルドしたものを mt-static/plugins/ContentFieldTypeEmailSvelte/dist/email.js に出力して読み込んでいます。

src/email.ts

options_script で指定したテンプレート中で、コンテンツフィールド登録に使われる mountEmailSvelte を定義したファイルです。

import Email from "./elements/Email.svelte";
import { EmailOptions } from "./elements/type";
import type { CustomContentFieldMountFunction } from "@sixapart/mt-toolkit/contenttype";
const mountEmailSvelte: CustomContentFieldMountFunction<EmailOptions> = function (
  props,
  target
) {
  const emailSvelte = new Email({
    props: props,
    target: target,
  });
  return {
    component: emailSvelte,
    destroy: () => {
      emailSvelte.$destroy();
    },
  };
};
export { Email, mountEmailSvelte };

mountEmailSveltepropstarget を引数として受け取ります。これらの引数を使って Svelte コンポーネントをマウントしたのちに、戻り値として component, destroy, gather をプロパティに持つオブジェクトを返します。プロパティの説明は以下の通りです。

component

Svelte コンポーネントを指定します。

destroy

コンテンツタイプ編集画面で、コンテンツフィールドが削除された時のアンマウント処理を記載します。

gather

サンプルプラグインでは使用しておりませんが、コンテンツフィールドの送信データ取得処理を記載することができます。HTMLフォームでそのまま送信できない形式でデータを保持している場合にこれを使います。

コンテンツタイプ編集画面の保存時に呼び出されます。

このパラメータはオプションです。

src/elements/Email.svelte

コンテンツタイプ編集画面でコンテンツフィールドの設定内容を表示する Svelte コンポーネントです。

<script lang="ts">
  import { Writable } from "svelte/store";
  import {
    ContentFieldOption,
    ContentFieldOptionGroup,
  } from "@sixapart/mt-toolkit/contenttype";
  import type {
    ConfigSettings,
    Field,
    OptionsHtmlParams,
  } from "@sixapart/mt-toolkit/contenttype";
  import type { EmailOptions } from "./type";
  // svelte-ignore unused-export-let
  export let config: ConfigSettings;
  export let fieldIndex: number;
  export let fieldsStore: Writable<Array<Field<EmailOptions>>>;
  // svelte-ignore unused-export-let
  export let optionsHtmlParams: OptionsHtmlParams;
  const id = `field-options-${$fieldsStore[fieldIndex].id}`;
  $fieldsStore[fieldIndex].options.min_length ??= 0;
  $fieldsStore[fieldIndex].options.max_length ??= 255;
  $fieldsStore[fieldIndex].options.initial_value ??= "";
</script>
<ContentFieldOptionGroup
  type="emails"
  bind:field={$fieldsStore[fieldIndex]}
  {id}
  bind:options={$fieldsStore[fieldIndex].options}
>
  <ContentFieldOption id="emails-min_length" label={window.trans("Min Length")}>
    <input
      {...{ ref: "min_length" }}
      type="number"
      name="min_length"
      id="emails-min_length"
      class="form-control w-25"
      min="0"
      bind:value={$fieldsStore[fieldIndex].options.min_length}
    />
  </ContentFieldOption>
  <ContentFieldOption id="emails-max_length" label={window.trans("Max Length")}>
    <input
      {...{ ref: "max_length" }}
      type="number"
      name="max_length"
      id="emails-max_length"
      class="form-control w-25"
      min="1"
      bind:value={$fieldsStore[fieldIndex].options.max_length}
    />
  </ContentFieldOption>
  <ContentFieldOption
    id="emails-initial_value"
    label={window.trans("Initial Value")}
  >
    <input
      {...{ ref: "initial_value" }}
      type="text"
      name="initial_value"
      id="emails-initial_value"
      class="form-control"
      bind:value={$fieldsStore[fieldIndex].options.initial_value}
    />
  </ContentFieldOption>
</ContentFieldOptionGroup>

Svlete を使うことにより、Movable Type 本体で使っている Svelte コンポーネントを使うことができます。

  • ContentFieldOption
    • Riot.js 環境の MTApp:ContentFieldOption タグと同等の Svelte コンポーネント
  • ContentFieldOptionGroup
    • Riot.js 環境の MTApp:ContentFieldOptionGroup タグと同等の Svelte コンポーネント

※ Svelte コンポーネント内で JavaScript を記載することができるので、MTApp::ContentFieldOptionScript タグと同等の Svelte コンポーネントは用意しておりません。

Svelte コンポーネントには下記のパラメータが渡ってきます。

  • config
    • 環境変数のオブジェクトです。初期状態では下記の環境変数値が設定されています。
      • NumberFieldMaxValue
      • NumberFieldMinValue
      • NumberFieldDecimalPlaces
    • 初期値以外を使う場合、options_script で指定したテンプレートで下記のように ContentTypeEditor.config に設定する必要があります。
<script type="module">
  import { Email, mountEmailSvelte } from "<mt:var name="static_uri">plugins/ContentFieldTypeEmailSvelte/dist/email.js?v=<mt:var name="mt_version_id" escape="url">";
  ContentTypeEditor.registerCustomType("emails", mountEmailSvelte);
  ContentTypeEditor.config.DebugMode = "<mt:var name="config.debugmode" escape="js">";
</script>
  • fieldIndex
    • 次に説明する fieldsStore 配列における、このコンテンツフィールドのインデックスです。
  • fieldsStore
    • コンテンツタイプ編集画面で、設定データを保持している配列オブジェクトです。設定データはこの fieldsStore と fieldIndex を使って取得や変更をします。
  • optionsHtmlParams
    • option_html_params で設定された値で、Riot.js 環境では options_html で使っていました。Svelte 環境では options_script で使います。Svelte 環境対応の変更は不要です。

mt-static/plugins/ContentFieldTypeEmailSvelte/dist/email.js

src/email.ts をビルドした出力ファイルです。

tmpl/options_script.tmpl で使用します。ビルドされたファイルですので、内容の説明は省略します。

package.json, package-lock.json, rollup.config.ts, tsconfig.json

src/email.ts をビルドするために必要な設定ファイルなどです。

内容の説明は省略します。これらのファイルはプラグイン開発のために自由にお使いください。

plugins/ContentFieldTypeEmailSvelte/tmpl/options_html.tmpl

Riot.js 環境のコンテンツタイプ編集画面でコンテンツフィールドの設定内容を表示するためのテンプレートファイルです。

Svelte 環境用のファイルではないのでここでの説明は省略します。基本的には src/elements/Email.svelte と同様の内容が記載されています。詳しくは こちらのブログ記事をご覧ください。

plugins/ContentFieldTypeEmailSvelte/tmpl/field_html.tmpl

コンテンツデータ編集画面でコンテンツフィールドの設定内容を表示するためのテンプレートファイルです。

Riot.js 環境と Svelte 環境で同じ設定が使えますので、説明は省略します。詳しくは こちらのブログ記事をご覧ください。

まとめ

Movable Type 8.4.0 から追加された Svelte 環境にて、プラグインでコンテンツフィールドを追加する方法について、Riot.js 環境から変更になった部分の説明をしました。

設定の違いとしては options_htmloptions_script のみではありますが、Riot.js 環境用に作成したプラグインはそのままでは Svelte 環境では動作せず、修正対応が必要になります。ユーザーの皆様にはご迷惑をおかけすることになり、大変申し訳ございません。

今回紹介しましたサンプルプラグインのコード解説を、ご自身のプラグイン開発に役立てていただければ幸いです。ご不明な点がありましたら、いつでもご質問ください。

⚠️ **GitHub.com Fallback** ⚠️