Svelte 環境で変わったコンテンツフィールドの追加方法について - movabletype/Documentation GitHub Wiki
※ (2026/02/04 追記) Movable Type 9.1.0 より、Svelte環境においてもビルド不要でコンテンツフィールドを追加できるようになりました。詳細は こちらのページ をご確認ください。
Movable Type 8.4.0 より、管理画面の JavaScript ライブラリを Riot.js から Svelte に切り替えることが可能になりました。この変更は、環境変数 UseRiot に 0 を設定することで適用できます(Movable Type 9.0 からは UseRiot 0 が初期値になり、デフォルトで Svelte が有効になります)。この切り替えに伴い、プラグインによるコンテンツフィールドの追加方法にもいくつかの変更が加わりました。
この記事では、Svelte 環境 (UseRiot 0 設定時) における新しいコンテンツフィールドの追加方法について、サンプルプラグインを通して解説します。
本記事で紹介するのは、ContentFieldTypeEmailSvelte というプラグインです。<input type="email"> を使い、メールアドレスの入力チェックを行うコンテンツフィールドを追加するプラグインになっています。テキストフィールドをベースにしており、文字数や初期値の設定も可能です。
インストール方法についてはリポジトリにある README.md をご覧ください。
サンプルプラグインの各ファイルについて、 Svelte 環境への対応に必要な変更点を順に説明します。
プラグインを登録する 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_valueSvelte 環境では、コンテンツタイプ編集画面でコンテンツフィールドの設定内容を表示するためのテンプレートを指定する options_html が使えなくなりました。代わりに options_script にテンプレートを指定して、その中でプラグイン登録を行う処理を記載する必要があります。(ここでは Riot.js 環境でも動作させる目的で、options_html 設定も追加しています)
上記以外の設定に関しては Riot.js 環境から変更ありません。Riot.js環境とSvelte環境で共通の設定については、こちらのブログ記事で詳しく解説しています。
こちらは新しく追加された 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 に出力して読み込んでいます。
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 };mountEmailSvelte は props と target を引数として受け取ります。これらの引数を使って Svelte コンポーネントをマウントしたのちに、戻り値として component, destroy, gather をプロパティに持つオブジェクトを返します。プロパティの説明は以下の通りです。
Svelte コンポーネントを指定します。
コンテンツタイプ編集画面で、コンテンツフィールドが削除された時のアンマウント処理を記載します。
サンプルプラグインでは使用しておりませんが、コンテンツフィールドの送信データ取得処理を記載することができます。HTMLフォームでそのまま送信できない形式でデータを保持している場合にこれを使います。
コンテンツタイプ編集画面の保存時に呼び出されます。
このパラメータはオプションです。
コンテンツタイプ編集画面でコンテンツフィールドの設定内容を表示する 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 環境対応の変更は不要です。
-
src/email.ts をビルドした出力ファイルです。
tmpl/options_script.tmpl で使用します。ビルドされたファイルですので、内容の説明は省略します。
src/email.ts をビルドするために必要な設定ファイルなどです。
内容の説明は省略します。これらのファイルはプラグイン開発のために自由にお使いください。
Riot.js 環境のコンテンツタイプ編集画面でコンテンツフィールドの設定内容を表示するためのテンプレートファイルです。
Svelte 環境用のファイルではないのでここでの説明は省略します。基本的には src/elements/Email.svelte と同様の内容が記載されています。詳しくは こちらのブログ記事をご覧ください。
コンテンツデータ編集画面でコンテンツフィールドの設定内容を表示するためのテンプレートファイルです。
Riot.js 環境と Svelte 環境で同じ設定が使えますので、説明は省略します。詳しくは こちらのブログ記事をご覧ください。
Movable Type 8.4.0 から追加された Svelte 環境にて、プラグインでコンテンツフィールドを追加する方法について、Riot.js 環境から変更になった部分の説明をしました。
設定の違いとしては options_html と options_script のみではありますが、Riot.js 環境用に作成したプラグインはそのままでは Svelte 環境では動作せず、修正対応が必要になります。ユーザーの皆様にはご迷惑をおかけすることになり、大変申し訳ございません。
今回紹介しましたサンプルプラグインのコード解説を、ご自身のプラグイン開発に役立てていただければ幸いです。ご不明な点がありましたら、いつでもご質問ください。