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

Better navigation link variations for post types / taxonomies #56100

Merged
Merged
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
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
Loading