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

Register post terms variations on taxonomy registration #56080

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
153 changes: 133 additions & 20 deletions packages/block-library/src/post-terms/index.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* Server-side rendering of the `core/post-terms` block.
* Server-side registering and rendering of the `core/post-terms` block.
*
* @package WordPress
*/
Expand Down Expand Up @@ -59,11 +59,100 @@ function render_block_core_post_terms( $attributes, $content, $block ) {
}

/**
* Returns the available variations for the `core/post-terms` block.
* Returns a post terms variation
*
* @return array The available variations for the block.
* @param WP_Taxonomy|stdClass $taxonomy taxonomy entity.
*
* @return array
*/
function build_variation_for_post_terms( $taxonomy ) {
$variation = array(
'name' => $taxonomy->name,
'title' => $taxonomy->label,
'description' => sprintf(
/* translators: %s: taxonomy's label */
__( 'Display a list of assigned terms from the taxonomy: %s' ),
$taxonomy->label
),
'attributes' => array(
'term' => $taxonomy->name,
),
'isActive' => array( 'term' ),
'scope' => array( 'inserter', 'transform' ),
);

return $variation;
}

/**
* Registers a variation for a taxonomy for the post-terms block.
*
* @since 6.X.Y
*
* @param array $variation Variation array from build_variation_for_post_terms.
*/
function block_core_post_terms_register_variation( $variation ) {
/*
* Directly set the variations on the registered block type
* because there's no server side registration for variations (see #47170).
*/
$navigation_block_type = WP_Block_Type_Registry::get_instance()->get_registered( 'core/post-terms' );
/*
* If the block is not registered yet, bail early.
* Variation will be registered in register_block_core_post_terms then.
*/
if ( ! $navigation_block_type ) {
return;
}

$navigation_block_type->variations = array_merge(
$navigation_block_type->variations,
array( $variation )
);
}

/**
* Unregisters a variation for a taxonomy for the post-terms block.
*
* @since 6.X.Y
*
* @param string $name Name of the taxonomy (which was used as variation name).
*/
function block_core_post_terms_unregister_variation( $name ) {
/*
* Directly get the variations from the registered block type
* because there's no server side (un)registration for variations (see #47170).
*/
$navigation_block_type = WP_Block_Type_Registry::get_instance()->get_registered( 'core/post-terms' );
// If the block is not registered (yet), there's no need to remove a variation.
if ( ! $navigation_block_type || empty( $navigation_block_type->variations ) ) {
return;
}
$variations = $navigation_block_type->variations;
// Search for the variation and remove it from the array.
foreach ( $variations as $i => $variation ) {
if ( $variation['name'] === $name ) {
unset( $variations[ $i ] );
break;
}
}
// Reindex array after removing one variation.
$navigation_block_type->variations = array_values( $variations );
}

