diff --git a/src/wp-includes/global-styles-and-settings.php b/src/wp-includes/global-styles-and-settings.php index 1ca81d4f0827c..21c37ed9411ee 100644 --- a/src/wp-includes/global-styles-and-settings.php +++ b/src/wp-includes/global-styles-and-settings.php @@ -243,6 +243,38 @@ function wp_get_global_stylesheet( $types = array() ) { return $stylesheet; } +/** + * Generate the stylesheet handle for a block. + * + * @since 6.9.0 + * @access private + * + * Examples: + * - 'core/paragraph' → 'wp-block-paragraph' + * - 'paragraph' → 'wp-block-paragraph' (implicit core) + * - 'my-plugin/custom-block' → 'wp-block-my-plugin-custom-block' + * - '' → null (invalid) + * + * @param string $block_name The block name. + * @return string|null The stylesheet handle or null if invalid. + */ +function wp_generate_block_stylesheet_handle( $block_name ) { + if ( ! is_string( $block_name ) || empty( $block_name ) ) { + return null; + } + + // Handle implicit core namespace (e.g., "paragraph" → "core/paragraph"). + if ( ! str_contains( $block_name, '/' ) ) { + $block_name = "core/{$block_name}"; + } + + // Strip core/ prefix and convert remaining slashes to dashes. + $block_name = str_replace( 'core/', '', $block_name ); + $handle = str_replace( '/', '-', $block_name ); + + return "wp-block-{$handle}"; +} + /** * Adds global style rules to the inline style for each block. * @@ -312,18 +344,25 @@ function wp_add_global_styles_for_blocks() { * Block-specific global styles should be attached to the global-styles handle, but * only for blocks on the page, thus we check if the block's handle is in the queue * before adding the inline style. - * This conditional loading only applies to core blocks. - * TODO: Explore how this could be expanded to third-party blocks as well. + * This conditional loading applies to both core and third-party blocks. */ if ( isset( $metadata['name'] ) ) { - if ( str_starts_with( $metadata['name'], 'core/' ) ) { - $block_name = str_replace( 'core/', '', $metadata['name'] ); - $block_handle = 'wp-block-' . $block_name; - if ( in_array( $block_handle, $wp_styles->queue, true ) ) { + $block_handle = wp_generate_block_stylesheet_handle( $metadata['name'] ); + + if ( $block_handle && in_array( $block_handle, $wp_styles->queue, true ) ) { + wp_add_inline_style( $stylesheet_handle, $block_css ); + } elseif ( ! $block_handle ) { + // Fallback for blocks with unexpected naming patterns. + wp_add_inline_style( $stylesheet_handle, $block_css ); + } else { + /* + * For third-party blocks, load styles if the block handle was generated successfully + * but not found in queue. This maintains backward compatibility where third-party + * block styles were always loaded. + */ + if ( ! str_starts_with( $metadata['name'], 'core/' ) ) { wp_add_inline_style( $stylesheet_handle, $block_css ); } - } else { - wp_add_inline_style( $stylesheet_handle, $block_css ); } } @@ -331,14 +370,22 @@ function wp_add_global_styles_for_blocks() { if ( ! isset( $metadata['name'] ) && ! empty( $metadata['path'] ) ) { $block_name = wp_get_block_name_from_theme_json_path( $metadata['path'] ); if ( $block_name ) { - if ( str_starts_with( $block_name, 'core/' ) ) { - $block_name = str_replace( 'core/', '', $block_name ); - $block_handle = 'wp-block-' . $block_name; - if ( in_array( $block_handle, $wp_styles->queue, true ) ) { + $block_handle = wp_generate_block_stylesheet_handle( $block_name ); + + if ( $block_handle && in_array( $block_handle, $wp_styles->queue, true ) ) { + wp_add_inline_style( $stylesheet_handle, $block_css ); + } elseif ( ! $block_handle ) { + // Fallback for blocks with unexpected naming patterns. + wp_add_inline_style( $stylesheet_handle, $block_css ); + } else { + /* + * For third-party blocks, load styles if the block handle was generated successfully + * but not found in queue. This maintains backward compatibility where third-party + * block styles were always loaded. + */ + if ( ! str_starts_with( $block_name, 'core/' ) ) { wp_add_inline_style( $stylesheet_handle, $block_css ); } - } else { - wp_add_inline_style( $stylesheet_handle, $block_css ); } } }