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

Support the blockTypes and viewport_width props for remote patterns fetched from Pattern Directory #3967

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 42 additions & 9 deletions src/wp-includes/block-patterns.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,38 @@ function _register_core_block_patterns_and_categories() {
);
}

/**
* Normalize the pattern properties to camelCase.
*
* The API's format is snake_case, `register_block_pattern()` expects camelCase.
*
* @since 6.2.0
* @access private
*
hellofromtonya marked this conversation as resolved.
Show resolved Hide resolved
* @param array $pattern Pattern as returned from the Pattern Directory API.
hellofromtonya marked this conversation as resolved.
Show resolved Hide resolved
* @return array Normalized pattern.
*/
function wp_normalize_remote_block_pattern( $pattern ) {
if ( isset( $pattern['block_types'] ) ) {
$pattern['blockTypes'] = $pattern['block_types'];
unset( $pattern['block_types'] );
}

if ( isset( $pattern['viewport_width'] ) ) {
$pattern['viewportWidth'] = $pattern['viewport_width'];
unset( $pattern['viewport_width'] );
}

return (array) $pattern;
}

/**
* Register Core's official patterns from wordpress.org/patterns.
*
* @since 5.8.0
* @since 5.9.0 The $current_screen argument was removed.
* @since 6.2.0 Normalize the pattern from the API (snake_case) to the
* format expected by `register_block_pattern` (camelCase).
*
* @param WP_Screen $deprecated Unused. Formerly the screen that the current request was triggered from.
*/
Expand Down Expand Up @@ -196,9 +223,10 @@ function _load_remote_block_patterns( $deprecated = null ) {
}
$patterns = $response->get_data();

