変換

Topics

  • 変換の方向: to と from
  • 変換タイプ
    • block
    • enter
    • files
    • prefix
    • raw
      • スキーマとコンテンツモデル
    • shortcode
  • ungroup ブロック

「ブロック変換 (Block Transforms)」API は、あるブロックを別のブロックに、あるいは、あるエンティティからブロックに変換します。この API のサポートする既存エンティティには、ショートコード、ファイル、正規表現、生の DOM ノードがあります。

変換の方向: to と from

ブロックはブロック構成の transforms オプションキーを使用して、どちらの方向の変換をサポートするかを宣言します。サブキー to と from には、すべての方向に対する利用可能な変換の配列を指定します。

export const settings = {
    title: 'My Block Title',
    description: 'My block description',
    /* ... */
    transforms: {
        from: [ /* サポートする from 変換 */ ],
        to: [ /* サポートする to 変換 */ ],
    }
}

Top ↑

変換タイプ

このセクションではブロックがサポートする既存の変換タイプを説明します。

  • block
  • enter
  • files
  • prefix
  • raw
  • shortcode

Top ↑

block

「block」変換タイプは from と to 双方向の変換をサポートし、あるブロックを異なるブロックに変換できます。ブロックツールバー内には関連する UI コントロールがあります。

block 変換タイプは次のパラメータを取るオブジェクトです。

  • type (string): 文字列 block
  • blocks (array): 既知のブロックタイプ。ワイルドカード値 ("*") も指定でき、この場合 すべての ブロックタイプで変換可能であることを意味する (例: すべてのブロックは core/group に変換できる)。
  • transform (function): 処理されるブロックの属性とインナーブロックを受け取るコールバック。ブロックオブジェクトまたはブロックオブジェクトの配列を返さなければならない。
  • isMatch (function、オプション): 第1引数にブロックの属性、第2引数にブロックオブジェクトを受け取り、ブール値を返すコールバック。false を返すと可能な変換を行わず、ユーザーにオプションを表示する。
  • isMultiBlock (boolean、オプション): 複数のブロックを選択している場合に変換を適用可能かどうか。true であれば transform 関数の最初のパラメータは選択した各ブロックの属性の配列、2番目のパラメータは選択した各ブロックのインナーブロックの配列になる。デフォルトは false。
  • priority (number、オプション): 変換を適用するプライオリティ。値の小さな方が優先される。この動きは WordPress のフック と同じ。フックと同様に指定されていない場合のデフォルトのプライオリティは 10

例: 「段落」ブロックから「見出し」ブロックへの変換

この変換を宣言するには「見出し」ブロック構成に以下のコードを追加します。wp-blocks パッケージ から createBlock 関数を使用します。

transforms: {
    from: [
        {
            type: 'block',
            blocks: [ 'core/paragraph' ],
            transform: ( { content } ) => {
                return createBlock( 'core/heading', {
                    content,
                } );
            },
        },
    ]
},

例: InnerBlock をもつブロックへの変換

InnerBlock をもつブロックも別の InnerBlock をもつブロックとの間で変換できます。

transforms: {
    to: [
        {
            type: 'block',
            blocks: [ 'some/block-with-innerblocks' ],
            transform: ( attributes, innerBlocks ) => {
                return createBlock(
                    'some/other-block-with-innerblocks',
                    attributes,
                    innerBlocks
                );
            },
        },
    ],
},

Top ↑

enter

「enter」変換タイプは from 方向の変換をサポートし、ユーザーが与えたコンテンツからブロックを作成します。ユーザーが何かコンテンツを入力し Enter キーを押下すると、新しいブロック行に適用されます。

