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

Block patterns: Remove the block that filters out core blocks from the patterns inserter #52656

Merged
merged 5 commits into from
May 18, 2021
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ class Block_Patterns_From_API {
*/
private $utils;

/**
* A dictionary to map existing WPCOM pattern categories to core patterns.
* These should match the categories in $patterns_sources,
* which are registered in $this->register_patterns()
*
* @var array
*/
private $core_to_wpcom_categories_dictionary;

/**
* Block_Patterns constructor.
*
Expand All @@ -54,6 +63,13 @@ public function __construct( $patterns_sources, Block_Patterns_Utils $utils = nu
$patterns_sources = empty( $patterns_sources ) ? array( 'block_patterns' ) : $patterns_sources;
$this->patterns_sources = empty( array_diff( $patterns_sources, $this->valid_patterns_sources ) ) ? $patterns_sources : array( 'block_patterns' );
$this->utils = empty( $utils ) ? new \A8C\FSE\Block_Patterns_Utils() : $utils;
// Add categories to this array using the core pattern name as the key for core patterns we wish to "recategorize".
$this->core_to_wpcom_categories_dictionary = array(
'core/quote' => array(
'quotes' => __( 'Quotes', 'full-site-editing' ),
'text' => __( 'Text', 'full-site-editing' ),
),
);
}

/**
Expand All @@ -62,14 +78,7 @@ public function __construct( $patterns_sources, Block_Patterns_Utils $utils = nu
* @return array Results of pattern registration.
*/
public function register_patterns() {
if ( class_exists( 'WP_Block_Patterns_Registry' ) ) {
// Remove core patterns.
foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) {
if ( 'core/' === substr( $pattern['name'], 0, 5 ) ) {
unregister_block_pattern( $pattern['name'] );
}
}
}
$this->reregister_core_patterns();

// Used to track which patterns we successfully register.
$results = array();
Expand Down Expand Up @@ -141,6 +150,9 @@ function ( $a, $b ) {
}
}
}

$this->update_core_patterns_with_wpcom_categories();

return $results;
}

Expand Down Expand Up @@ -188,21 +200,13 @@ private function get_patterns( $patterns_cache_key, $patterns_source ) {
);

$block_patterns = $this->utils->remote_get( $request_url );

$this->utils->cache_add( $patterns_cache_key, $block_patterns, 'ptk_patterns', DAY_IN_SECONDS );
}

return $block_patterns;
}

/**
* Get the locale to be used for fetching block patterns
*/
private function get_block_patterns_locale() {
// Make sure to get blog locale, not user locale.
$language = function_exists( 'get_blog_lang_code' ) ? get_blog_lang_code() : get_locale();
return \A8C\FSE\Common\get_iso_639_locale( $language );
}

/**
* Check that the pattern is allowed to be registered.
*
Expand Down Expand Up @@ -236,5 +240,56 @@ private function can_register_pattern( $pattern ) {

return true;
}

/**
* Unregister all core patterns, then reregister core patterns in core WordPress only,
* that is those in wp-includes/block-patterns.php
* Gutenberg adds new and overrides existing core patterns. We don't want these for now.
*/
private function reregister_core_patterns() {
if ( class_exists( 'WP_Block_Patterns_Registry' ) ) {
foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) {
// Gutenberg registers patterns with varying prefixes, but categorizes them using `core/*` in a blockTypes array.
Copy link
Member

Choose a reason for hiding this comment

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

It looks like the blockTypes array is used to declare which blocks a pattern is associated with, rather than categorising the pattern itself as core. At the moment, since blockTypes appears to be an experimental feature, using this to target Gutenberg patterns sounds like it should work since they're the only patterns that are using that array. At some point, though, we'll probably want to use this in wpcom patterns so that we can link our patterns with different block types. And plugins might do the same, so could this section unintentionally end up unregistering patterns we don't mean to?

This probably doesn't affect anything right now, though, and I can't quite think of another way to target those Gutenberg patterns. So it might not be a blocker... should we add a "todo" item somewhere to revisit it? Or propose in Gutenberg to flag the experimental ones in some way so that they can be more easily excluded?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for flagging this.

I can't quite think of another way to target those Gutenberg patterns.

It seemed too unruly to add exceptions for query/* and other Gutenberg pattern names, especially if WPCOM wishes to add its own too.

should we add a "todo" item somewhere to revisit it

You bet. Will do.

Or propose in Gutenberg to flag the experimental ones in some way so that they can be more easily excluded

Both I think sound über reasonable. Great idea. 🙇

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've found a patterns tracking issue. I've asked there whether it's worth creating an issue.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good, thanks for that!

// This will ensure we remove `query/*` blocks for example.
// TODO: We need to revisit our usage or $pattern['blockTypes']: they are currently an experimental feature and not guaranteed to reference `core/*` blocks.
$pattern_block_type_or_name = ! empty( $pattern['blockTypes'][0] ) ? $pattern['blockTypes'][0] : $pattern['name'];
if ( 'core/' === substr( $pattern_block_type_or_name, 0, 5 ) ) {
unregister_block_pattern( $pattern['name'] );
}
}
if ( function_exists( '_register_core_block_patterns_and_categories' ) ) {
$did_switch_locale = switch_to_locale( $this->utils->get_block_patterns_locale() );
_register_core_block_patterns_and_categories();
// The site locale might be the same as the current locale so switching could have failed in such instances.
if ( false !== $did_switch_locale ) {
restore_previous_locale();
}
}
}
}

/**
* Update categories for core patterns if a records exists in $this->core_to_wpcom_categories_dictionary
* and reregister them.
*/
private function update_core_patterns_with_wpcom_categories() {
if ( class_exists( 'WP_Block_Patterns_Registry' ) ) {
foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) {
$wpcom_categories = $this->core_to_wpcom_categories_dictionary[ $pattern['name'] ];
if ( isset( $wpcom_categories ) ) {
unregister_block_pattern( $pattern['name'] );
$pattern_properties = array_merge(
$pattern,
array( 'categories' => array_keys( $wpcom_categories ) )
);
unset( $pattern_properties['name'] );
register_block_pattern(
$pattern['name'],
$pattern_properties
);
}
}
}
}
}