` and drops the nested List rendered inside it. Core * still has the inner blocks on the instance, so re-append them after the * binding has been applied. * * This can be removed once the minimum required WordPress version is 7.1. */ /** * Returns whether the list item metadata declares a content binding. * * @since 7.1.0 * * @param mixed $metadata Block metadata attribute. * @return bool Whether a content binding (direct or via pattern overrides) is present. */ function gutenberg_list_item_metadata_has_content_binding( $metadata ) { if ( empty( $metadata['bindings'] ) || ! is_array( $metadata['bindings'] ) ) { return false; } $bindings = $metadata['bindings']; return isset( $bindings['content'] ) || ( isset( $bindings['__default']['source'] ) && 'core/pattern-overrides' === $bindings['__default']['source'] ); } /** * Restores the nested inner blocks dropped when binding a List Item's content. * * Core replaces the whole `
  • ` when it applies the rich-text binding, removing * the nested List. The inner blocks are still available on the instance, so they * are rendered again and re-appended before the closing `
  • `. * * @since 7.1.0 * * @param string $block_content The rendered block content. * @param array $parsed_block The parsed block. * @param WP_Block $instance The block instance. * @return string The block content with the nested inner blocks restored. */ function gutenberg_restore_list_item_inner_blocks_after_binding( $block_content, $parsed_block, $instance ) { if ( 'core/list-item' !== ( $parsed_block['blockName'] ?? null ) ) { return $block_content; } if ( ! $instance instanceof WP_Block || empty( $instance->inner_blocks ) ) { return $block_content; } if ( ! gutenberg_list_item_metadata_has_content_binding( $instance->parsed_block['attrs']['metadata'] ?? null ) ) { return $block_content; } $inner_blocks_html = ''; foreach ( $instance->inner_blocks as $inner_block ) { $inner_blocks_html .= $inner_block->render(); } /* * Nothing to restore when the inner blocks did not render, or when they are * still present because Core already preserves them (the fix is in place). */ if ( '' === $inner_blocks_html || str_contains( $block_content, $inner_blocks_html ) ) { return $block_content; } $closer_position = strripos( $block_content, '' ); if ( false === $closer_position ) { return $block_content; } return substr( $block_content, 0, $closer_position ) . $inner_blocks_html . substr( $block_content, $closer_position ); } add_filter( 'render_block', 'gutenberg_restore_list_item_inner_blocks_after_binding', 10, 3 );