-
Notifications
You must be signed in to change notification settings - Fork 109
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
POC - Pass group block alignment context to image block #1704
Changes from all commits
47c6779
894ed57
cf8691a
93d3f08
f1ec64d
2735713
b84d33e
5a9ce37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,6 +84,7 @@ function auto_sizes_filter_image_tag( $content, array $parsed_block, WP_Block $b | |
if ( ! is_string( $content ) ) { | ||
return ''; | ||
} | ||
|
||
$processor = new WP_HTML_Tag_Processor( $content ); | ||
$has_image = $processor->next_tag( array( 'tag_name' => 'IMG' ) ); | ||
|
||
|
@@ -98,12 +99,14 @@ function auto_sizes_filter_image_tag( $content, array $parsed_block, WP_Block $b | |
* @param string $sizes The image sizes attribute value. | ||
* @param string $size The image size data. | ||
*/ | ||
$filter = static function ( $sizes, $size ) use ( $block ) { | ||
$id = $block->attributes['id'] ?? 0; | ||
$alignment = $block->attributes['align'] ?? ''; | ||
$width = $block->attributes['width'] ?? ''; | ||
$filter = static function ( $sizes, $size ) use ( $block, $parsed_block ) { | ||
$id = $block->attributes['id'] ?? 0; | ||
$alignment = $block->attributes['align'] ?? ''; | ||
$width = $block->attributes['width'] ?? ''; | ||
$has_parent_block = isset( $parsed_block['parentLayout'] ); | ||
$ancestor_block_align = $block->context['ancestor_block_align'] ?? ''; | ||
|
||
return auto_sizes_calculate_better_sizes( (int) $id, (string) $size, (string) $alignment, (string) $width ); | ||
return auto_sizes_calculate_better_sizes( (int) $id, (string) $size, (string) $alignment, (string) $width, $has_parent_block, (string) $ancestor_block_align ); | ||
}; | ||
|
||
// Hook this filter early, before default filters are run. | ||
|
@@ -135,50 +138,121 @@ function auto_sizes_filter_image_tag( $content, array $parsed_block, WP_Block $b | |
/** | ||
* Modifies the sizes attribute of an image based on layout context. | ||
* | ||
* @param int $id The image id. | ||
* @param string $size The image size data. | ||
* @param string $align The image alignment. | ||
* @param string $resize_width Resize image width. | ||
* @since n.e.x.t | ||
* | ||
* @param int $id The image id. | ||
* @param string $size The image size data. | ||
* @param string $align The image alignment. | ||
* @param string $resize_width Resize image width. | ||
* @param bool $has_parent_block Check if image block has parent block. | ||
* @param string $ancestor_block_align The ancestor block alignment. | ||
* @return string The sizes attribute value. | ||
*/ | ||
function auto_sizes_calculate_better_sizes( int $id, string $size, string $align, string $resize_width ): string { | ||
$sizes = ''; | ||
function auto_sizes_calculate_better_sizes( int $id, string $size, string $align, string $resize_width, bool $has_parent_block, string $ancestor_block_align ): string { | ||
$image = wp_get_attachment_image_src( $id, $size ); | ||
|
||
if ( false === $image ) { | ||
return $sizes; | ||
return ''; | ||
} | ||
|
||
// Retrieve width from the image tag itself. | ||
$image_width = '' !== $resize_width ? (int) $resize_width : $image[1]; | ||
|
||
if ( $has_parent_block ) { | ||
if ( 'full' === $ancestor_block_align && 'full' === $align ) { | ||
return auto_sizes_get_sizes_by_block_alignments( $align, $image_width, true ); | ||
} elseif ( 'full' !== $ancestor_block_align && 'full' === $align ) { | ||
return auto_sizes_get_sizes_by_block_alignments( $ancestor_block_align, $image_width, true ); | ||
} elseif ( 'full' !== $ancestor_block_align ) { | ||
$parent_block_alignment_width = auto_sizes_get_sizes_by_block_alignments( $ancestor_block_align, $image_width ); | ||
$block_alignment_width = auto_sizes_get_sizes_by_block_alignments( $align, $image_width ); | ||
if ( (int) $parent_block_alignment_width < (int) $block_alignment_width ) { | ||
return sprintf( '(max-width: %1$s) 100vw, %1$s', $parent_block_alignment_width ); | ||
} else { | ||
return sprintf( '(max-width: %1$s) 100vw, %1$s', $block_alignment_width ); | ||
} | ||
} | ||
} | ||
|
||
return auto_sizes_get_sizes_by_block_alignments( $align, $image_width, true ); | ||
} | ||
|
||
/** | ||
* Generates the `sizes` attribute value based on block information. | ||
* | ||
* @since n.e.x.t | ||
* | ||
* @param string $alignment The alignment. | ||
* @param int $image_width The image width. | ||
* @param bool $print_sizes Print the sizes attribute. Default is false. | ||
* @return string The sizes attribute value. | ||
*/ | ||
function auto_sizes_get_sizes_by_block_alignments( string $alignment, int $image_width, bool $print_sizes = false ): string { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand changing the return type based on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initially, I considered separating them, but since the two functions are similar, I combined them into a single function by adding an extra parameter. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to separating them. Using a boolean to change function behavior is a code smell. Ideally a separate function should take the return value of this function and format it, like @joemcgill suggested. |
||
$sizes = ''; | ||
|
||
$layout = wp_get_global_settings( array( 'layout' ) ); | ||
|
||
// Handle different alignment use cases. | ||
switch ( $align ) { | ||
switch ( $alignment ) { | ||
case 'full': | ||
$sizes = '100vw'; | ||
break; | ||
|
||
case 'wide': | ||
if ( array_key_exists( 'wideSize', $layout ) ) { | ||
$sizes = sprintf( '(max-width: %1$s) 100vw, %1$s', $layout['wideSize'] ); | ||
$sizes = $layout['wideSize']; | ||
} | ||
break; | ||
|
||
case 'left': | ||
case 'right': | ||
case 'center': | ||
$sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $image_width ); | ||
$sizes = auto_sizes_get_width( '', $image_width ); | ||
break; | ||
|
||
default: | ||
if ( array_key_exists( 'contentSize', $layout ) ) { | ||
$width = auto_sizes_get_width( $layout['contentSize'], $image_width ); | ||
$sizes = sprintf( '(max-width: %1$s) 100vw, %1$s', $width ); | ||
$sizes = auto_sizes_get_width( $layout['contentSize'], $image_width ); | ||
} | ||
break; | ||
} | ||
|
||
if ( $print_sizes ) { | ||
$sizes = 'full' === $alignment ? $sizes : sprintf( '(max-width: %1$s) 100vw, %1$s', $sizes ); | ||
} | ||
|
||
return $sizes; | ||
} | ||
|
||
/** | ||
* Filters the context keys that a block type uses. | ||
* | ||
* @since n.e.x.t | ||
* | ||
* @param array<string> $uses_context Array of registered uses context for a block type. | ||
mukeshpanchal27 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* @param WP_Block_Type $block_type The full block type object. | ||
* @return array<string> The filtered context keys used by the block type. | ||
*/ | ||
function auto_sizes_allowed_uses_context_for_image_blocks( array $uses_context, WP_Block_Type $block_type ): array { | ||
if ( 'core/image' === $block_type->name ) { | ||
// Use array_values to reset the array keys after merging. | ||
return array_values( array_unique( array_merge( $uses_context, array( 'ancestor_block_align' ) ) ) ); | ||
} | ||
return $uses_context; | ||
} | ||
|
||
/** | ||
* Modifies the block context during rendering to blocks. | ||
* | ||
* @since n.e.x.t | ||
* | ||
* @param array<string, mixed> $context Current block context. | ||
* @param array<string, mixed> $block The block being rendered. | ||
* @return array<string, mixed> Modified block context. | ||
*/ | ||
function auto_sizes_modify_render_block_context( array $context, array $block ): array { | ||
if ( 'core/group' === $block['blockName'] || 'core/columns' === $block['blockName'] ) { | ||
$context['ancestor_block_align'] = $block['attrs']['align'] ?? ''; | ||
} | ||
return $context; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
parentLayout
added in WP 6.6. See https://github.com/WordPress/WordPress/blob/e174cbef2e3b7f1901892cb501f683c6e122231b/wp-includes/block-supports/layout.php#L926-L943.Once we bump the version in #1682 it will fix the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 5a9ce37 i bump the workflow WP version to 6.6