foreach ( $patterns as $settings ) {
$pattern_name = 'core/' . sanitize_title( $settings['title'] );
register_block_pattern( $pattern_name, (array) $settings );
foreach ( $patterns as $pattern ) {
$normalized_pattern = wp_normalize_remote_block_pattern( $pattern );
$pattern_name = 'core/' . sanitize_title( $normalized_pattern['title'] );
register_block_pattern( $pattern_name, $normalized_pattern );
}
}
}
Expand All @@ -207,6 +235,8 @@ function _load_remote_block_patterns( $deprecated = null ) {
* Register `Featured` (category) patterns from wordpress.org/patterns.
*
* @since 5.9.0
* @since 6.2.0 Normalized the pattern from the API (snake_case) to the
* format expected by `register_block_pattern()` (camelCase).
*/
function _load_remote_featured_patterns() {
$supports_core_patterns = get_theme_support( 'core-block-patterns' );
Expand All @@ -226,14 +256,14 @@ function _load_remote_featured_patterns() {
return;
}
$patterns = $response->get_data();

$registry = WP_Block_Patterns_Registry::get_instance();
foreach ( $patterns as $pattern ) {
$pattern_name = sanitize_title( $pattern['title'] );
$registry = WP_Block_Patterns_Registry::get_instance();
$normalized_pattern = wp_normalize_remote_block_pattern( $pattern );
$pattern_name = sanitize_title( $normalized_pattern['title'] );
// Some patterns might be already registered as core patterns with the `core` prefix.
$is_registered = $registry->is_registered( $pattern_name ) || $registry->is_registered( "core/$pattern_name" );
if ( ! $is_registered ) {
register_block_pattern( $pattern_name, (array) $pattern );
register_block_pattern( $pattern_name, $normalized_pattern );
}
}
}
Expand All @@ -243,6 +273,8 @@ function _load_remote_featured_patterns() {
* `theme.json` file.
*
* @since 6.0.0
* @since 6.2.0 Normalized the pattern from the API (snake_case) to the
* format expected by `register_block_pattern()` (camelCase).
* @access private
*/
function _register_remote_theme_patterns() {
Expand All @@ -269,11 +301,12 @@ function _register_remote_theme_patterns() {
$patterns = $response->get_data();
$patterns_registry = WP_Block_Patterns_Registry::get_instance();
foreach ( $patterns as $pattern ) {
$pattern_name = sanitize_title( $pattern['title'] );
$normalized_pattern = wp_normalize_remote_block_pattern( $pattern );
$pattern_name = sanitize_title( $normalized_pattern['title'] );
// Some patterns might be already registered as core patterns with the `core` prefix.
$is_registered = $patterns_registry->is_registered( $pattern_name ) || $patterns_registry->is_registered( "core/$pattern_name" );
if ( ! $is_registered ) {
register_block_pattern( $pattern_name, (array) $pattern );
register_block_pattern( $pattern_name, $normalized_pattern );
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function get_items( $request ) {
'search' => true,
'slug' => true,
);
$query_args = array_intersect_key( $request->get_params(), $valid_query_args );
$query_args = array_intersect_key( $request->get_params(), $valid_query_args );

$query_args['locale'] = get_user_locale();
$query_args['wp-version'] = $wp_version; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- it's defined in `version.php` above.
Expand Down Expand Up @@ -202,6 +202,7 @@ public function prepare_item_for_response( $item, $request ) {
'keywords' => array_map( 'sanitize_text_field', explode( ',', $raw_pattern->meta->wpop_keywords ) ),
'description' => sanitize_text_field( $raw_pattern->meta->wpop_description ),
'viewport_width' => absint( $raw_pattern->meta->wpop_viewport_width ),
'block_types' => array_map( 'sanitize_text_field', $raw_pattern->meta->wpop_block_types ),
);

$prepared_pattern = $this->add_additional_fields_to_object( $prepared_pattern, $request );
Expand All @@ -224,6 +225,7 @@ public function prepare_item_for_response( $item, $request ) {
* Retrieves the block pattern's schema, conforming to JSON Schema.
*
* @since 5.8.0
* @since 6.2.0 Added `'block_types'` to schema.
*
* @return array Item schema data.
*/
Expand Down Expand Up @@ -286,6 +288,14 @@ public function get_item_schema() {
'type' => 'integer',
'context' => array( 'view', 'edit', 'embed' ),
),

'block_types' => array(
'description' => __( 'The block types which can use this pattern.' ),
'type' => 'array',
'uniqueItems' => true,
'items' => array( 'type' => 'string' ),
'context' => array( 'view', 'embed' ),
),
),
);

Expand Down
9 changes: 6 additions & 3 deletions tests/phpunit/data/blocks/pattern-directory/browse-all.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"spay_email": "",
"wpop_description": "A heading preceded by a chapter number, and followed by a paragraph.",
"wpop_keywords": "blog post",
"wpop_viewport_width": 1000
"wpop_viewport_width": 1000,
"wpop_block_types": [ "core/heading" ]
},
"category_slugs": [ "text" ],
"keyword_slugs": [ "core" ],
Expand All @@ -27,7 +28,8 @@
"spay_email": "",
"wpop_description": "A large hero section with an example background image and a heading in the center.",
"wpop_keywords": "header, hero",
"wpop_viewport_width": 1000
"wpop_viewport_width": 1000,
"wpop_block_types": []
},
"category_slugs": [ "header" ],
"keyword_slugs": [ "core" ],
Expand All @@ -44,7 +46,8 @@
"spay_email": "",
"wpop_description": "A large hero section with a bright gradient background, a big heading and a filled button.",
"wpop_keywords": "call to action, hero section",
"wpop_viewport_width": 1000
"wpop_viewport_width": 1000,
"wpop_block_types": []
},
"category_slugs": [ "header" ],
"keyword_slugs": [ "core" ],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"spay_email": "",
"wpop_description": "Three filled buttons with rounded corners, side by side.",
"wpop_keywords": "",
"wpop_viewport_width": 600
"wpop_viewport_width": 600,
"wpop_block_types": []
},
"category_slugs": [ "buttons" ],
"keyword_slugs": [ "core" ],
Expand All @@ -27,7 +28,8 @@
"spay_email": "",
"wpop_description": "Two buttons, one filled and one outlined, side by side.",
"wpop_keywords": "",
"wpop_viewport_width": 500
"wpop_viewport_width": 500,
"wpop_block_types": []
},
"category_slugs": [ "buttons" ],
"keyword_slugs": [ "core" ],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"spay_email": "",
"wpop_description": "A heading preceded by a chapter number, and followed by a paragraph.",
"wpop_keywords": "",
"wpop_viewport_width": 1000
"wpop_viewport_width": 1000,
"wpop_block_types": []
},
"category_slugs": [ "text" ],
"keyword_slugs": [ "core" ],
Expand All @@ -27,7 +28,8 @@
"spay_email": "",
"wpop_description": "A large hero section with an example background image and a heading in the center.",
"wpop_keywords": "",
"wpop_viewport_width": 1000
"wpop_viewport_width": 1000,
"wpop_block_types": []
},
"category_slugs": [ "header" ],
"keyword_slugs": [ "core" ],
Expand All @@ -44,7 +46,8 @@
"spay_email": "",
"wpop_description": "A large hero section with a bright gradient background, a big heading and a filled button.",
"wpop_keywords": "",
"wpop_viewport_width": 1000
"wpop_viewport_width": 1000,
"wpop_block_types": []
},
"category_slugs": [ "header" ],
"keyword_slugs": [ "core" ],
Expand Down
12 changes: 8 additions & 4 deletions tests/phpunit/data/blocks/pattern-directory/search-button.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"spay_email": "",
"wpop_description": "A large hero section with a bright gradient background, a big heading and a filled button.",
"wpop_keywords": "",
"wpop_viewport_width": 1000
"wpop_viewport_width": 1000,
"wpop_block_types": []
},
"category_slugs": [ "header" ],
"keyword_slugs": [ "core" ],
Expand All @@ -27,7 +28,8 @@
"spay_email": "",
"wpop_description": "Three small columns of text, each with an outlined button with rounded corners at the bottom.",
"wpop_keywords": "",
"wpop_viewport_width": 1000
"wpop_viewport_width": 1000,
"wpop_block_types": []
},
"category_slugs": [ "columns" ],
"keyword_slugs": [ "core" ],
Expand All @@ -44,7 +46,8 @@
"spay_email": "",
"wpop_description": "Three filled buttons with rounded corners, side by side.",
"wpop_keywords": "",
"wpop_viewport_width": 600
"wpop_viewport_width": 600,
"wpop_block_types": []
},
"category_slugs": [ "buttons" ],
"keyword_slugs": [ "core" ],
Expand All @@ -61,7 +64,8 @@
"spay_email": "",
"wpop_description": "Two buttons, one filled and one outlined, side by side.",
"wpop_keywords": "",
"wpop_viewport_width": 500
"wpop_viewport_width": 500,
"wpop_block_types": []
},
"category_slugs": [ "buttons" ],
"keyword_slugs": [ "core" ],
Expand Down