enter 変換タイプは次のパラメータを取るオブジェクトです。

  • type (string): 文字列 enter
  • regExp (RegExp): パターンマッチに使用する正規表現。マッチすれば変換が適用される。
  • transform (function): 入力された値を含む content フィールドを持つオブジェクトを受け取るコールバック。ブロックオブジェクトまたはブロックオブジェクトの配列を返さなければならない。
  • priority (number, オプション): 変換を適用するプライオリティ。値の小さな方が優先される。この動きは WordPress のフック と同じ。フックと同様に指定されていない場合のデフォルトのプライオリティは 10

例: — から「区切り」ブロックへの変換

ユーザーが「-」を3回入力し Enter キーを押下した場合に「区切り」ブロックを作成します。

transforms = {
	from: [
		{
			type: 'enter',
			regExp: /^-{3,}$/,
			transform: () => createBlock( 'core/separator' ),
		},
	],
};

Top ↑

files

「files」変換タイプは from 方向の変換をサポートし、エディター内にドロップされたファイルからブロックを作成します。

files 変換タイプは次のパラメータを取るオブジェクトです。

  • type (string): 文字列 files
  • transform (function): 処理するファイルの配列を受け取るコールバック。ブロックオブジェクトまたはブロックオブジェクトの配列を返さなければならない。
  • isMatch (function、オプション): 処理するファイルの配列を受け取り、ブール値を返すコールバック。false を返すと変換を適用しない。
  • priority (number, オプション): 変換を適用するプライオリティ。値の小さな方が優先される。この動きは WordPress のフック と同じ。フックと同様に指定されていない場合のデフォルトのプライオリティは 10

例: ファイルから「ファイル」ブロックへの変換

ユーザーがエディターにファイルをドロップすると「ファイル」ブロックに変換します。

transforms: {
    from: [
        {
            type: 'files',
            isMatch: ( files ) => files.length === 1,
            // デフォルトの 10 よりも低いプライオリティを設定することで
            // 他の変換が見つからない場合のフォールバックとして
            // 「ファイル」ブロックを作成できます。
            priority: 15,
            transform: ( files ) => {
                const file = files[ 0 ];
                const blobURL = createBlobURL( file );
                // ファイルは componentDidMount() でアップロードされます。
                return createBlock( 'core/file', {
                    href: blobURL,
                    fileName: file.name,
                    textLinkHref: blobURL,
                } );
            },
        },
    ];
}

Top ↑

prefix

「prefix」変換タイプは from 方向をサポートし、ユーザーが入力したテキストからブロックを作成します。新しいブロック行でユーザーがテキストを入力し、続けて空白を入力するとこの変換が適用されます。

prefix 変換タイプは次のパラメータを取るオブジェクトです。

  • type (string): 文字列 prefix
  • prefix (string): この変換にマッチする文字、または文字列。
  • transform (function): 入力したコンテンツを受け取るコールバック。ブロックオブジェクトまたはブロックオブジェクトの配列を返さなければならない。
  • priority (number, オプション): 変換を適用するプライオリティ。値の小さな方が優先される。この動きは WordPress のフック と同じ。フックと同様に指定されていない場合のデフォルトのプライオリティは 10

例: テキストからカスタムブロックへの変換

ユーザーが疑問符「?」を入力するとカスタムブロックを作成します。

transforms: {
	from: [
		{
			type: 'prefix',
			prefix: '?',
			transform( content ) {
				return createBlock( 'my-plugin/question', {
					content,
				} );
			},
		},
	];
}

Top ↑

raw

「raw」変換タイプは from 方向をサポートし、生の HTML ノードからブロックを生成します。ユーザーがブロック設定 UI メニューで「ブロックへ変換」アクションを実行した場合、またはコンテンツをエディターに貼り付けたり、ドロップした場合にこの変換が適用されます。

タイプ raw の変換は、次のパラメータを取るオブジェクトです。

  • type (string): 文字列 raw
  • transform (function、オプション): 処理するノードを受け取るコールバック。ブロックオブジェクトまたはブロックオブジェクトの配列を返さなければならない。
  • schema (object|function、オプション): 張り付けられたコンテンツの検出と処理に使用される HTML content model を定義する。以下の「スキーマとコンテンツモデル」を参照してください。
  • selector (string、オプション)element.matches メソッドに従って要素が合致するかどうかを決定する CSS セレクター文字列。要素がマッチしない場合、変換は実行されない。isMatch の代替、かつ、短縮形。あれば、isMatch が優先。
  • isMatch (function、オプション): 処理するノードを受け取り、ブール値を返すコールバック。false を返すと変換を適用しない。
  • priority (number, オプション): 変換を適用するプライオリティ。値の小さな方が優先される。この動きは WordPress のフック と同じ。フックと同じく、値が指定されていない場合のデフォルトのプライオリティは 10

例: URL から「埋め込み」ブロックへの変換

ユーザーがエディターに URL を貼り付けると「埋め込み」ブロックを作成する。

transforms: {
    from: [
        {
            type: 'raw',
            isMatch: ( node ) =>
                node.nodeName === 'P' &&
                /^\s*(https?:\/\/\S+)\s*$/i.test( node.textContent ),
            transform: ( node ) => {
                return createBlock( 'core/embed', {
                    url: node.textContent.trim(),
                } );
            },
        },
    ],
}

Top ↑

スキーマとコンテンツモデル

コンテンツを貼り付ける際、コンテンツモデルを定義して、コンテンツの妥当性を検証し、処理できます。エディターに貼り付けられたHTMLには、変換すべき要素と、変換すべきでない要素が混在します。例えば、エディターに <span class="time">12:04 pm</span> を貼り付ける場合、12:04 pm はコピーしますが、<span> と、その class 属性は削除したいでしょう。なぜなら、コピー元のオリジナル文書には存在した、意味や構造を、コピー先には持ち込めないためです。

raw 変換を書く際に、schema を指定することで、これを制御できます。schema は、許容されるコンテンツを記述し、ブロックとのマッチングを試みる前に、貼り付けられたコンテンツのクリーンアップに適用できます。schema は、@wordpress/dom の cleanNodeList に渡されます。スキーマの完全な説明については、こちら を参照してください。

schema = { span: { children: { '#text': {} } } };

例: カスタムコンテンツモデル

例えば、次のようなHTMLスニペットにマッチして、ある種のカスタム投稿プレビューブロックに変換したいとします。

<div data-post-id="13">
	<h2>The Post Title</h2>
	<p>Some <em>great</em> content.</p>
</div>

エディターには、内側の h2 と p 要素を許可するように指示します。それには次のようなスキーマを提供できます。この例では、関数形式を使っていて、関数は、引数に phrasingContentSchema プロパティの値 (と同時に、変換操作がテキストの貼り付けから始まったかどうかを示すブール値 isPaste) を受け取ります。phrasingContentSchema は、HTML のフレージング要素 (例: <strong><sup><kbd>) とマッチするよう、あらかじめ定義されていています。<RichText /> コンポーネントを期待する場所ではどこでも、フレージングコンテンツ (記述コンテンツ。文章とその中に含まれるマークアップ) を許可する良い候補となります。そうでなければ、変換時にすべてのテキストの書式が失われます。

schema = ({ phrasingContentSchema }) => {
    div: {
        required: true,
        attributes: [ 'data-post-id' ],
        children: {
            h2: { children: phrasingContentSchema },
            p: { children: phrasingContentSchema }
        }
    }
}

このコンテンツとのマッチングに成功すると、data-post-id 以外のすべての HTML 属性が取り除かれます。指定された div の中に他の HTML の配置があると、この変換にはマッチしません。同様に、<h2> の代わりに <h3> があると、マッチングは失敗します。

スキーマは、フレージングコンテンツ以外を含む HTML スニペットとマッチングする場合 (例: <summary> を含む <details>) に、最も重要になります。カスタムスキーマを宣言しなければ、エディターはブロック変換を実行する前に、これらの他の構造をスキップします。

Top ↑

shortcode

「shortcode」変換タイプは from 方向をサポートし、ショートコードからブロックを作成します。raw 変換プロセスの一部として適用されます。

shortcode 変換タイプは次のパラメータを取るオブジェクトです。

  • type (string): 文字列 shortcode
  • tag (string|array): この変換が動作可能なショートコードタグ、またはショートコードエイリアスのリスト。
  • transform (function, オプション): 第1引数にショートコードの属性、第2引数に WPShortcodeMatch を受け取るコールバック。ブロックオブジェクト、またはブロックオブジェクトの配列を返さなければならない。このパラメータが定義されると、attributes パラメータに優先する。
  • attributes (object, オプション)block 構成オブジェクト で定義された属性の形に従い、ブロック属性がどこを source とするかを表したオブジェクト。特定の属性が shortcode キーを含む場合には関数であり、第1引数にショートコードの属性、第2引数に WPShortcodeMatch を受け取り、ブロックのコメントを source とする属性の値を返さなければならない。
  • isMatch (function、オプション)Shortcode API ごとにショートコード属性を受け取り、ブール値を返すコールバック。false を返すとショートコードのブロックへの変換を適用しない。
  • priority (number, オプション): 変換を適用するプライオリティ。値の小さな方が優先される。この動きは WordPress のフック と同じ。フックと同様に指定されていない場合のデフォルトのプライオリティは 10

例: ショートコードからブロックへの、transform を使用した変換

既存のショートコードを対応するブロックバージョンに、transform 方式を使用して変換する。

transforms: {
    from: [
        {
            type: 'shortcode',
            tag: 'video',
            transform( { named: { src } } ) {
                return createBlock( 'core/video', { src } );
            },
            // 適切な ID をもたない場合、
            // ショートコードからこのブロックへの変換は
            // 行われない。
            isMatch( { named: { id } } ) {
                return id === 'my-id';
            },
        },
    ],
},

例: ショートコードからブロックへの、attributes を使用した変換

既存のショートコードを対応するブロックバージョンに、attributes 方式を使用して変換する。

transforms: {
    from: [
        {
            type: 'shortcode',
            tag: 'caption',
            attributes: {
                url: {
                    type: 'string',
                    source: 'attribute',
                    attribute: 'src',
                    selector: 'img',
                },
                align: {
                    type: 'string',
                    // ショートコード関数は
                    // ブロックコメントを source とする形式で
                    // ショートコード属性を取り出す。
                    shortcode: ( { named: { align = 'alignnone' } } ) => {
                        return align.replace( 'align', '' );
                    },
                },
            },
            // 適切な ID をもたない場合、
            // ショートコードからこのブロックへの変換は
            // 行われない。
            isMatch( { named: { id } } ) {
                return id === 'my-id';
            },
        },
    ]
},

Top ↑

ungroup ブロック

ブロックは、ブロック構成のオプションの transforms キーで ungroup サブキーを使用して、処理中のブロックを置換するブロックを定義できます。通常これらの新しいブロックは既存のインナーブロックのサブセットですが、新しいブロックも含められます。

ブロックが ungroup 変換を持つ場合、デフォルトのグループ化ブロックである必要性なしに、グループを解除できます。この API でブロックのグループ解除に使用する UI は、デフォルトのブロックのグループ化で使用される UI と同じです。グループ解除ボタンを表示するには、1つのグループ化ブロックを選択し、その中にいくつかのインナーブロックを含む必要があります。

ungroup はコールバック関数で、処理中のブロックの属性とインナーブロックを受け取ります。ブロックオブジェクトの配列を返す必要があります。

例:

export const settings = {
	title: 'My grouping Block Title',
	description: 'My grouping block description',
	/* ... */
	transforms: {
		ungroup: ( attributes, innerBlocks ) =>
			innerBlocks.flatMap( ( innerBlock ) => innerBlock.innerBlocks ),
	},
};

原文

最終更新日: