非推奨プロセス

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

  • 既存のブロックはそのままにして、異なる名前で新しいブロックを作成する。
  • ブロックの「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 ];

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

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

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

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

例:

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 に更新しています。

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

原文

最終更新日: