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

__experimentalBlockPatterns: load them with REST API #39185

Merged
merged 30 commits into from
Mar 28, 2022

Conversation

jsnajdr
Copy link
Member

@jsnajdr jsnajdr commented Mar 3, 2022

This is a draft fix for #39055. We're removing __experimentalBlockPatterns data from editor settings, stop sending them in the initial HTML document, and load them from a new REST endpoint instead. The PR has several parts:

  1. Add a new /wp/v2/block-patterns REST endpoint. Currently, it only supports getting the whole list, not individual items. Gutenberg doesn't need the individual items, but I guess it's a good custom in WP REST APIs to provide access to them, too.
  2. Add a new getBlockPatterns() selector/resolver to the core-data store. It uses the new endpoint to fetch the data.
  3. In the Post Editor React UI, immediately before the settings object is passed to BlockEditorProvider, fill the __experimentalBlockPatterns field with results of the core-data selector if it's not present.
  4. Do the same also in the Site Editor UI, at a different place, but in the same spirit. We can also remove the creation of __experimentalBlockPatterns field in the PHP code that generates the wp.editSite.initializeEditor code.
  5. Register a filter (block_editor_settings_all) that removes __experimentalBlockPatterns field from the settings generated by Core pages like site-editor.php or edit-form-blocks.php.

If this works well, I'll add an endpoint for block pattern categories, too.

There's one thing I don't like about this patch: I used an approach that is already used for __experimentalReusableBlocks, but it has one downside: instead of loading the block patterns only when they're needed, i.e., when opening the Block Inserter UI, they are loaded when the editor is initialized. So the download is not really delayed, only slightly deferred and parallelized: instead of being a static part of the initial HTML, there's a separate REST request that doesn't block anything.

I'll proceed with trying to improve this: the settings field won't be the block pattern list itself, but rather a function to fetch them, used by a resolver. There's an __experimentalFetchLinkSuggestions field that works like this.

@github-actions
Copy link

github-actions bot commented Mar 3, 2022

Size Change: +287 B (0%)

Total Size: 1.21 MB

Filename Size Change
build/core-data/index.min.js 14.5 kB +167 B (+1%)
build/edit-site/index.min.js 45.2 kB +56 B (0%)
build/editor/index.min.js 38.4 kB +64 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/admin-manifest/index.min.js 1.24 kB
build/annotations/index.min.js 2.77 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 487 B
build/block-directory/index.min.js 6.49 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/index.min.js 148 kB
build/block-editor/style-rtl.css 15.4 kB
build/block-editor/style.css 15.4 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 65 B
build/block-library/blocks/archives/style.css 65 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 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/avatar/editor-rtl.css 59 B
build/block-library/blocks/avatar/editor.css 59 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 445 B
build/block-library/blocks/button/editor.css 445 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 103 B
build/block-library/blocks/code/style.css 103 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 406 B
build/block-library/blocks/columns/style.css 406 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-template/style-rtl.css 127 B
build/block-library/blocks/comment-template/style.css 127 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-query-loop/editor-rtl.css 95 B
build/block-library/blocks/comments-query-loop/editor.css 95 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.56 kB
build/block-library/blocks/cover/style.css 1.56 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 961 B
build/block-library/blocks/gallery/editor.css 964 B
build/block-library/blocks/gallery/style-rtl.css 1.51 kB
build/block-library/blocks/gallery/style.css 1.51 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 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 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 731 B
build/block-library/blocks/image/editor.css 730 B
build/block-library/blocks/image/style-rtl.css 529 B
build/block-library/blocks/image/style.css 535 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 447 B
build/block-library/blocks/latest-posts/style.css 446 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 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 708 B
build/block-library/blocks/navigation-link/editor.css 706 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/view.min.js 375 B
build/block-library/blocks/navigation/editor-rtl.css 2.03 kB
build/block-library/blocks/navigation/editor.css 2.04 kB
build/block-library/blocks/navigation/style-rtl.css 1.89 kB
build/block-library/blocks/navigation/style.css 1.88 kB
build/block-library/blocks/navigation/view.min.js 2.85 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 363 B
build/block-library/blocks/page-list/editor.css 363 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 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 273 B
build/block-library/blocks/paragraph/style.css 273 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/style-rtl.css 446 B
build/block-library/blocks/post-comments-form/style.css 446 B
build/block-library/blocks/post-comments/style-rtl.css 521 B
build/block-library/blocks/post-comments/style.css 521 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 721 B
build/block-library/blocks/post-featured-image/editor.css 721 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 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 323 B
build/block-library/blocks/post-template/style.css 323 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 370 B
build/block-library/blocks/pullquote/style.css 370 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 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 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 201 B
build/block-library/blocks/quote/style.css 201 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 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 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 140 B
build/block-library/blocks/separator/editor.css 140 B
build/block-library/blocks/separator/style-rtl.css 233 B
build/block-library/blocks/separator/style.css 233 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 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 759 B
build/block-library/blocks/site-logo/editor.css 759 B
build/block-library/blocks/site-logo/style-rtl.css 181 B
build/block-library/blocks/site-logo/style.css 181 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 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.37 kB
build/block-library/blocks/social-links/style.css 1.36 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 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 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 226 B
build/block-library/blocks/tag-cloud/style.css 227 B
build/block-library/blocks/template-part/editor-rtl.css 149 B
build/block-library/blocks/template-part/editor.css 149 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 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 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 934 B
build/block-library/common.css 932 B
build/block-library/editor-rtl.css 9.94 kB
build/block-library/editor.css 9.94 kB
build/block-library/index.min.js 171 kB
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/style-rtl.css 11.2 kB
build/block-library/style.css 11.2 kB
build/block-library/theme-rtl.css 689 B
build/block-library/theme.css 694 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 46.8 kB
build/components/index.min.js 223 kB
build/components/style-rtl.css 14.9 kB
build/components/style.css 14.9 kB
build/compose/index.min.js 11.2 kB
build/customize-widgets/index.min.js 11 kB
build/customize-widgets/style-rtl.css 1.39 kB
build/customize-widgets/style.css 1.39 kB
build/data-controls/index.min.js 663 B
build/data/index.min.js 8.61 kB
build/date/index.min.js 32 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.58 kB
build/edit-navigation/index.min.js 15.8 kB
build/edit-navigation/style-rtl.css 4.04 kB
build/edit-navigation/style.css 4.05 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 29.6 kB
build/edit-post/style-rtl.css 7.07 kB
build/edit-post/style.css 7.07 kB
build/edit-site/style-rtl.css 7.6 kB
build/edit-site/style.css 7.58 kB
build/edit-widgets/index.min.js 16.3 kB
build/edit-widgets/style-rtl.css 4.4 kB
build/edit-widgets/style.css 4.39 kB
build/editor/style-rtl.css 3.71 kB
build/editor/style.css 3.71 kB
build/element/index.min.js 4.29 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 6.62 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.83 kB
build/keycodes/index.min.js 1.41 kB
build/list-reusable-blocks/index.min.js 1.75 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.94 kB
build/notices/index.min.js 957 B
build/nux/index.min.js 2.12 kB
build/nux/style-rtl.css 751 B
build/nux/style.css 749 B
build/plugins/index.min.js 1.98 kB
build/preferences/index.min.js 1.2 kB
build/primitives/index.min.js 949 B
build/priority-queue/index.min.js 611 B
build/react-i18n/index.min.js 704 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/index.min.js 2.24 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.2 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.52 kB
build/token-list/index.min.js 668 B
build/url/index.min.js 1.99 kB
build/vendors/react-dom.min.js 38.5 kB
build/vendors/react.min.js 4.34 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 280 B
build/widgets/index.min.js 7.21 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.07 kB

compressed-size-action

@jsnajdr jsnajdr force-pushed the add/block-patterns-endpoint branch from 349af5d to 9b1ad3d Compare March 3, 2022 12:00
@youknowriad youknowriad added [Type] Enhancement A suggestion for improvement. Core REST API Task Task for Core REST API efforts REST API Interaction Related to REST API labels Mar 4, 2022
@ntsekouras
Copy link
Contributor

