From d9353eb78a76e305a301a285865dff5e3878b18f Mon Sep 17 00:00:00 2001 From: Developer Ravi Date: Tue, 21 Apr 2026 23:59:58 +0545 Subject: [PATCH] Enhanced Responsive Images: Account for Gallery and grid layouts in sizes calculation --- .../includes/improve-calculate-sizes.php | 87 ++++++++++++++++++- .../tests/test-improve-calculate-sizes.php | 65 +++++++++++++- 2 files changed, 147 insertions(+), 5 deletions(-) diff --git a/plugins/auto-sizes/includes/improve-calculate-sizes.php b/plugins/auto-sizes/includes/improve-calculate-sizes.php index 027f4d1013..4133b53f81 100644 --- a/plugins/auto-sizes/includes/improve-calculate-sizes.php +++ b/plugins/auto-sizes/includes/improve-calculate-sizes.php @@ -313,7 +313,8 @@ function auto_sizes_filter_uses_context( array $uses_context, WP_Block_Type $blo 'core/cover' => array( 'max_alignment', 'container_relative_width' ), 'core/image' => array( 'max_alignment', 'container_relative_width' ), 'core/post-featured-image' => array( 'max_alignment', 'container_relative_width' ), - 'core/group' => array( 'max_alignment' ), + 'core/gallery' => array( 'max_alignment', 'column_count', 'container_relative_width' ), + 'core/group' => array( 'max_alignment', 'column_count', 'container_relative_width' ), 'core/columns' => array( 'max_alignment', 'column_count', 'container_relative_width' ), 'core/column' => array( 'max_alignment' ), ); @@ -325,6 +326,75 @@ function auto_sizes_filter_uses_context( array $uses_context, WP_Block_Type $blo return $uses_context; } +/** + * Gets the number of equal-width columns for a layout block. + * + * @since n.e.x.t + * + * @param array $block The parsed block. + * @return int The number of columns, or 0 if the block does not constrain child widths equally. + */ +function auto_sizes_get_layout_block_column_count( array $block ): int { + $inner_block_count = isset( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ? count( $block['innerBlocks'] ) : 0; + + if ( 'core/columns' === $block['blockName'] ) { + return $inner_block_count; + } + + if ( 'core/gallery' === $block['blockName'] ) { + $column_count = isset( $block['attrs']['columns'] ) ? (int) $block['attrs']['columns'] : 0; + + return $column_count > 0 ? $column_count : $inner_block_count; + } + + if ( + 'core/group' === $block['blockName'] && + isset( $block['attrs']['layout']['type'] ) && + 'grid' === $block['attrs']['layout']['type'] + ) { + $column_count = isset( $block['attrs']['layout']['columnCount'] ) ? (int) $block['attrs']['layout']['columnCount'] : 0; + + return $column_count > 0 ? $column_count : $inner_block_count; + } + + return 0; +} + +/** + * Inherits equal-width layout constraints from a parent block. + * + * @since n.e.x.t + * + * @param array $context Current block context. + * @param WP_Block $parent_block Parent block instance. + * @return array Modified block context. + */ +function auto_sizes_inherit_parent_layout_width( array $context, WP_Block $parent_block ): array { + $column_count = isset( $parent_block->context['column_count'] ) ? (int) $parent_block->context['column_count'] : 0; + + if ( 0 === $column_count && is_array( $parent_block->parsed_block ) ) { + $column_count = auto_sizes_get_layout_block_column_count( $parent_block->parsed_block ); + } + + if ( $column_count <= 0 ) { + return $context; + } + + $current_width = 1.0 / $column_count; + + if ( + isset( $parent_block->context['container_relative_width'] ) && + ( $current_width > 0.0 || + $current_width < 1.0 ) + ) { + $context['container_relative_width'] = $parent_block->context['container_relative_width'] * $current_width; + } else { + $context['container_relative_width'] = $current_width; + } + + return $context; +} + /** * Modifies the block context during rendering to blocks. * @@ -341,6 +411,7 @@ function auto_sizes_filter_render_block_context( array $context, array $block, ? // The list of blocks that can modify outer layout context. $provider_blocks = array( + 'core/gallery', 'core/columns', 'core/group', 'core/post-featured-image', @@ -355,9 +426,10 @@ function auto_sizes_filter_render_block_context( array $context, array $block, ? $context['max_alignment'] = $constraints[ $context['max_alignment'] ] > $constraints[ $alignment ] ? $context['max_alignment'] : $alignment; } - if ( 'core/columns' === $block['blockName'] ) { - // This is a special context key just to pass to the child 'core/column' block. - $context['column_count'] = count( $block['innerBlocks'] ); + $column_count = auto_sizes_get_layout_block_column_count( $block ); + if ( $column_count > 0 ) { + // This context value is used to calculate equal-width child layouts. + $context['column_count'] = $column_count; } if ( 'core/column' === $block['blockName'] ) { @@ -386,6 +458,13 @@ function auto_sizes_filter_render_block_context( array $context, array $block, ? } } } + + if ( + null !== $parent_block && + in_array( $block['blockName'], array( 'core/cover', 'core/image', 'core/post-featured-image' ), true ) + ) { + $context = auto_sizes_inherit_parent_layout_width( $context, $parent_block ); + } return $context; } diff --git a/plugins/auto-sizes/tests/test-improve-calculate-sizes.php b/plugins/auto-sizes/tests/test-improve-calculate-sizes.php index 3971efb8b7..064177fbea 100644 --- a/plugins/auto-sizes/tests/test-improve-calculate-sizes.php +++ b/plugins/auto-sizes/tests/test-improve-calculate-sizes.php @@ -1359,6 +1359,52 @@ public function test_image_block_in_three_column_layout_renders_correct_sizes_at $this->assertStringContainsString( 'sizes="(max-width: 206px) 100vw, 206px" ', $result ); } + /** + * Test that the image block in a gallery layout renders the correct sizes attribute. + * + * @cover ::auto_sizes_filter_image_tag + * @cover ::auto_sizes_filter_render_block_context + * @cover ::auto_sizes_get_layout_block_column_count + * @cover ::auto_sizes_inherit_parent_layout_width + */ + public function test_image_block_in_gallery_layout_renders_correct_sizes_attribute(): void { + $block_content = $this->get_gallery_block_markup( + $this->get_image_block_markup( self::$image_id, 'large' ) . + $this->get_image_block_markup( self::$image_id, 'large' ) . + $this->get_image_block_markup( self::$image_id, 'large' ) + ); + + $result = apply_filters( 'the_content', $block_content ); + + $this->assertStringContainsString( 'sizes="(max-width: 206px) 100vw, 206px" ', $result ); + } + + /** + * Test that the image block in a grid group layout renders the correct sizes attribute. + * + * @cover ::auto_sizes_filter_image_tag + * @cover ::auto_sizes_filter_render_block_context + * @cover ::auto_sizes_get_layout_block_column_count + * @cover ::auto_sizes_inherit_parent_layout_width + */ + public function test_image_block_in_group_grid_layout_renders_correct_sizes_attribute(): void { + $block_content = $this->get_group_block_markup( + $this->get_image_block_markup( self::$image_id, 'large' ) . + $this->get_image_block_markup( self::$image_id, 'large' ) . + $this->get_image_block_markup( self::$image_id, 'large' ), + array( + 'layout' => array( + 'type' => 'grid', + 'columnCount' => 3, + ), + ) + ); + + $result = apply_filters( 'the_content', $block_content ); + + $this->assertStringContainsString( 'sizes="(max-width: 206px) 100vw, 206px" ', $result ); + } + /** * Verifies that the post featured image block does not render when no featured image is set for the post. */ @@ -1562,7 +1608,7 @@ public function get_group_block_markup( string $content, array $atts = array() ) ) ); - $align_class = (bool) $atts['align'] ? ' align' . $atts['align'] : ''; + $align_class = isset( $atts['align'] ) && '' !== $atts['align'] ? ' align' . $atts['align'] : ''; return '
' . $content . '
@@ -1623,4 +1669,21 @@ public function get_columns_block_markup( string $content, array $atts = array() $column_block ); } + + /** + * Helper to generate gallery block markup. + * + * @param string $content Block content. + * @param array $atts Optional. Block attributes. Default empty array. + * @return string Gallery block markup. + */ + public function get_gallery_block_markup( string $content, array $atts = array() ): string { + $column_count = isset( $atts['columns'] ) ? (int) $atts['columns'] : 0; + $columns = $column_count > 0 ? ' columns-' . $column_count : ' columns-default'; + $attrs = array() !== $atts ? ' ' . wp_json_encode( $atts ) : ''; + + return ' + + '; + } }