Skip to content

Commit

Permalink
Better navigation link variations for post types / taxonomies (#56100)
Browse files Browse the repository at this point in the history
* better naming + code comments

* add unit tests for private post types / taxonomies

* handle unregistering of post types / taxonomies

* Fix typo in code comment

Co-authored-by: Andrei Draganescu <me@andreidraganescu.info>

---------

Co-authored-by: Andrei Draganescu <me@andreidraganescu.info>
  • Loading branch information
gaambo and draganescu committed Jan 12, 2024
1 parent 1b6948a commit 295ebf5
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 15 deletions.
68 changes: 58 additions & 10 deletions packages/block-library/src/navigation-link/index.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* Server-side rendering of the `core/navigation-link` block.
* Server-side registering and rendering of the `core/navigation-link` block.
*
* @package WordPress
*/
Expand Down Expand Up @@ -323,12 +323,12 @@ function build_variation_for_navigation_link( $entity, $kind ) {
}

/**
* Register a variation for a post type / taxonomy for the navigation link block
* 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 ) {
function block_core_navigation_link_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/navigation-link' );
Expand All @@ -341,6 +341,31 @@ function register_block_core_navigation_link_variation( $variation ) {
$navigation_block_type->variations[] = $variation;
}

/**
* Unregister a variation for a post type / taxonomy for the navigation link block.
*
* @param string $name Name of the post type / taxonomy (which was used as variation name).
* @return void
*/
function block_core_navigation_link_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/navigation-link' );
// 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;
}
// Search for the variation and remove it from the array.
foreach ( $navigation_block_type->variations as $i => $variation ) {
if ( $variation['name'] === $name ) {
unset( $navigation_block_type->variations[ $i ] );
break;
}
}
// Reindex array after removing one variation.
$navigation_block_type->variations = array_values( $navigation_block_type->variations );
}

/**
* Register the navigation link block.
*
Expand Down Expand Up @@ -393,21 +418,24 @@ function register_block_core_navigation_link() {
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 );
add_action( 'registered_post_type', 'block_core_navigation_link_register_post_type_variation', 10, 2 );
add_action( 'registered_taxonomy', 'block_core_navigation_link_register_taxonomy_variation', 10, 3 );
// Handle unregistering of post types and taxonomies and remove the variations.
add_action( 'unregistered_post_type', 'block_core_navigation_link_unregister_post_type_variation' );
add_action( 'unregistered_taxonomy', 'block_core_navigation_link_unregister_taxonomy_variation' );

/**
* 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 string $post_type The post type name passed from registered_post_type action hook.
* @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 ) {
function block_core_navigation_link_register_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 );
block_core_navigation_link_register_variation( $variation );
}
}

Expand All @@ -420,9 +448,29 @@ function register_block_core_navigation_link_post_type_variation( $post_type, $p
* @param array $args Array of taxonomy registration arguments.
* @return void
*/
function register_block_core_navigation_link_taxonomy_variation( $taxonomy, $object_type, $args ) {
function block_core_navigation_link_register_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 );
block_core_navigation_link_register_variation( $variation );
}
}

/**
* Unregisters a custom post type variation for navigation link on post type unregistration.
*
* @param string $post_type The post type name passed from unregistered_post_type action hook.
* @return void
*/
function block_core_navigation_link_unregister_post_type_variation( $post_type ) {
block_core_navigation_link_unregister_variation( $post_type );
}

/**
* Unregisters a custom taxonomy variation for navigation link on taxonomy unregistration.
*
* @param string $taxonomy The taxonomy name passed from unregistered_taxonomy action hook.
* @return void
*/
function block_core_navigation_link_unregister_taxonomy_variation( $taxonomy ) {
block_core_navigation_link_unregister_variation( $taxonomy );
}
112 changes: 107 additions & 5 deletions phpunit/blocks/block-navigation-link-variations-test.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* Navigation block rendering tests.
* Navigation block post type/taxonomies variations tests.
*
* @package WordPress
* @subpackage Blocks
Expand All @@ -25,6 +25,17 @@ public function set_up() {
'show_in_nav_menus' => true,
)
);
register_post_type(
'private_custom_book',
array(
'labels' => array(
'item_link' => 'Custom Book',
),
'public' => false,
'show_in_rest' => true,
'show_in_nav_menus' => false,
)
);
register_taxonomy(
'book_type',
'custom_book',
Expand All @@ -35,40 +46,131 @@ public function set_up() {
'show_in_nav_menus' => true,
)
);
register_taxonomy(
'private_book_type',
'private_custom_book',
array(
'labels' => array(
'item_link' => 'Book Type',
),
'show_in_nav_menus' => false,
)
);
}

public function tear_down() {
unregister_post_type( 'custom_book' );
unregister_post_type( 'private_custom_book' );
unregister_taxonomy( 'book_type' );
unregister_taxonomy( 'private_book_type' );
unregister_post_type( 'temp_custom_book' );
unregister_taxonomy( 'temp_book_type' );
parent::tear_down();
}

/**
* @covers ::register_block_core_navigation_link_post_type_variation
* @covers ::block_core_navigation_link_register_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->assertNotEmpty( $nav_link_block->variations, 'Block has no variations' );
$variation = $this->get_variation_by_name( 'custom_book', $nav_link_block->variations );
$this->assertIsArray( $variation, 'Block variation is not an array' );
$this->assertIsArray( $variation, 'Block variation does not exist' );
$this->assertArrayHasKey( 'title', $variation, 'Block variation has no title' );
$this->assertEquals( 'Custom Book', $variation['title'], 'Variation title is different than the post type label' );
}

/**
* @covers ::register_block_core_navigation_link_taxonomy_variation
* @covers ::block_core_navigation_link_register_post_type_variation
*/
public function test_navigation_link_variations_private_custom_post_type() {
$registry = WP_Block_Type_Registry::get_instance();
$nav_link_block = $registry->get_registered( 'core/navigation-link' );
$this->assertNotEmpty( $nav_link_block->variations, 'Block has no variations' );
$variation = $this->get_variation_by_name( 'private_custom_book', $nav_link_block->variations );
$this->assertEmpty( $variation, 'Block variation for private post type exists.' );
}

/**
* @covers ::block_core_navigation_link_register_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->assertNotEmpty( $nav_link_block->variations, 'Block has no variations' );
$variation = $this->get_variation_by_name( 'book_type', $nav_link_block->variations );
$this->assertIsArray( $variation, 'Block variation is not an array' );
$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 post type label' );
}

/**
* @covers ::block_core_navigation_link_register_taxonomy_variation
*/
public function test_navigation_link_variations_private_custom_taxonomy() {
$registry = WP_Block_Type_Registry::get_instance();
$nav_link_block = $registry->get_registered( 'core/navigation-link' );
$this->assertNotEmpty( $nav_link_block->variations, 'Block has no variations' );
$variation = $this->get_variation_by_name( 'private_book_type', $nav_link_block->variations );
$this->assertEmpty( $variation, 'Block variation for private taxonomy exists.' );
}

/**
* @covers ::block_core_navigation_link_unregister_post_type_variation
*/
public function test_navigation_link_variations_unregister_post_type() {
register_post_type(
'temp_custom_book',
array(
'labels' => array(
'item_link' => 'Custom Book',
),
'public' => true,
'show_in_rest' => true,
'show_in_nav_menus' => true,
)
);

$registry = WP_Block_Type_Registry::get_instance();
$nav_link_block = $registry->get_registered( 'core/navigation-link' );
$this->assertNotEmpty( $nav_link_block->variations, 'Block has no variations' );
$variation = $this->get_variation_by_name( 'temp_custom_book', $nav_link_block->variations );
$this->assertIsArray( $variation, 'Block variation does not exist' );

unregister_post_type( 'temp_custom_book' );

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

/**
* @covers ::block_core_navigation_link_unregister_taxonomy_variation
*/
public function test_navigation_link_variations_unregister_taxonomy() {
register_taxonomy(
'temp_book_type',
'custom_book',
array(
'labels' => array(
'item_link' => 'Book Type',
),
'show_in_nav_menus' => true,
)
);

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

unregister_taxonomy( 'temp_book_type' );

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

/**
* Get a variation by its name from an array of variations.
*
Expand Down

0 comments on commit 295ebf5

Please sign in to comment.