Skip to content

Commit

Permalink
Add a migration to the new format
Browse files Browse the repository at this point in the history
  • Loading branch information
talldan committed Feb 28, 2024
1 parent 6d4b66e commit ef59150
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 23 deletions.
87 changes: 76 additions & 11 deletions packages/block-library/src/block/deprecated.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,75 @@
// v1: Migrate and rename the `overrides` attribute to the `content` attribute.
const isObject = ( obj ) =>
typeof obj === 'object' && ! Array.isArray( obj ) && obj !== null;

// v2: Migrate to a more condensed version of the 'content' attribute attribute.
const v2 = {
attributes: {
ref: {
type: 'number',
},
overrides: {
type: 'object',
},
},
supports: {
customClassName: false,
html: false,
inserter: false,
renaming: false,
},
// Force this deprecation to run whenever there's a values sub-property that's an object.
//
// This could fail in the future if a block ever has binding to a `values` attribute.
// Some extra protection is added to ensure `values` is an object, but this only reduces
// the likelihood, it doesn't solve it completely.
isEligible( { content } ) {
return (
!! content &&
Object.keys( content ).every(
( contentKey ) =>
content[ contentKey ].values &&
isObject( content[ contentKey ].values )
)
);
},
/*
* Old attribute format:
* content: {
* "V98q_x": {
* // The attribute values are now stored as a 'values' sub-property.
* values: { content: 'My content value' },
* // ... additional metadata, like the block name can be stored here.
* }
* }
*
* New attribute format:
* content: {
* "V98q_x": {
* content: 'My content value',
* }
* }
*/
migrate( attributes ) {
const { content, ...retainedAttributes } = attributes;

if ( content && Object.keys( content ).length ) {
const updatedContent = { ...content };

for ( const contentKey in content ) {
updatedContent[ contentKey ] = content[ contentKey ].values;
}

return {
...retainedAttributes,
content,
};
}

return attributes;
},
};

// v1: Rename the `overrides` attribute to the `content` attribute.
const v1 = {
attributes: {
ref: {
Expand All @@ -23,16 +94,12 @@ const v1 = {
* overrides: {
* // An key is an id that represents a block.
* // The values are the attribute values of the block.
* "V98q_x": { content: 'dwefwefwefwe' }
* "V98q_x": { content: 'My content value' }
* }
*
* New attribute format:
* content: {
* "V98q_x": {
* // The attribute values are now stored as a 'values' sub-property.
* values: { content: 'dwefwefwefwe' },
* // ... additional metadata, like the block name can be stored here.
* }
* "V98q_x": { content: 'My content value' }
* }
*
*/
Expand All @@ -42,9 +109,7 @@ const v1 = {
const content = {};

Object.keys( overrides ).forEach( ( id ) => {
content[ id ] = {
values: overrides[ id ],
};
content[ id ] = overrides[ id ];
} );

return {
Expand All @@ -54,4 +119,4 @@ const v1 = {
},
};

export default [ v1 ];
export default [ v2, v1 ];
34 changes: 22 additions & 12 deletions packages/block-library/src/block/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,36 @@ function render_block_core_block( $attributes ) {
$content = $wp_embed->run_shortcode( $reusable_block->post_content );
$content = $wp_embed->autoembed( $content );

// Back compat, the content attribute was previously named overrides and
// had a slightly different format. For blocks that have not been migrated,
// also convert the format here so that the provided `pattern/overrides`
// context is correct.
if ( isset( $attributes['overrides'] ) && ! isset( $attributes['content'] ) ) {
$migrated_content = array();
foreach ( $attributes['overrides'] as $id => $values ) {
$migrated_content[ $id ] = array(
'values' => $values,
);
// Back compat.
// For blocks that have not been migrated in the editor, add some back compat
// so that front-end rendering continues to work.

// This matches the `v2` deprecation. Removes the inner `values` property
// from every item.
if ( isset( $attributes['content' ] ) ) {
foreach ( $attributes['content'] as $content_key => &$content_data ) {
if ( isset( $content_data[ 'values' ] ) ) {
$is_assoc_array = is_array( $content_data[ 'values' ] ) && ! wp_is_numeric_array( $content_data[ 'values' ] );

if ( $is_assoc_array ) {
$content_data = $content_data[ 'values' ];
}
}
}
$attributes['content'] = $migrated_content;
}
$has_pattern_overrides = isset( $attributes['content'] );

// This matches the `v1` deprecation. Rename `overrides` to `content`.
if ( isset( $attributes['overrides'] ) && ! isset( $attributes['content'] ) ) {
$attributes['content'] = $attributes['overrides'];
}


/**
* We set the `pattern/overrides` context through the `render_block_context`
* filter so that it is available when a pattern's inner blocks are
* rendering via do_blocks given it only receives the inner content.
*/
$has_pattern_overrides = isset( $attributes['content'] );
if ( $has_pattern_overrides ) {
$filter_block_context = static function ( $context ) use ( $attributes ) {
$context['pattern/overrides'] = $attributes['content'];
Expand Down

0 comments on commit ef59150

Please sign in to comment.