From 6f57ab749559d93a0a9c7c36e8c572279f71bf06 Mon Sep 17 00:00:00 2001 From: Fabian Todt Date: Mon, 25 Sep 2023 20:01:21 +0200 Subject: [PATCH 1/5] register variations on cpt/taxonomy registration --- .../src/navigation-link/index.php | 56 ++++++++++++ .../block-navigation-link-variations-test.php | 89 +++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 phpunit/blocks/block-navigation-link-variations-test.php diff --git a/packages/block-library/src/navigation-link/index.php b/packages/block-library/src/navigation-link/index.php index 5333ab6ea3dc9..f4427ae1b5747 100644 --- a/packages/block-library/src/navigation-link/index.php +++ b/packages/block-library/src/navigation-link/index.php @@ -322,6 +322,23 @@ function build_variation_for_navigation_link( $entity, $kind ) { return $variation; } +/** + * Register a variation for a post type / taxonomy for the navigation link block + * + * @param array $variation Variation array from build_variation_for_navigation_link. + * @return void + */ +function register_block_core_navigation_link_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/navigation-link' ); + if ( ! $navigation_block_type ) { + return; + } + + $navigation_block_type->variations[] = $variation; +} + /** * Register the navigation link block. * @@ -329,6 +346,8 @@ function build_variation_for_navigation_link( $entity, $kind ) { * @throws WP_Error An WP_Error exception parsing the block definition. */ function register_block_core_navigation_link() { + // This will only handle post types and taxonomies registered until this point (init on priority 9). + // See action hooks at the end of this function for other post types and taxonomies. $post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' ); $taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'objects' ); @@ -367,5 +386,42 @@ function register_block_core_navigation_link() { 'variations' => array_merge( $built_ins, $variations ), ) ); + + // Register actions for all post types and taxonomies not registered until now. + // This needs to happen in this function, because otherwise for post types/taxonomies + // registered before this block, those functions would add variations to a block that don't exist. + add_action( 'registered_post_type', 'register_block_core_navigation_link_post_type_variation', 10, 2 ); + add_action( 'registered_taxonomy', 'register_block_core_navigation_link_taxonomy_variation', 10, 3 ); } add_action( 'init', 'register_block_core_navigation_link' ); + +/** + * Register custom post type variations for navigation link on post type registration + * Handles all post types registered after the block is registered in register_navigation_link_post_type_variations + * + * @param string $post_type The post type name passed from registered_post_type filter. + * @param WP_Post_Type $post_type_object The post type object passed from registered_post_type. + * @return void + */ +function register_block_core_navigation_link_post_type_variation( $post_type, $post_type_object ) { + if ( $post_type_object->show_in_nav_menus ) { + $variation = build_variation_for_navigation_link( $post_type_object, 'post-type' ); + register_block_core_navigation_link_variation( $variation ); + } +} + +/** + * Register a custom taxonomy variation for navigation link on taxonomy registration + * Handles all taxonomies registered after the block is registered in register_navigation_link_post_type_variations + * + * @param string $taxonomy Taxonomy name. + * @param array|string $object_type Name of the object type for the taxonomy object. + * @param array|string $args Optional args used in taxonomy registration. + * @return void + */ +function register_block_core_navigation_link_taxonomy_variation( $taxonomy, $object_type, $args ) { + if ( isset( $args['show_in_nav_menus'] ) && $args['show_in_nav_menus'] ) { + $variation = build_variation_for_navigation_link( (object) $args, 'post-type' ); + register_block_core_navigation_link_variation( $variation ); + } +} diff --git a/phpunit/blocks/block-navigation-link-variations-test.php b/phpunit/blocks/block-navigation-link-variations-test.php new file mode 100644 index 0000000000000..728b1181dad2a --- /dev/null +++ b/phpunit/blocks/block-navigation-link-variations-test.php @@ -0,0 +1,89 @@ + array( + 'item_link' => 'Custom Book', + ), + 'public' => true, + 'show_in_rest' => true, + 'show_in_nav_menus' => true, + ) + ); + register_taxonomy( + 'book_type', + 'custom_book', + array( + 'labels' => array( + 'item_link' => 'Book Type', + ), + 'show_in_nav_menus' => true, + ) + ); + } + + public function tear_down() { + unregister_post_type( 'custom_book' ); + unregister_taxonomy( 'book_type' ); + parent::tear_down(); + } + + /** + * @covers ::register_block_core_navigation_link_post_type_variation + */ + public function test_navigation_link_variations_custom_post_type() { + $registry = WP_Block_Type_Registry::get_instance(); + $nav_link_block = $registry->get_registered( 'core/navigation-link' ); + $this->assertFalse( empty( $nav_link_block->variations ) ); + $variation = $this->get_variation_by_name( 'custom_book', $nav_link_block->variations ); + $this->assertIsArray( $variation ); + $this->assertArrayHasKey( 'title', $variation ); + $this->assertEquals( 'Custom Book', $variation['title'] ); + } + + /** + * @covers ::register_block_core_navigation_link_taxonomy_variation + */ + public function test_navigation_link_variations_custom_taxonomy() { + $registry = WP_Block_Type_Registry::get_instance(); + $nav_link_block = $registry->get_registered( 'core/navigation-link' ); + $this->assertFalse( empty( $nav_link_block->variations ) ); + $variation = $this->get_variation_by_name( 'book_type', $nav_link_block->variations ); + $this->assertIsArray( $variation ); + $this->assertArrayHasKey( 'title', $variation ); + $this->assertEquals( 'Book Type', $variation['title'] ); + } + + /** + * 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; + } +} From 8e2e302d1853431262548751a2d5cffaa9e76af8 Mon Sep 17 00:00:00 2001 From: Fabian Todt Date: Wed, 4 Oct 2023 11:02:34 +0200 Subject: [PATCH 2/5] Apply code documentation suggestions from code review Co-authored-by: Dave Smith --- packages/block-library/src/navigation-link/index.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/navigation-link/index.php b/packages/block-library/src/navigation-link/index.php index f4427ae1b5747..a189f9ae18541 100644 --- a/packages/block-library/src/navigation-link/index.php +++ b/packages/block-library/src/navigation-link/index.php @@ -348,6 +348,7 @@ function register_block_core_navigation_link_variation( $variation ) { function register_block_core_navigation_link() { // This will only handle post types and taxonomies registered until this point (init on priority 9). // See action hooks at the end of this function for other post types and taxonomies. + // See https://github.com/WordPress/gutenberg/issues/53826 for details. $post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' ); $taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'objects' ); @@ -387,9 +388,9 @@ function register_block_core_navigation_link() { ) ); - // Register actions for all post types and taxonomies not registered until now. - // This needs to happen in this function, because otherwise for post types/taxonomies - // registered before this block, those functions would add variations to a block that don't exist. + // Register actions for all post types and taxonomies that may not yet be registered. + // This needs to happen in this function, because otherwise any post types/taxonomies + // registered **before** this block will attempt to register on a block that does not yet exist. add_action( 'registered_post_type', 'register_block_core_navigation_link_post_type_variation', 10, 2 ); add_action( 'registered_taxonomy', 'register_block_core_navigation_link_taxonomy_variation', 10, 3 ); } From d79387e12fafac668a927f516e5c58003bae46f7 Mon Sep 17 00:00:00 2001 From: Fabian Todt Date: Mon, 16 Oct 2023 12:15:03 +0200 Subject: [PATCH 3/5] tests: better assertions --- .../block-navigation-link-variations-test.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/phpunit/blocks/block-navigation-link-variations-test.php b/phpunit/blocks/block-navigation-link-variations-test.php index 728b1181dad2a..c5082e0f4c878 100644 --- a/phpunit/blocks/block-navigation-link-variations-test.php +++ b/phpunit/blocks/block-navigation-link-variations-test.php @@ -49,11 +49,11 @@ public function tear_down() { public function test_navigation_link_variations_custom_post_type() { $registry = WP_Block_Type_Registry::get_instance(); $nav_link_block = $registry->get_registered( 'core/navigation-link' ); - $this->assertFalse( empty( $nav_link_block->variations ) ); + $this->assertNotEmpty( $nav_link_block->variations, 'Block has no variations' ); $variation = $this->get_variation_by_name( 'custom_book', $nav_link_block->variations ); - $this->assertIsArray( $variation ); - $this->assertArrayHasKey( 'title', $variation ); - $this->assertEquals( 'Custom Book', $variation['title'] ); + $this->assertIsArray( $variation, 'Block variation is not an array' ); + $this->assertArrayHasKey( 'title', $variation, 'Block variation has no title' ); + $this->assertEquals( 'Custom Book', $variation['title'], 'Variation title is different than the post type label' ); } /** @@ -62,11 +62,11 @@ public function test_navigation_link_variations_custom_post_type() { public function test_navigation_link_variations_custom_taxonomy() { $registry = WP_Block_Type_Registry::get_instance(); $nav_link_block = $registry->get_registered( 'core/navigation-link' ); - $this->assertFalse( empty( $nav_link_block->variations ) ); + $this->assertNotEmpty( $nav_link_block->variations, 'Block has no variations' ); $variation = $this->get_variation_by_name( 'book_type', $nav_link_block->variations ); - $this->assertIsArray( $variation ); - $this->assertArrayHasKey( 'title', $variation ); - $this->assertEquals( 'Book Type', $variation['title'] ); + $this->assertIsArray( $variation, 'Block variation is not an array' ); + $this->assertArrayHasKey( 'title', $variation, 'Block variation has no title' ); + $this->assertEquals( 'Book Type', $variation['title'], 'Variation title is different than the post type label' ); } /** From dfa40b8ddc2481e0c8c4589d1c80c073e6ff2ba3 Mon Sep 17 00:00:00 2001 From: Fabian Todt Date: Mon, 16 Oct 2023 12:15:45 +0200 Subject: [PATCH 4/5] corect filter params --- packages/block-library/src/navigation-link/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/block-library/src/navigation-link/index.php b/packages/block-library/src/navigation-link/index.php index a189f9ae18541..c7cb3ea286eac 100644 --- a/packages/block-library/src/navigation-link/index.php +++ b/packages/block-library/src/navigation-link/index.php @@ -415,9 +415,9 @@ function register_block_core_navigation_link_post_type_variation( $post_type, $p * Register a custom taxonomy variation for navigation link on taxonomy registration * Handles all taxonomies registered after the block is registered in register_navigation_link_post_type_variations * - * @param string $taxonomy Taxonomy name. - * @param array|string $object_type Name of the object type for the taxonomy object. - * @param array|string $args Optional args used in taxonomy registration. + * @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 register_block_core_navigation_link_taxonomy_variation( $taxonomy, $object_type, $args ) { From e747ba09e3ff207fea0725c0728691766fec3523 Mon Sep 17 00:00:00 2001 From: Fabian Todt Date: Fri, 3 Nov 2023 18:14:32 +0100 Subject: [PATCH 5/5] Move add_action calls outside of function --- .../block-library/src/navigation-link/index.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/navigation-link/index.php b/packages/block-library/src/navigation-link/index.php index c7cb3ea286eac..1165ce94b5921 100644 --- a/packages/block-library/src/navigation-link/index.php +++ b/packages/block-library/src/navigation-link/index.php @@ -332,6 +332,8 @@ function register_block_core_navigation_link_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/navigation-link' ); + // If the block is not registered yet, bail early. + // Variation will be registered in register_block_core_navigation_link then. if ( ! $navigation_block_type ) { return; } @@ -347,7 +349,7 @@ function register_block_core_navigation_link_variation( $variation ) { */ function register_block_core_navigation_link() { // This will only handle post types and taxonomies registered until this point (init on priority 9). - // See action hooks at the end of this function for other post types and taxonomies. + // See action hooks below for other post types and taxonomies. // See https://github.com/WordPress/gutenberg/issues/53826 for details. $post_types = get_post_types( array( 'show_in_nav_menus' => true ), 'objects' ); $taxonomies = get_taxonomies( array( 'show_in_nav_menus' => true ), 'objects' ); @@ -387,14 +389,12 @@ function register_block_core_navigation_link() { 'variations' => array_merge( $built_ins, $variations ), ) ); - - // Register actions for all post types and taxonomies that may not yet be registered. - // This needs to happen in this function, because otherwise any post types/taxonomies - // registered **before** this block will attempt to register on a block that does not yet exist. - add_action( 'registered_post_type', 'register_block_core_navigation_link_post_type_variation', 10, 2 ); - add_action( 'registered_taxonomy', 'register_block_core_navigation_link_taxonomy_variation', 10, 3 ); } add_action( 'init', 'register_block_core_navigation_link' ); +// Register actions for all post types and taxonomies, to add variations when they are registered. +// All post types/taxonomies registered before register_block_core_navigation_link, will be handled by that function. +add_action( 'registered_post_type', 'register_block_core_navigation_link_post_type_variation', 10, 2 ); +add_action( 'registered_taxonomy', 'register_block_core_navigation_link_taxonomy_variation', 10, 3 ); /** * Register custom post type variations for navigation link on post type registration