/**
* Returns an array of variations for the post-terms block.
*
* @since 6.5.0
*
* @return array
*/
function build_post_term_block_variations() {
/*
* This will only handle taxonomies registered until this point (init on priority 9).
* See action hooks below for other taxonomies.
* See https://github.com/WordPress/gutenberg/issues/52569 for details.
*/
$taxonomies = get_taxonomies(
array(
'publicly_queryable' => true,
Expand All @@ -72,28 +161,16 @@ function build_post_term_block_variations() {
'objects'
);

// Split the available taxonomies to `built_in` and custom ones,
// in order to prioritize the `built_in` taxonomies at the
// search results.
/* Split the available taxonomies to `built_in` and custom ones,
* in order to prioritize the `built_in` taxonomies at the
* search results.
*/
$built_ins = array();
$custom_variations = array();

// Create and register the eligible taxonomies variations.
foreach ( $taxonomies as $taxonomy ) {
$variation = array(
'name' => $taxonomy->name,
'title' => $taxonomy->label,
'description' => sprintf(
/* translators: %s: taxonomy's label */
__( 'Display a list of assigned terms from the taxonomy: %s' ),
$taxonomy->label
),
'attributes' => array(
'term' => $taxonomy->name,
),
'isActive' => array( 'term' ),
'scope' => array( 'inserter', 'transform' ),
);
$variation = build_variation_for_post_terms( $taxonomy );
// Set the category variation as the default one.
if ( 'category' === $taxonomy->name ) {
$variation['isDefault'] = true;
Expand Down Expand Up @@ -121,3 +198,39 @@ function register_block_core_post_terms() {
);
}
add_action( 'init', 'register_block_core_post_terms' );
/*
* Register actions for all taxonomies, to add variations when they are registered.
* All taxonomies registered before register_block_core_post_terms, will be handled by that function.
*/
add_action( 'registered_taxonomy', 'block_core_post_terms_register_taxonomy_variation', 10, 3 );
add_action( 'unregistered_taxonomy', 'block_core_post_terms_unregister_taxonomy_variation', 10, 3 );

/**
* Registers a custom taxonomy variation for the post-terms block on taxonomy registration
* Handles all taxonomies registered after the block is registered in register_block_core_post_terms
*
* @since 6.X.Y
*
* @param string $taxonomy Taxonomy slug.
* @param array|string $object_type Object type or array of object types.
* @param array $args Array of taxonomy registration arguments.
* @return void
*/
function block_core_post_terms_register_taxonomy_variation( $taxonomy, $object_type, $args ) {
if ( isset( $args['publicly_queryable'] ) && $args['publicly_queryable']
&& isset( $args['show_in_rest'] ) && $args['show_in_rest'] ) {
$variation = build_variation_for_post_terms( (object) $args );
block_core_post_terms_register_variation( $variation );
}
}

/**
* Unregisters a custom taxonomy variation for post terms block on taxonomy unregistration.
*
* @since 6.X.Y
*
* @param string $taxonomy The taxonomy name passed from unregistered_taxonomy action hook.
*/
function block_core_post_terms_unregister_taxonomy_variation( $taxonomy ) {
block_core_post_terms_unregister_variation( $taxonomy );
}
1 change: 1 addition & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
<element value="build_template_part_block_instance_variations"/>
<element value="build_template_part_block_variations"/>
<element value="build_variation_for_navigation_link"/>
<element value="build_variation_for_post_terms"/>
<element value="classnames_for_block_core_search"/>
<element value="comments_block_form_defaults"/>
<element value="enqueue_legacy_post_comments_block_styles"/>
Expand Down
117 changes: 117 additions & 0 deletions phpunit/blocks/block-post-terms-variations-test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
/**
* Post Terms block variations tests.
*
* @package WordPress
* @subpackage Blocks
*/

/**
* Tests for the Post Terms block variations for taxonomies.
*
* @group blocks
*/
class Block_Post_Terms_Variations_Test extends WP_UnitTestCase {
public function set_up() {
parent::set_up();
register_taxonomy(
'book_type',
array( 'post' ),
array(
'labels' => array(
'name' => 'Book Type',
),
'publicly_queryable' => true,
'show_in_rest' => true,
)
);

register_taxonomy(
'private_book_type',
array( 'post' ),
array(
'labels' => array(
'name' => 'Book Type',
),
'publicly_queryable' => false,
)
);
}

public function tear_down() {
unregister_taxonomy( 'book_type' );
unregister_taxonomy( 'private_book_type' );
unregister_taxonomy( 'temp_book_type' );
parent::tear_down();
}

/**
* @covers ::block_core_post_terms_register_taxonomy_variation
*/
public function test_post_terms_variations_custom_taxonomy() {
$registry = WP_Block_Type_Registry::get_instance();
$post_terms_block = $registry->get_registered( 'core/post-terms' );
$this->assertNotEmpty( $post_terms_block->variations, 'Block has no variations' );
$variation = $this->get_variation_by_name( 'book_type', $post_terms_block->variations );
$this->assertIsArray( $variation, 'Block variation does not exist' );
$this->assertArrayHasKey( 'title', $variation, 'Block variation has no title' );
$this->assertEquals( 'Book Type', $variation['title'], 'Variation title is different than the taxonomy label' );
}

/**
* @covers ::block_core_post_terms_register_taxonomy_variation
*/
public function test_post_terms_variations_custom_private_taxonomy() {
$registry = WP_Block_Type_Registry::get_instance();
$post_terms_block = $registry->get_registered( 'core/post-terms' );
$this->assertNotEmpty( $post_terms_block->variations, 'Block has no variations' );
$variation = $this->get_variation_by_name( 'private_book_type', $post_terms_block->variations );
$this->assertEmpty( $variation, 'Block variation for private taxonomy exists.' );
}

/**
* @covers ::block_core_post_terms_unregister_taxonomy_variation
*/
public function test_post_terms_variations_unregister_taxonomy() {
register_taxonomy(
'temp_book_type',
'custom_book',
array(
'labels' => array(
'name' => 'Book Type',
),
'publicly_queryable' => true,
'show_in_rest' => true,
)
);

$registry = WP_Block_Type_Registry::get_instance();
$post_terms_block = $registry->get_registered( 'core/post-terms' );
$this->assertNotEmpty( $post_terms_block->variations, 'Block has no variations' );
$variation = $this->get_variation_by_name( 'temp_book_type', $post_terms_block->variations );
$this->assertIsArray( $variation, 'Block variation does not exist' );

unregister_taxonomy( 'temp_book_type' );

$variation = $this->get_variation_by_name( 'temp_book_type', $post_terms_block->variations );
$this->assertEmpty( $variation, 'Block variation still exists' );
}

/**
* Get a variation by its name from an array of variations.
*
* @param string $variation_name The name (= slug) of the variation.
* @param array $variations An array of variations.
* @return array|null The found variation or null.
*/
private function get_variation_by_name( $variation_name, $variations ) {
$found_variation = null;
foreach ( $variations as $variation ) {
if ( $variation['name'] === $variation_name ) {
$found_variation = $variation;
}
}

return $found_variation;
}
}
Loading