diff --git a/src/wp-includes/class-wp-block-templates-registry.php b/src/wp-includes/class-wp-block-templates-registry.php index 368c517fc9e27..1a1c259dba1dc 100644 --- a/src/wp-includes/class-wp-block-templates-registry.php +++ b/src/wp-includes/class-wp-block-templates-registry.php @@ -50,7 +50,7 @@ public function register( $template_name, $args = array() ) { } elseif ( preg_match( '/[A-Z]+/', $template_name ) ) { $error_message = __( 'Template names must not contain uppercase characters.' ); $error_code = 'template_name_no_uppercase'; - } elseif ( ! preg_match( '/^[a-z0-9-]+\/\/[a-z0-9-]+$/', $template_name ) ) { + } elseif ( ! preg_match( '/^[a-z0-9_\-]+\/\/[a-z0-9_\-]+$/', $template_name ) ) { $error_message = __( 'Template names must contain a namespace prefix. Example: my-plugin//my-custom-template' ); $error_code = 'template_no_prefix'; } elseif ( $this->is_registered( $template_name ) ) { diff --git a/tests/phpunit/tests/block-templates/WpBlockTemplatesRegistry.php b/tests/phpunit/tests/block-templates/WpBlockTemplatesRegistry.php index cc44d265e9dc3..a2b1d16eef618 100644 --- a/tests/phpunit/tests/block-templates/WpBlockTemplatesRegistry.php +++ b/tests/phpunit/tests/block-templates/WpBlockTemplatesRegistry.php @@ -267,4 +267,51 @@ public function test_unregister() { $this->assertEquals( $template, $unregistered_template, 'Unregistered template should be the same as the registered one.' ); $this->assertFalse( self::$registry->is_registered( $template_name ), 'Template should not be registered after unregistering.' ); } + + /** + * Data provider for test_template_name_validation. + * + * @return array[] Test data. + */ + public static function data_template_name_validation() { + return array( + 'valid_simple_name' => array( + 'my-plugin//my-template', + true, + 'Valid template name with simple characters should be accepted', + ), + 'valid_with_underscores' => array( + 'my-plugin//my_template', + true, + 'Template name with underscores should be accepted', + ), + 'valid_cpt_archive' => array( + 'my-plugin//archive-my_post_type', + true, + 'Template name for CPT archive with underscore should be accepted', + ), + ); + } + + /** + * Tests template name validation with various inputs. + * + * @ticket 62523 + * + * @dataProvider data_template_name_validation + * + * @param string $template_name The template name to test. + * @param bool $expected Expected validation result. + * @param string $message Test assertion message. + */ + public function test_template_name_validation( $template_name, $expected, $message ) { + $result = self::$registry->register( $template_name, array() ); + + if ( $expected ) { + self::$registry->unregister( $template_name ); + $this->assertNotWPError( $result, $message ); + } else { + $this->assertWPError( $result, $message ); + } + } }