非推奨プロセス

ブロックの静的なマークアップや属性を更新する場合、開発者は現在のバージョンを使用している既存の投稿に注意する必要があります。適切にアップグレードするには以下のどちらかの戦略を選択する必要があります。

  • 既存のブロックはそのままにして、異なる名前で新しいブロックを作成する。
  • ブロックの「deprecated (非推奨)」バージョンを提供する。ユーザーはブロックエディターで投稿を開き、更新されたブロックを使用して編集する。

ブロックは複数の非推奨バージョンをもつことができます。パースしたブロックの現行の状態が不正 (invalid) の場合、または、true を返す isEligible 関数が定義されている場合、非推奨プロセス (deprecation) が実行されます。

非推奨プロセスは、たとえばデータベースの移行のような、ソフトウエアデータの更新に見られる「更新の連鎖」としては動作しません。誰もが非推奨プロセスを、データに対して必要な変更を行うと、次の非推奨プロセスにブロックの新しい形が渡され、またそこで必要な変更が行われるものと考えます。しかし実際には、

  1. 現在の save メソッドが正しい (valid) ブロックを生成しないなら、非推奨プロセス配列内の最初の非推奨プロセスに、オリジナルの保存されたコンテンツが渡される。
  2. その save メソッドが正しいコンテンツを生成するなら、この非推奨プロセスが、ブロックの属性のパースに使用される。もし migrate メソッドがあるなら、非推奨プロセスによってパースされた属性を用いて実行される。
  3. 最初の非推奨プロセスの save メソッドが正しいブロックを生成しないなら、正しいブロックを生成するまで、配列内の後続の非推奨プロセスを試行する。
  4. 属性と任意の innerBlock は、正しいブロックを作成した最初の非推奨プロセスから、現行の save メソッドに戻され、ブロックのための新しく正しいコンテンツを生成する。
  5. この時点で現行のブロックは正しい状態になり、非推奨プロセスワークフローは停止する。

注意点として、非推奨プロセスの save メソッドが正しいブロックを生成しない場合、与えられた属性に対して isEligible が true を返すとしても、その migrate メソッドを含め、完全にスキップされます。あるブロックに複数の非推奨プロセスのメソッドがあり、例えばコンテンツを InnerBlocks に移動するような、新しい移行を行いたい場合、必要な変更を以前のバージョンのブロックすべてに適用するために、複数の非推奨プロセスの migrate メソッドを更新する必要があります。

また、非推奨プロセスの save メソッドが他のファイルから追加の関数をインポートする場合、このファイルを変更すると、誤って非推奨プロセスの動きが変わるかもしれません。これを防ぐには、関数をインポートする代わりに、関数のスナップショットのコピーを非推奨プロセスのファイルに追加してください。

複数の非推奨プロセスを持つブロックの場合、各非推奨プロセスを適用するブロックのバージョンを示す定数に保存し、これらをブロックの deprecated 配列に追加すると分かりやすいでしょう。配列内の非推奨プロセスは時系列の逆順 (新しいものが先) で格納します。ブロックエディターはまず、最新の、恐らく適切な非推奨プロセスを最初に適用し、不要で高価な処理を避けられます。

例:

const v1 = {};
const v2 = {};
const v3 = {};
const deprecated = [ v3, v2, v1 ];

また fixtures の保持を推奨します。異なるバージョンのブロックコンテンツを含み、ブロックのすべての過去のバージョンに対して新しい非推奨プロセスと移行が動作することを簡単にテストできます。

非推奨プロセスは、ブロックタイプの deprecated プロパティに以下の形式の非推奨プロセスオブジェクトの配列として定義します。

  • attributes (Object): ブロックの非推奨形式の attributes 定義
  • supports (Object): ブロックの非推奨形式の supports 定義
  • save (Function): ブロックの非推奨形式の save の実装
  • migrate (Function、オプション): 古い属性と内部ブロックを指定すると、新しい属性、または、ブロックと互換性のある [ attributes, innerBlocks ] のタブル配列を返す関数。上で説明したように、非推奨プロセスの save 関数が正しいブロックを返さない場合、migrate は実行されません。したがって関連するすべての非推奨プロセスで移行が利用可能であることを確認する必要があります。
  • isEligible (Function、オプション): パースされたブロックの属性と内部ブロックを指定すると、ブロックが正しく (valid) ても、非推奨プロセスがブロック移行を処理できる場合に true を返す関数。この関数が特に有用なケースはブロックが非推奨となっても技術的には正しいにも関わらず、属性や内部ブロックの更新が必要な場合です。以前のすべての非推奨プロセスの save 関数が不正 (invalid) の場合にはこの関数は呼ばれません。

重要な点として attributessupportssave は自動で現行バージョンから継承されないことに注意してください。これはブロックのパースとシリアライゼーションに影響を与えるためです。移行中に処理されるためには非推奨オブジェクトで定義する必要があります。

