非推奨にするブロック
ブロックの静的なマークアップや属性を更新する場合、開発者は現在のバージョンを使用している既存の投稿に注意する必要があります。適切にアップグレードするには以下のどちらかの戦略を選択する必要があります。
- 既存のブロックはそのままにして、異なる名前で新しいブロックを作成する。
- ブロックの「deprecated (非推奨)」バージョンを提供する。ユーザーはブロックエディターで投稿を開き、更新されたブロックを使用して編集する。
ブロックは複数の非推奨バージョンをもつことができます。パースしたブロックの現行の状態が不正 (invalid) の場合、または、true を返す isEligible
関数が定義されている場合、非推奨プロセス (deprecation) が実行されます。
重要な注意点ですが、仮に isEligible
が与えられた属性に対して true を返しても、非推奨プロセスの save
メソッドが正しい (valid) ブロックを作成しない場合には、migrate
メソッドを含む非推奨プロセスはスキップされます。すなわち、あるブロックに対して複数の非推奨プロセスがあって新しい移行を実行したい場合、たとえば InnerBlocks
にコンテンツを移動する場合、複数の非推奨プロセスに、ブロックのすべての先行するバージョンに適用される migrate
メソッドを含める必要があります。
非推奨プロセスは、たとえばデータベース移行のような、ソフトウエアデータの更新に見られる「更新の連鎖」としては動作しません。誰もが非推奨プロセスを、データに対して必要な変更を行うと、次の非推奨プロセスにブロックの新しい形が渡され、またそこで必要な変更が行われるものと考えます。しかし実際には各非推奨プロセスにはオリジナルの保存されたコンテンツが渡され、その save
メソッドが正しい (valid) コンテンツを作成するなら、ブロック属性のパースに非推奨プロセスが使用されます。また migrate
メソッドがあるなら、これも非推奨プロセスがパースした属性を使用して実行されます。現行のブロックは移行された属性と内部ブロックで更新され、次に save
関数を実行して、ブロックの新しい正しいコンテンツが生成されます。この時点で現行のブロックは正しい状態になります。
複数の非推奨プロセスをもつブロックの場合、適用するブロックのバージョンと共に各非推奨プロセスを定数に保存し、これらをブロックの deprecated
配列に追加すると簡単になります。配列内の非推奨プロセスは時系列の逆順 (新しいものが先) で格納します。ブロックエディターは最新の、恐らく最初の非推奨プロセスを適用し、不要で高価な処理を避けられます。
例:
ESNext
const v1 = {};
const v2 = {};
const v3 = {};
const deprecated = [ v3, v2, v1 ];
ES5
var v1 = {};
var v2 = {};
var v3 = {};
var 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) の場合にはこの関数は呼ばれません。
重要な点として attributes
、supports
、save
は自動で現行バージョンから継承されないことに注意してください。これはブロックのパースとシリアライゼーションに影響を与えるためです。移行中に処理されるためには非推奨オブジェクトで定義する必要があります。
例:
ESNext
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>;
},
}
]
} );
ES5
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 here
attributes: attributes,
save: function( props ) {
return el( 'div', {}, props.attributes.text );
},
deprecated: [
{
attributes: attributes,
save: function( props ) {
return el( 'p', {}, props.attributes.text );
},
}
]
} );
上の例ではブロックのマークアップを更新し a
の代わりに div
を使用しています。
属性の変更
場合によっては属性の集合を更新して、古い属性の名前を変更したり変更する必要があります。
例:
ESNext
const { registerBlockType } = wp.blocks;
registerBlockType( 'gutenberg/block-with-deprecated-version', {
// ... other block properties go here
attributes: {
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>;
},
}
]
} );
ES5
var el = wp.element.createElement,
registerBlockType = wp.blocks.registerBlockType;
registerBlockType( 'gutenberg/block-with-deprecated-version', {
// ... other block properties go here
attributes: {
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
属性に変更しています。
innerBlock の変更
ブロックの移行の際に、innerBlock を追加したり削除する場合もあります。 例: ブロックの title 属性を段落 innerBlock に変更する。
例:
ESNext
const { registerBlockType } = wp.blocks;
const { omit } = lodash;
registerBlockType( 'gutenberg/block-with-deprecated-version', {
// ... block properties go here
save( 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>;
},
}
]
} );
ES5
var el = wp.element.createElement,
registerBlockType = wp.blocks.registerBlockType,
omit = lodash.omit;
registerBlockType( 'gutenberg/block-with-deprecated-version', {
// ... block properties go here
deprecated: [
{
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 に更新しています。
ここまでブロックの非推奨プロセスの例を挙げましたが、実際の使用例については コアブロックライブラリー 内の非推奨を調べてください。コアブロックはリリース全体で更新されていて、簡単なものや複雑なものなど、さまざまな非推奨プロセスがあります。
最終更新日: