Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocks: Merge variations bootstrapped from a server with the client definitions #60832

Merged
merged 3 commits into from
Apr 22, 2024

Conversation

Mamaduka
Copy link
Member

@Mamaduka Mamaduka commented Apr 17, 2024

What?

Resolves #60298.

PR updates the block type processing logic (processBlockType) to merge the variations settings provided by the server and client.

Why?

Some block settings like variations should be merged.

Testing Instructions

  1. Add block variation to a Group using a PHP snippet.
  2. Open a post or page.
  3. The "Test Group Variation" should be visible in the inserter.

Testing variation

add_filter( 'get_block_type_variations', function( $variations, $block_type ) {
	if ( 'core/group' === $block_type->name ) {
		$variations[] = array(
			'name'  => 'group-test-variation',
			'title' => 'Test Group Variation',
			'icon'  => 'layout',
			'scope' => [ 'inserter' ],
		);
	}

	return $variations;
}, 10, 2 );

Testing Instructions for Keyboard

Same.

Screenshots or screencast

CleanShot 2024-04-18 at 09 28 48

@Mamaduka Mamaduka added [Type] Bug An existing feature does not function as intended [Package] Blocks /packages/blocks [Feature] Block Variations Block variations, including introducing new variations and variations as a feature labels Apr 17, 2024
@Mamaduka Mamaduka self-assigned this Apr 17, 2024
Copy link

github-actions bot commented Apr 17, 2024

Size Change: -1.58 kB (0%)

Total Size: 1.75 MB

Filename Size Change
build/block-editor/content.css 4.5 kB +1 B (0%)
build/block-editor/index.min.js 256 kB -3 B (0%)
build/block-library/blocks/gallery/editor-rtl.css 956 B +9 B (+1%)
build/block-library/blocks/gallery/editor.css 960 B +8 B (+1%)
build/block-library/editor-rtl.css 12.4 kB +6 B (0%)
build/block-library/editor.css 12.4 kB +8 B (0%)
build/blocks/index.min.js 51.6 kB +78 B (0%)
build/components/index.min.js 222 kB -148 B (0%)
build/components/style-rtl.css 11.9 kB +13 B (0%)
build/components/style.css 11.9 kB +14 B (0%)
build/edit-post/index.min.js 18.1 kB -1.38 kB (-7%)
build/edit-post/style-rtl.css 4.24 kB -208 B (-5%)
build/edit-post/style.css 4.23 kB -209 B (-5%)
build/edit-site/index.min.js 225 kB -1.57 kB (-1%)
build/edit-site/style-rtl.css 13.9 kB -89 B (-1%)
build/edit-site/style.css 13.9 kB -91 B (-1%)
build/edit-widgets/index.min.js 17.9 kB +76 B (0%)
build/editor/index.min.js 77.9 kB +1.5 kB (+2%)
build/editor/style-rtl.css 6.94 kB +197 B (+3%)
build/editor/style.css 6.94 kB +196 B (+3%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 955 B
build/annotations/index.min.js 2.27 kB
build/api-fetch/index.min.js 2.32 kB
build/autop/index.min.js 2.1 kB
build/blob/index.min.js 578 B
build/block-directory/index.min.js 7.26 kB
build/block-directory/style-rtl.css 1.03 kB
build/block-directory/style.css 1.03 kB
build/block-editor/content-rtl.css 4.51 kB
build/block-editor/default-editor-styles-rtl.css 395 B
build/block-editor/default-editor-styles.css 395 B
build/block-editor/style-rtl.css 15.6 kB
build/block-editor/style.css 15.6 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 90 B
build/block-library/blocks/archives/style.css 90 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 122 B
build/block-library/blocks/audio/style.css 122 B
build/block-library/blocks/audio/theme-rtl.css 133 B
build/block-library/blocks/audio/theme.css 133 B
build/block-library/blocks/avatar/editor-rtl.css 116 B
build/block-library/blocks/avatar/editor.css 116 B
build/block-library/blocks/avatar/style-rtl.css 104 B
build/block-library/blocks/avatar/style.css 104 B
build/block-library/blocks/block/editor-rtl.css 305 B
build/block-library/blocks/block/editor.css 305 B
build/block-library/blocks/button/editor-rtl.css 415 B
build/block-library/blocks/button/editor.css 414 B
build/block-library/blocks/button/style-rtl.css 627 B
build/block-library/blocks/button/style.css 626 B
build/block-library/blocks/buttons/editor-rtl.css 337 B
build/block-library/blocks/buttons/editor.css 337 B
build/block-library/blocks/buttons/style-rtl.css 332 B
build/block-library/blocks/buttons/style.css 332 B
build/block-library/blocks/calendar/style-rtl.css 239 B
build/block-library/blocks/calendar/style.css 239 B
build/block-library/blocks/categories/editor-rtl.css 113 B
build/block-library/blocks/categories/editor.css 112 B
build/block-library/blocks/categories/style-rtl.css 124 B
build/block-library/blocks/categories/style.css 124 B
build/block-library/blocks/code/editor-rtl.css 53 B
build/block-library/blocks/code/editor.css 53 B
build/block-library/blocks/code/style-rtl.css 121 B
build/block-library/blocks/code/style.css 121 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 421 B
build/block-library/blocks/columns/style.css 421 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-content/style-rtl.css 92 B
build/block-library/blocks/comment-content/style.css 92 B
build/block-library/blocks/comment-template/style-rtl.css 199 B
build/block-library/blocks/comment-template/style.css 198 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-title/editor-rtl.css 75 B
build/block-library/blocks/comments-title/editor.css 75 B
build/block-library/blocks/comments/editor-rtl.css 840 B
build/block-library/blocks/comments/editor.css 839 B
build/block-library/blocks/comments/style-rtl.css 637 B
build/block-library/blocks/comments/style.css 636 B
build/block-library/blocks/cover/editor-rtl.css 671 B
build/block-library/blocks/cover/editor.css 674 B
build/block-library/blocks/cover/style-rtl.css 1.7 kB
build/block-library/blocks/cover/style.css 1.69 kB
build/block-library/blocks/details/editor-rtl.css 65 B
build/block-library/blocks/details/editor.css 65 B
build/block-library/blocks/details/style-rtl.css 86 B
build/block-library/blocks/details/style.css 86 B
build/block-library/blocks/embed/editor-rtl.css 322 B
build/block-library/blocks/embed/editor.css 322 B
build/block-library/blocks/embed/style-rtl.css 410 B
build/block-library/blocks/embed/style.css 410 B
build/block-library/blocks/embed/theme-rtl.css 133 B
build/block-library/blocks/embed/theme.css 133 B
build/block-library/blocks/file/editor-rtl.css 326 B
build/block-library/blocks/file/editor.css 327 B
build/block-library/blocks/file/style-rtl.css 280 B
build/block-library/blocks/file/style.css 281 B
build/block-library/blocks/file/view.min.js 324 B
build/block-library/blocks/footnotes/style-rtl.css 201 B
build/block-library/blocks/footnotes/style.css 199 B
build/block-library/blocks/form-input/editor-rtl.css 227 B
build/block-library/blocks/form-input/editor.css 227 B
build/block-library/blocks/form-input/style-rtl.css 343 B
build/block-library/blocks/form-input/style.css 343 B
build/block-library/blocks/form-submission-notification/editor-rtl.css 340 B
build/block-library/blocks/form-submission-notification/editor.css 340 B
build/block-library/blocks/form-submit-button/style-rtl.css 69 B
build/block-library/blocks/form-submit-button/style.css 69 B
build/block-library/blocks/form/view.min.js 471 B
build/block-library/blocks/freeform/editor-rtl.css 2.61 kB
build/block-library/blocks/freeform/editor.css 2.61 kB
build/block-library/blocks/gallery/style-rtl.css 1.72 kB
build/block-library/blocks/gallery/style.css 1.72 kB
build/block-library/blocks/gallery/theme-rtl.css 108 B
build/block-library/blocks/gallery/theme.css 108 B
build/block-library/blocks/group/editor-rtl.css 647 B
build/block-library/blocks/group/editor.css 647 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 189 B
build/block-library/blocks/heading/style.css 189 B
build/block-library/blocks/html/editor-rtl.css 336 B
build/block-library/blocks/html/editor.css 337 B
build/block-library/blocks/image/editor-rtl.css 878 B
build/block-library/blocks/image/editor.css 878 B
build/block-library/blocks/image/style-rtl.css 1.6 kB
build/block-library/blocks/image/style.css 1.59 kB
build/block-library/blocks/image/theme-rtl.css 133 B
build/block-library/blocks/image/theme.css 133 B
build/block-library/blocks/image/view.min.js 1.54 kB
build/block-library/blocks/latest-comments/style-rtl.css 357 B
build/block-library/blocks/latest-comments/style.css 357 B
build/block-library/blocks/latest-posts/editor-rtl.css 213 B
build/block-library/blocks/latest-posts/editor.css 212 B
build/block-library/blocks/latest-posts/style-rtl.css 478 B
build/block-library/blocks/latest-posts/style.css 478 B
build/block-library/blocks/list/style-rtl.css 88 B
build/block-library/blocks/list/style.css 88 B
build/block-library/blocks/media-text/editor-rtl.css 306 B
build/block-library/blocks/media-text/editor.css 305 B
build/block-library/blocks/media-text/style-rtl.css 505 B
build/block-library/blocks/media-text/style.css 503 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 668 B
build/block-library/blocks/navigation-link/editor.css 669 B
build/block-library/blocks/navigation-link/style-rtl.css 259 B
build/block-library/blocks/navigation-link/style.css 257 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 296 B
build/block-library/blocks/navigation-submenu/editor.css 295 B
build/block-library/blocks/navigation/editor-rtl.css 2.26 kB
build/block-library/blocks/navigation/editor.css 2.26 kB
build/block-library/blocks/navigation/style-rtl.css 2.26 kB
build/block-library/blocks/navigation/style.css 2.25 kB
build/block-library/blocks/navigation/view.min.js 1.03 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 377 B
build/block-library/blocks/page-list/editor.css 377 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 235 B
build/block-library/blocks/paragraph/editor.css 235 B
build/block-library/blocks/paragraph/style-rtl.css 335 B
build/block-library/blocks/paragraph/style.css 335 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/editor-rtl.css 96 B
build/block-library/blocks/post-comments-form/editor.css 96 B
build/block-library/blocks/post-comments-form/style-rtl.css 508 B
build/block-library/blocks/post-comments-form/style.css 508 B
build/block-library/blocks/post-content/editor-rtl.css 74 B
build/block-library/blocks/post-content/editor.css 74 B
build/block-library/blocks/post-date/style-rtl.css 61 B
build/block-library/blocks/post-date/style.css 61 B
build/block-library/blocks/post-excerpt/editor-rtl.css 71 B
build/block-library/blocks/post-excerpt/editor.css 71 B
build/block-library/blocks/post-excerpt/style-rtl.css 141 B
build/block-library/blocks/post-excerpt/style.css 141 B
build/block-library/blocks/post-featured-image/editor-rtl.css 729 B
build/block-library/blocks/post-featured-image/editor.css 727 B
build/block-library/blocks/post-featured-image/style-rtl.css 342 B
build/block-library/blocks/post-featured-image/style.css 342 B
build/block-library/blocks/post-navigation-link/style-rtl.css 215 B
build/block-library/blocks/post-navigation-link/style.css 214 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 409 B
build/block-library/blocks/post-template/style.css 408 B
build/block-library/blocks/post-terms/style-rtl.css 96 B
build/block-library/blocks/post-terms/style.css 96 B
build/block-library/blocks/post-time-to-read/style-rtl.css 69 B
build/block-library/blocks/post-time-to-read/style.css 69 B
build/block-library/blocks/post-title/style-rtl.css 100 B
build/block-library/blocks/post-title/style.css 100 B
build/block-library/blocks/preformatted/style-rtl.css 125 B
build/block-library/blocks/preformatted/style.css 125 B
build/block-library/blocks/pullquote/editor-rtl.css 135 B
build/block-library/blocks/pullquote/editor.css 135 B
build/block-library/blocks/pullquote/style-rtl.css 354 B
build/block-library/blocks/pullquote/style.css 353 B
build/block-library/blocks/pullquote/theme-rtl.css 174 B
build/block-library/blocks/pullquote/theme.css 174 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 288 B
build/block-library/blocks/query-pagination/style.css 284 B
build/block-library/blocks/query-title/style-rtl.css 63 B
build/block-library/blocks/query-title/style.css 63 B
build/block-library/blocks/query/editor-rtl.css 486 B
build/block-library/blocks/query/editor.css 486 B
build/block-library/blocks/query/view.min.js 958 B
build/block-library/blocks/quote/style-rtl.css 237 B
build/block-library/blocks/quote/style.css 237 B
build/block-library/blocks/quote/theme-rtl.css 233 B
build/block-library/blocks/quote/theme.css 235 B
build/block-library/blocks/read-more/style-rtl.css 140 B
build/block-library/blocks/read-more/style.css 140 B
build/block-library/blocks/rss/editor-rtl.css 149 B
build/block-library/blocks/rss/editor.css 149 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 184 B
build/block-library/blocks/search/editor.css 184 B
build/block-library/blocks/search/style-rtl.css 690 B
build/block-library/blocks/search/style.css 689 B
build/block-library/blocks/search/theme-rtl.css 114 B
build/block-library/blocks/search/theme.css 114 B
build/block-library/blocks/search/view.min.js 478 B
build/block-library/blocks/separator/editor-rtl.css 146 B
build/block-library/blocks/separator/editor.css 146 B
build/block-library/blocks/separator/style-rtl.css 239 B
build/block-library/blocks/separator/style.css 239 B
build/block-library/blocks/separator/theme-rtl.css 194 B
build/block-library/blocks/separator/theme.css 194 B
build/block-library/blocks/shortcode/editor-rtl.css 323 B
build/block-library/blocks/shortcode/editor.css 323 B
build/block-library/blocks/site-logo/editor-rtl.css 801 B
build/block-library/blocks/site-logo/editor.css 801 B
build/block-library/blocks/site-logo/style-rtl.css 204 B
build/block-library/blocks/site-logo/style.css 204 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 116 B
build/block-library/blocks/site-title/editor.css 116 B
build/block-library/blocks/site-title/style-rtl.css 57 B
build/block-library/blocks/site-title/style.css 57 B
build/block-library/blocks/social-link/editor-rtl.css 184 B
build/block-library/blocks/social-link/editor.css 184 B
build/block-library/blocks/social-links/editor-rtl.css 676 B
build/block-library/blocks/social-links/editor.css 675 B
build/block-library/blocks/social-links/style-rtl.css 1.48 kB
build/block-library/blocks/social-links/style.css 1.48 kB
build/block-library/blocks/spacer/editor-rtl.css 350 B
build/block-library/blocks/spacer/editor.css 350 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 395 B
build/block-library/blocks/table/editor.css 395 B
build/block-library/blocks/table/style-rtl.css 639 B
build/block-library/blocks/table/style.css 639 B
build/block-library/blocks/table/theme-rtl.css 152 B
build/block-library/blocks/table/theme.css 152 B
build/block-library/blocks/tag-cloud/style-rtl.css 251 B
build/block-library/blocks/tag-cloud/style.css 253 B
build/block-library/blocks/template-part/editor-rtl.css 431 B
build/block-library/blocks/template-part/editor.css 431 B
build/block-library/blocks/template-part/theme-rtl.css 107 B
build/block-library/blocks/template-part/theme.css 107 B
build/block-library/blocks/term-description/style-rtl.css 111 B
build/block-library/blocks/term-description/style.css 111 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 99 B
build/block-library/blocks/verse/style.css 99 B
build/block-library/blocks/video/editor-rtl.css 552 B
build/block-library/blocks/video/editor.css 555 B
build/block-library/blocks/video/style-rtl.css 185 B
build/block-library/blocks/video/style.css 185 B
build/block-library/blocks/video/theme-rtl.css 133 B
build/block-library/blocks/video/theme.css 133 B
build/block-library/classic-rtl.css 179 B
build/block-library/classic.css 179 B
build/block-library/common-rtl.css 1.11 kB
build/block-library/common.css 1.11 kB
build/block-library/editor-elements-rtl.css 75 B
build/block-library/editor-elements.css 75 B
build/block-library/elements-rtl.css 54 B
build/block-library/elements.css 54 B
build/block-library/index.min.js 218 kB
build/block-library/reset-rtl.css 472 B
build/block-library/reset.css 472 B
build/block-library/style-rtl.css 14.8 kB
build/block-library/style.css 14.8 kB
build/block-library/theme-rtl.css 707 B
build/block-library/theme.css 713 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.87 kB
build/commands/index.min.js 15.2 kB
build/commands/style-rtl.css 953 B
build/commands/style.css 951 B
build/compose/index.min.js 12.6 kB
build/core-commands/index.min.js 2.77 kB
build/core-data/index.min.js 72.5 kB
build/customize-widgets/index.min.js 11.2 kB
build/customize-widgets/style-rtl.css 1.36 kB
build/customize-widgets/style.css 1.36 kB
build/data-controls/index.min.js 640 B
build/data/index.min.js 9 kB
build/date/index.min.js 17.9 kB
build/deprecated/index.min.js 451 B
build/dom-ready/index.min.js 324 B
build/dom/index.min.js 4.65 kB
build/edit-post/classic-rtl.css 578 B
build/edit-post/classic.css 578 B
build/edit-widgets/style-rtl.css 4.16 kB
build/edit-widgets/style.css 4.16 kB
build/element/index.min.js 4.83 kB
build/escape-html/index.min.js 537 B
build/format-library/index.min.js 8.07 kB
build/format-library/style-rtl.css 493 B
build/format-library/style.css 492 B
build/hooks/index.min.js 1.55 kB
build/html-entities/index.min.js 448 B
build/i18n/index.min.js 3.58 kB
build/interactivity/debug.min.js 16.2 kB
build/interactivity/file.min.js 447 B
build/interactivity/image.min.js 1.67 kB
build/interactivity/index.min.js 13 kB
build/interactivity/navigation.min.js 1.17 kB
build/interactivity/query.min.js 740 B
build/interactivity/router.min.js 1.36 kB
build/interactivity/search.min.js 618 B
build/is-shallow-equal/index.min.js 527 B
build/keyboard-shortcuts/index.min.js 1.3 kB
build/keycodes/index.min.js 1.46 kB
build/list-reusable-blocks/index.min.js 2.11 kB
build/list-reusable-blocks/style-rtl.css 851 B
build/list-reusable-blocks/style.css 851 B
build/media-utils/index.min.js 2.92 kB
build/modules/importmap-polyfill.min.js 12.2 kB
build/notices/index.min.js 948 B
build/nux/index.min.js 1.57 kB
build/nux/style-rtl.css 748 B
build/nux/style.css 744 B
build/patterns/index.min.js 6.47 kB
build/patterns/style-rtl.css 595 B
build/patterns/style.css 595 B
build/plugins/index.min.js 1.8 kB
build/preferences-persistence/index.min.js 2.06 kB
build/preferences/index.min.js 2.85 kB
build/preferences/style-rtl.css 710 B
build/preferences/style.css 712 B
build/primitives/index.min.js 975 B
build/priority-queue/index.min.js 1.52 kB
build/private-apis/index.min.js 1 kB
build/react-i18n/index.min.js 623 B
build/react-refresh-entry/index.min.js 9.47 kB
build/react-refresh-runtime/index.min.js 6.78 kB
build/redux-routine/index.min.js 2.7 kB
build/reusable-blocks/index.min.js 2.73 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10 kB
build/router/index.min.js 1.88 kB
build/server-side-render/index.min.js 1.96 kB
build/shortcode/index.min.js 1.39 kB
build/style-engine/index.min.js 2.03 kB
build/token-list/index.min.js 582 B
build/url/index.min.js 3.74 kB
build/vendors/inert-polyfill.min.js 2.48 kB
build/vendors/react-dom.min.js 41.7 kB
build/vendors/react.min.js 4.02 kB
build/viewport/index.min.js 957 B
build/warning/index.min.js 249 B
build/widgets/index.min.js 7.23 kB
build/widgets/style-rtl.css 1.17 kB
build/widgets/style.css 1.17 kB
build/wordcount/index.min.js 1.02 kB

compressed-size-action

Comment on lines 64 to 67
variations: [
...( bootstrappedBlockType?.variations || [] ),
...( blockSettings?.variations || [] ),
],
Copy link
Member Author

@Mamaduka Mamaduka Apr 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially planned to use deepmerge here but decided to handle only this singular case for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should do some more sophisticated merging from the beginning. It doesn't need to be deep merge, but it should handle the following typical situation.

The server usually knows some subset of the block registration info. It can know as little as just the name and render_callback. The bootstrapped block info from server can look something like this:

{
  name: 'core/group',
  title: 'Group',
  variations: [
    {
      name: 'group-row',
      title: 'Row'
    },
    {
      name: 'group-stack',
      title: 'Stack'
    }
  ]
}

Then when the client registers the block in JS, it has the complete information. Including some fields that have JS functions as values, and can't be even expressed in PHP and JSON. The client-side block registration then does a shallow merge of the server and client values:

...bootstrappedBlockType, // from server PHP
...blockSettings, // from client JS

There's no merging of fields, just overwriting server values with client ones.

The individual variations have the same field structure as the top-level block. Therefore, to combine server and client information, you should match the array elements by name, and merge them. Like:

variations = bootstrappedVariations.map( b => {
  return {
    ...b,
    ...clientVariations.find( c => c.name === b.name ),
  }
} );

The real code should also add the items that are not in bootstrappedVariations but are only in clientVariations, but you get the idea.

Note that there is no deep merging, just matching the array elements and shallow-merging them together.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Thanks, @jsnajdr!

Also, just to clarify, I was considering deep merging of whole setting objects.

...deepmerge( bootstrappedBlockType, blockSettings )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think deepmerge is overkill, and base block registration doesn't do that either. You might even end up with some unexpected buggy results. It might not always be a good idea to merge {a} and {b} into {a,b} or {a:[1]} and {a:[2]} into {a:[1,2]}.

Deep merging should be very specifically targeted at specific properties. For example, with variations, we'll be doing one-level deep merge of two arrays keyed by name.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think deepmerge is overkill

I thought so too, and dropped the idea 😄

We can add similar handlers as needed and eventually extract them into a custom merger method.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in ad4c38d.

@Mamaduka Mamaduka marked this pull request as ready for review April 18, 2024 05:31
@Mamaduka Mamaduka requested a review from jsnajdr April 18, 2024 05:31
Copy link

github-actions bot commented Apr 18, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: Mamaduka <[email protected]>
Co-authored-by: jsnajdr <[email protected]>
Co-authored-by: tyxla <[email protected]>
Co-authored-by: t-hamano <[email protected]>
Co-authored-by: joemcgill <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@Mamaduka Mamaduka requested a review from tyxla April 18, 2024 05:32
@Mamaduka Mamaduka force-pushed the fix/block-registration-merge-settings branch from de8786a to be32c0b Compare April 18, 2024 11:39
@Mamaduka
Copy link
Member Author

@jsnajdr, @tyxla, do you mind having another look? 🙇

Copy link
Member

@tyxla tyxla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good in my opinion, but I wanted to ask a few naive questions before I ✅ .

clientVariations.forEach( ( clientVariation ) => {
const index = result.findIndex(
( bootstrappedVariation ) =>
bootstrappedVariation.name === clientVariation.name
Copy link
Member

@tyxla tyxla Apr 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any concerns with the fact that variations are not required to have a name? Could this possibly run into the issue of wrongly assuming two completely different variations without a name are the same one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Odd. I always thought that a unique name was required; this seems like an oversight on our end.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's a very rare or legacy scenario, but still worth considering. I was also surprised when I learned about it when reading @ndiego's post linked above.

Maybe we should treat such variations as unique and never attempt to merge them?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the article is wrong about this (fyi @ndiego). A variation name is crucial for Gutenberg to be able to use it. If I look at how variations list for block inserter is constructed in getInserterItems and getItemFromVariation, how an unique id is generated from block and variation name in getItemFromVariation, how the name is used as a React list key in many UI components, I don't think a variation without a name would work.

);

if ( index !== -1 ) {
result[ index ] = { ...result[ index ], ...clientVariation };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we intentionally want to keep the bootstrapped variation data and mingle it with the client side one? What if on the client we intentionally want to keep a variation property empty, but the server declares it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate a little more here?

The merge is intentional. Otherwise, data defined on the client side will override variations provided by the server, which causes the bug described in the original issue #60298.

I think processing logic should respect any definition of block variations. The server-side definition becomes much easier with WP 6.5, and I think we'll see more issue reports until this is resolved.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if on the client we intentionally want to keep a variation property empty, but the server declares it?

You mean that the server would set a variation property and then client doesn't want it to exist at all, wants to unset it? This should never happen. First, when registering blocks, the server has incomplete information and then the client fills in the missing pieces or providing more detail. The server information should not be ever wrong, the client's job is to improve it, not overwrite.

Second, the block registration already uses exactly the same logic when building the blockType object:

  ...select.getBootstrappedBlockType( name ),
  ...blockSettings,

In this PR we're merely extending this logic to variations.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The server information should not be ever wrong, the client's job is to improve it, not overwrite.

This is what I wanted to confirm. If that's the intention, then we're good here.

variations: mergeBlockVariations(
bootstrappedBlockType?.variations,
blockSettings?.variations
),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, if neither source has a variation field, we shouldn't set it on the resulting blockType at all.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That case would result in empty array, just like before.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I didn't notice there is always an empty array by default.

clientVariations.forEach( ( clientVariation ) => {
const index = result.findIndex(
( bootstrappedVariation ) =>
bootstrappedVariation.name === clientVariation.name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the article is wrong about this (fyi @ndiego). A variation name is crucial for Gutenberg to be able to use it. If I look at how variations list for block inserter is constructed in getInserterItems and getItemFromVariation, how an unique id is generated from block and variation name in getItemFromVariation, how the name is used as a React list key in many UI components, I don't think a variation without a name would work.

Copy link
Member

@jsnajdr jsnajdr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

variations: mergeBlockVariations(
bootstrappedBlockType?.variations,
blockSettings?.variations
),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I didn't notice there is always an empty array by default.

@Mamaduka
Copy link
Member Author

Thanks for the reviews and feedback! 🙇

I'll try to follow up on variations requiring the name property. A warning could be a good start while also supporting previous behavior.

@Mamaduka Mamaduka merged commit ad31355 into trunk Apr 22, 2024
71 of 72 checks passed
@Mamaduka Mamaduka deleted the fix/block-registration-merge-settings branch April 22, 2024 17:13
@github-actions github-actions bot added this to the Gutenberg 18.3 milestone Apr 22, 2024
@gziolo
Copy link
Member

gziolo commented Apr 24, 2024

Here is the type definition for block variations:

https://github.com/WordPress/gutenberg/blob/ba3a51f27dfe6823f6c6817531e9f095b4635cc7/packages/blocks/src/api/registration.js#L62L98

Name and title are mandatory. It's also reflected in block.json schema:

https://github.com/WordPress/gutenberg/blob/ba3a51f27dfe6823f6c6817531e9f095b4635cc7/schemas/json/block.json#L894L980

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block Variations Block variations, including introducing new variations and variations as a feature [Package] Blocks /packages/blocks [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Block variations registered on the server can get overwritten in the client
4 participants