Top ↑

例:

Top ↑

JSX

const { registerBlockType } = wp.blocks;
const attributes = {
	text: {
		type: 'string',
		default: 'some random value',
	},
};

registerBlockType( 'gutenberg/block-with-deprecated-version', {
	// ... other block properties go here

	attributes,

	save( props ) {
		return<div>{ props.attributes.text }</div>;
	},

	deprecated: [
		{
			attributes,

			save( props ) {
				return<p>{ props.attributes.text }</p>;
			},
		},
	],
} );

Top ↑

Plain

var el = wp.element.createElement,
	registerBlockType = wp.blocks.registerBlockType,
	attributes = {
		text: {
			type: 'string',
			default: 'some random value',
		},
	};

registerBlockType( 'gutenberg/block-with-deprecated-version', {
	// ... other block properties go hereattributes: attributes,

	save: function ( props ) {
		return el( 'div', {}, props.attributes.text );
	},

	deprecated: [
		{
			attributes: attributes,

			save: function ( props ) {
				return el( 'p', {}, props.attributes.text );
			},
		},
	],
} );

上の例ではブロックのマークアップを更新し p の代わりに div を使用しています。

Top ↑

属性の変更

場合によっては属性の集合を更新して、古い属性の名前を変更したり変更する必要があります。

Top ↑

例:

Top ↑

JSX

const { registerBlockType } = wp.blocks;

registerBlockType( 'gutenberg/block-with-deprecated-version', {
	// ... other block properties go hereattributes: {
		content: {
			type: 'string',
			default: 'some random value',
		},
	},

	save( props ) {
		return<div>{ props.attributes.content }</div>;
	},

	deprecated: [
		{
			attributes: {
				text: {
					type: 'string',
					default: 'some random value',
				},
			},

			migrate( { text } ) {
				return {
					content: text,
				};
			},

			save( props ) {
				return<p>{ props.attributes.text }</p>;
			},
		},
	],
} );

Top ↑

Plain

var el = wp.element.createElement,
	registerBlockType = wp.blocks.registerBlockType;

registerBlockType( 'gutenberg/block-with-deprecated-version', {
	// ... other block properties go hereattributes: {
		content: {
			type: 'string',
			default: 'some random value',
		},
	},

	save: function ( props ) {
		return el( 'div', {}, props.attributes.content );
	},

	deprecated: [
		{
			attributes: {
				text: {
					type: 'string',
					default: 'some random value',
				},
			},

			migrate: function ( attributes ) {
				return {
					content: attributes.text,
				};
			},

			save: function ( props ) {
				return el( 'p', {}, props.attributes.text );
			},
		},
	],
} );

上の例ではブロックのマークアップを p から div に変更し、text 属性を content 属性に変更しています。

Top ↑

innerBlock の変更

ブロックの移行の際に、innerBlock を追加したり削除する場合もあります。 例: ブロックの title 属性を段落 innerBlock に変更する。

Top ↑

例:

Top ↑

JSX

const { registerBlockType } = wp.blocks;
const { omit } = lodash;

registerBlockType( 'gutenberg/block-with-deprecated-version', {
	// ... block properties go heresave( props ) {
		return<p>{ props.attributes.title }</p>;
	},

	deprecated: [
		{
			attributes: {
				title: {
					type: 'string',
					source: 'html',
					selector: 'p',
				},
			},

			migrate( attributes, innerBlocks ) {
				return [
					omit( attributes, 'title' ),
					[
						createBlock( 'core/paragraph', {
							content: attributes.title,
							fontSize: 'large',
						} ),
						...innerBlocks,
					],
				];
			},

			save( props ) {
				return<p>{ props.attributes.title }</p>;
			},
		},
	],
} );

Top ↑

Plain

var el = wp.element.createElement,
	registerBlockType = wp.blocks.registerBlockType,
	omit = lodash.omit;

registerBlockType( 'gutenberg/block-with-deprecated-version', {
	// ... block properties go heredeprecated: [
		{
			attributes: {
				title: {
					type: 'string',
					source: 'html',
					selector: 'p',
				},
			},

			migrate: function ( attributes, innerBlocks ) {
				return [
					omit( attributes, 'title' ),
					[
						createBlock( 'core/paragraph', {
							content: attributes.title,
							fontSize: 'large',
						} ),
					].concat( innerBlocks ),
				];
			},

			save: function ( props ) {
				return el( 'p', {}, props.attributes.title );
			},
		},
	],
} );

上の例でブロックは title 属性の代わりにタイトルをもつ段落 innerBlock に更新しています。

ここまでブロックの非推奨プロセスの例を挙げましたが、実際の使用例については コアブロックライブラリー 内の非推奨を調べてください。コアブロックはリリース全体で更新されていて、簡単なものや複雑なものなど、さまざまな非推奨プロセスがあります。

原文

最終更新日: