Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions plugins/webp-uploads/hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,9 @@ function webp_uploads_img_tag_update_mime_type( string $original_image, string $
* @return string The updated HTML markup.
*/
function webp_uploads_update_featured_image( string $html, int $post_id, int $attachment_id ): string {
if ( webp_uploads_is_picture_element_enabled() ) {
return webp_uploads_wrap_image_in_picture( $html, 'post_thumbnail_html', $attachment_id );
}
return webp_uploads_img_tag_update_mime_type( $html, 'post_thumbnail_html', $attachment_id );
}
add_filter( 'post_thumbnail_html', 'webp_uploads_update_featured_image', 10, 3 );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, right now we are using the post_thumbnail_html filter for the featured image, but we could use the wp_get_attachment_image filter as the bug reporter suggested. However, this filter would also include any image echoed using the wp_get_attachment_image() function, which is used for featured images and is also typically used by other plugins. So, I'm not sure whether the Modern Image Formats plugin should also handle those images.

@adamsilverstein what do you think about this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets avoid altering other plugin output for now, the unexpected change could break things or cause conflicts.

Expand Down
2 changes: 1 addition & 1 deletion plugins/webp-uploads/picture-element.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* @return string The new image tag.
*/
function webp_uploads_wrap_image_in_picture( string $image, string $context, int $attachment_id ): string {
if ( 'the_content' !== $context ) {
if ( ! in_array( $context, array( 'the_content', 'post_thumbnail_html', 'widget_block_content' ), true ) ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned #2178 (comment), I also added widget_block_content for testing the widgets. From my testing, adding widget_block_content as a context solves the issue for widgets. Should this be handled in a separate PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind see #2179 (comment).

Copy link
Member

@adamsilverstein adamsilverstein Sep 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably, since its a separate issue entirely!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha! Cross path. Its fine to include in a single PR since the changes are tiny and its a bunch of extra work to add additional Issue and PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I’ll update this PR then.

return $image;
}

Expand Down
40 changes: 40 additions & 0 deletions plugins/webp-uploads/tests/test-load.php
Original file line number Diff line number Diff line change
Expand Up @@ -1268,4 +1268,44 @@ static function () {
);
$this->assertSameSets( $file, webp_uploads_convert_palette_png_to_truecolor( $file ) );
}

/**
* Test that the webp_uploads_update_featured_image function is hooked to the post_thumbnail_html filter.
*
* @covers ::webp_uploads_update_featured_image
*/
public function test_webp_uploads_update_featured_image_hooked_into_post_thumbnail_html(): void {
$this->assertSame( 10, has_filter( 'post_thumbnail_html', 'webp_uploads_update_featured_image' ) );
}

/**
* Test that the featured image is not wrapped in a picture element.
*
* @covers ::webp_uploads_update_featured_image
*/
public function test_webp_uploads_update_featured_image_picture_element_disabled(): void {
$attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/data/images/car.jpeg' );
$post_id = self::factory()->post->create();
set_post_thumbnail( $post_id, $attachment_id );

$featured_image = get_the_post_thumbnail( $post_id );
$this->assertStringStartsWith( '<img ', $featured_image );
}

/**
* Test that the featured image is wrapped in a picture element.
*
* @covers ::webp_uploads_update_featured_image
*/
public function test_webp_uploads_update_featured_image_picture_element_enabled(): void {
update_option( 'perflab_generate_webp_and_jpeg', '1' );
$this->opt_in_to_picture_element();

$attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/data/images/car.jpeg' );
$post_id = self::factory()->post->create();
set_post_thumbnail( $post_id, $attachment_id );

$featured_image = get_the_post_thumbnail( $post_id );
$this->assertStringStartsWith( '<picture ', $featured_image );
}
}
58 changes: 58 additions & 0 deletions plugins/webp-uploads/tests/test-picture-element.php
Original file line number Diff line number Diff line change
Expand Up @@ -526,4 +526,62 @@ public function test_wrap_image_in_picture_with_false_image_src(): void {

$this->assertSame( $image, $filtered_image );
}

/**
* Test that images are not wrapped in picture element for unsupported contexts.
*
* @dataProvider data_provider_webp_uploads_wrap_image_in_picture_with_different_context
*
* @param string $context The context to test.
* @param bool $expected Whether the image should be wrapped in a picture element.
*/
public function test_webp_uploads_wrap_image_in_picture_with_different_context( string $context, bool $expected ): void {
$image = wp_get_attachment_image(
self::$image_id,
'large',
false,
array(
'class' => 'wp-image-' . self::$image_id,
'alt' => 'Green Leaves',
)
);

$this->opt_in_to_picture_element();
$filtered_image = apply_filters( 'wp_content_img_tag', $image, $context, self::$image_id );
if ( $expected ) {
$this->assertStringStartsWith( '<picture', $filtered_image );
} else {
$this->assertSame( $image, $filtered_image );
}
}

/**
* Data provider for test_webp_uploads_wrap_image_in_picture_with_different_context.
*
* @return array<string, array{ context: string, expected: bool }>
*/
public function data_provider_webp_uploads_wrap_image_in_picture_with_different_context(): array {
return array(
'the_content' =>
array(
'context' => 'the_content',
'expected' => true,
),
'post_thumbnail_html' =>
array(
'context' => 'post_thumbnail_html',
'expected' => true,
),
'widget_block_content' =>
array(
'context' => 'widget_block_content',
'expected' => true,
),
'invalid_context' =>
array(
'context' => 'invalid_context',
'expected' => false,
),
);
}
}
Loading