ntsekouras commented Mar 16, 2022

There's one thing I don't like about this patch: I used an approach that is already used for __experimentalReusableBlocks, but it has one downside: instead of loading the block patterns only when they're needed, i.e., when opening the Block Inserter UI, they are loaded when the editor is initialized.

I think that's good and is needed because patterns are not only used in the inserter. They are used in every block in block-switcher trying to find pattern transformations, during some blocks insertion, etc.... Because parsing the patterns can take some time, right now we preparse them on load, on browsers idle time and I think this should be preserved.

*/
public function get_items() {
$data = WP_Block_Patterns_Registry::get_instance()->get_all_registered();
return rest_ensure_response( $data );
Copy link
Member

Choose a reason for hiding this comment

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

Please ensure that prepare_item_for_response is implemented here. I would also use prepare_response_for_collection.

This is a good example to follow.

https://github.com/WordPress/wordpress-develop/blob/c7e067c578362fd67580ef1ef230856e57171329/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php#L142-L154

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 implemented prepare_item_for_response, which merely copies the supported fields from the "raw" pattern to the "prepared" one. There's not need to sanitize or escape any fields. The patterns have been either registered by themes and plugins, or downloaded from wordpress.org and already sanitized. There's also an add_additional_fields_to_object call which allows new fields to be registered with register_rest_field( 'block-pattern' ).

I added also a prepare_response_for_collection call, although it's a noop because there are no links in the items.

* Constructor.
*/
public function __construct() {
$this->namespace = 'wp/v2';
Copy link
Member

Choose a reason for hiding this comment

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

Testing REST API endpoints, use the __experimental namespace.

Copy link
Member Author

Choose a reason for hiding this comment

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

Moved to __experimental namespace ✅

Copy link
Member

@spacedmonkey spacedmonkey left a comment

Choose a reason for hiding this comment

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

When providing this much PHP code, please provide unit test to prove the REST API endpoints work. Without them it hard to review.

Please ensure that passing ?_fields= param to the rest api works, as other endpoints do.

@jsnajdr
Copy link
Member Author

jsnajdr commented Mar 16, 2022

I think that's good and is needed because patterns are not only used in the inserter.

Still, they should not block the initial load that leads to displaying the post and edit UI. The first time I really need the patterns is when I click on a block and its block controls are displayed, right? Only then there is UI to transform the block to something else, to replace it with another pattern etc.

The canonical way to lazy load things is that they are not loaded until their selector is actually called for the first time:

useSelect( ( select ) => select( blockEditorStore ).getPatterns() );

In our case though, the patterns are loaded much earlier, namely when mounting the editor provider component.

I'm not sure how much of a problem this will still be after we fully migrate the load to REST API. The ideal situation though is that they are loaded as late as possible.

Copy link
Contributor

@ntsekouras ntsekouras left a comment

Choose a reason for hiding this comment

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

I tested and this seems to work well. Thanks @jsnajdr!

lib/rest-api.php Outdated
$block_patterns = new WP_REST_Block_Patterns_Controller();
$block_patterns->register_routes();
}
add_action( 'rest_api_init', 'gutenberg_register_rest_block_patterns' );
Copy link
Contributor

Choose a reason for hiding this comment

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

We should move this in compat/wordpress-6.0 folder.

lib/class-wp-rest-block-patterns-controller.php Outdated Show resolved Hide resolved
*
* @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
*/
public function get_items() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Without the $request param this throws a warning.

Suggested change
public function get_items() {
public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable

@jsnajdr
Copy link
Member Author

jsnajdr commented Mar 17, 2022

Please ensure that passing ?_fields= param to the rest api works, as other endpoints do.

That's supported without writing any explicit code, because the _fields are filtered by the rest_filter_response_fields function registered with the rest_post_dispatch hook.

The endpoint handler could call $this->get_fields_for_response and populate only the requested fields, but that's useful only when it's expensive to calculate the fields. Here we're just copying strings from one object to another.

Comment on lines 100 to 108
$prepared_pattern = array(
'name' => $item['name'],
'title' => $item['title'],
'blockTypes' => $item['blockTypes'],
'categories' => $item['categories'],
'content' => $item['content'],
);

$prepared_pattern = $this->add_additional_fields_to_object( $prepared_pattern, $request );
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
$prepared_pattern = array(
'name' => $item['name'],
'title' => $item['title'],
'blockTypes' => $item['blockTypes'],
'categories' => $item['categories'],
'content' => $item['content'],
);
$prepared_pattern = $this->add_additional_fields_to_object( $prepared_pattern, $request );
$fields = $this->get_fields_for_response( $request );
$prepared_pattern = array();
$keys = array( 'name', 'title', 'blockTypes', 'categories', 'content' );
foreach( $keys as $key ) {
if ( rest_is_field_included( $key, $fields ) ) {
$prepared_pattern[$key] = $item[$key];
}
}
$prepared_pattern = $this->add_additional_fields_to_object( $prepared_pattern, $request );

Let's try this.

Copy link
Member

Choose a reason for hiding this comment

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

@jsnajdr This still needs eyes on.

Copy link
Member Author

Choose a reason for hiding this comment

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

The _fields list is already being honored, just in a different way, I described it here: #39185 (comment)

Or is it preferred that rest_is_field_included is used explicitly by all new endpoints?


$prepared_pattern = $this->add_additional_fields_to_object( $prepared_pattern, $request );

return new WP_REST_Response( $prepared_pattern );
Copy link
Member

@spacedmonkey spacedmonkey Mar 17, 2022

Choose a reason for hiding this comment

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

Suggested change
return new WP_REST_Response( $prepared_pattern );
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$data = $this->add_additional_fields_to_object( $prepared_pattern, $request );
$data = $this->filter_response_by_context( $data, $context );
$response = rest_ensure_response( $data );
return $response;

Copy link
Member Author

Choose a reason for hiding this comment

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

Added context support to the endpoint, although in this case it doesn't really make much difference.

'title' => array(
'description' => __( 'The pattern title, in human readable format.', 'gutenberg' ),
'type' => 'string',
'readonly' => true,
Copy link
Member

Choose a reason for hiding this comment

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

Please ensure that all these properties have 'context' defined.

@jsnajdr
Copy link
Member Author

jsnajdr commented Mar 17, 2022

@ntsekouras There are some changes in this PR that are related to #39493 and that you might be the best person to review:

the goal is to load the remote patterns only in the block-patterns/patterns REST endpoint and to disable loading them everywhere else, with the should_load_remote_block_patterns filter. To achieve that, the PR does:

  • update the lib/compat/wordpress-5.9/block-patterns.php file to only create the _load_remote_featured_patterns function, which otherwise doesn't exist in 5.9 (only in 6.0), and stop calling it in the current_screen action -- we don't want to call it anywhere outside the REST endpoint.
  • update the lib/compat/wordpress-6.0/block-patterns.php file to only create the gutenberg_register_remote_theme_patterns function (new in 6.0) and stop calling it in the current_screen action. Various checks (is theme support, is disabled, ...) are move from the action to the function itself.
  • in lib/compat/wordpress-6.0/edit-form-blocks.php, add a new action that disables remote patterns (with should_load_remote_block_patterns) for block editor pages -- that's to neutralize existing Core calls to _load_remote_featured_patterns et al.
  • load all the patterns (core, featured, theme) explicitly in the REST controller for block-patterns/patterns.

Copy link
Member

@spacedmonkey spacedmonkey left a comment

Choose a reason for hiding this comment

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

Approve, all other tweaks I have suggested, can happen in follow up PRs.

@jsnajdr jsnajdr force-pushed the add/block-patterns-endpoint branch from 8648de4 to f2edbd5 Compare March 28, 2022 11:37
@spacedmonkey
Copy link
Member

would have to work, but it doesn't. The /block-types endpoint doesn't support such a filter.

What I mean was this. http://localhost:8899/wp-json/wp/v2/block-types/core/block which the block type support rest api does support.

@jsnajdr
Copy link
Member Author

jsnajdr commented Mar 28, 2022

http://localhost:8899/wp-json/wp/v2/block-types/core/block

That would work if the block pattern was linking to just one block type. Then it's similar to how, e.g., author can be linked and embedded:

{
  "blockType": "core/paragraph",
  "_links": {
    "blockType": [ {
      "embeddable": true,
      "href": "http://localhost:8899/wp-json/wp/v2/block-types/core/paragraph"
    } ],
  },
  "_embedded: {
    "blockType": [ {
      "name": "core/paragraph",
      ...
    } ]
  }
}

How would the structure look like for array of blockTypes? Would the _links.blockTypes field be an array of several links to individual block types?

Copy link
Contributor

@ntsekouras ntsekouras left a comment

Choose a reason for hiding this comment

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

Thanks @jsnajdr! LGTM 👍

I seem to cannot reproduce my previous comment here about the featured category not being fetched and I couldn't see any related changes about it, afterwards, so 🤷 ..

@jsnajdr jsnajdr merged commit bdd024e into trunk Mar 28, 2022
@jsnajdr jsnajdr deleted the add/block-patterns-endpoint branch March 28, 2022 12:35
@github-actions github-actions bot added this to the Gutenberg 13.0 milestone Mar 28, 2022
@TimothyBJacobs
Copy link
Member

Why is batching support needed here?
There's no reason why the request couldn't be a part of a batch, so I'm enabling batching support. Because why not? My understanding is that it's disabled by default.

Batching is not possible at all for GET requests. So we should remove this in a follow up PR.

@jsnajdr
Copy link
Member Author

jsnajdr commented Mar 29, 2022

Batching is not possible at all for GET requests. So we should remove this in a follow up PR.

That's right, fixing in #39834.

pento pushed a commit to WordPress/wordpress-develop that referenced this pull request Apr 12, 2022
Backport of WordPress/gutenberg#39185 from the Gutenberg plugin. Namely the part where the `gutenberg_remove_block_patterns_settings` filter function removes the block patterns fields from settings.

Props jsnajdr, zieladam.
See #55505.
Follow-up for [53152].



git-svn-id: https://develop.svn.wordpress.org/trunk@53155 602fd350-edb4-49c9-b593-d223f7449a82
github-actions bot pushed a commit to platformsh/wordpress-performance that referenced this pull request Apr 12, 2022
Backport of WordPress/gutenberg#39185 from the Gutenberg plugin. Namely the part where the `gutenberg_remove_block_patterns_settings` filter function removes the block patterns fields from settings.

Props jsnajdr, zieladam.
See #55505.
Follow-up for [53152].


Built from https://develop.svn.wordpress.org/trunk@53155


git-svn-id: https://core.svn.wordpress.org/trunk@52744 1a063a9b-81f0-0310-95a4-ce76da25c4cd
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Apr 12, 2022
Backport of WordPress/gutenberg#39185 from the Gutenberg plugin. Namely the part where the `gutenberg_remove_block_patterns_settings` filter function removes the block patterns fields from settings.

Props jsnajdr, zieladam.
See #55505.
Follow-up for [53152].


Built from https://develop.svn.wordpress.org/trunk@53155


git-svn-id: http://core.svn.wordpress.org/trunk@52744 1a063a9b-81f0-0310-95a4-ce76da25c4cd
fullofcaffeine added a commit to Automattic/wp-calypso that referenced this pull request May 2, 2022
…r of patterns registered

After the changes in WordPress/gutenberg#39185, patterns are not available in the `__experimentalBlockPatterns` symbol anymore.
fullofcaffeine added a commit to Automattic/wp-calypso that referenced this pull request May 2, 2022
…r of patterns registered (#63228)

After the changes in WordPress/gutenberg#39185, patterns are not available in the `__experimentalBlockPatterns` symbol anymore.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Core REST API Task Task for Core REST API efforts REST API Interaction Related to REST API [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants