Make WordPress Core

Opened 21 months ago

Last modified 20 months ago

#54192 new defect (bug)

`get_header_image_tag` doesn't add `srcset`/`sizes`

Reported by: strarsis's profile strarsis Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: General Keywords: reporter-feedback
Focuses: Cc:

Description

Currently the get_header_image_tag method (and all other methods calling it like the_custom_header_markup and get_custom_header_markup) outputs an <img> without srcset and sizes attributes.

This is important for header images that are normally quite large.

The custom header image method doesn't use the normal WordPress wp_get_attachment_image method for outputting the actual <img>, instead it constructs the <img> markup with its own code.

Related issue: https://core.trac.wordpress.org/ticket/46134#comment:6

Change History (8)

#1 follow-up: @joyously
21 months ago

The srcset and sizes are added later, for all the images that have a wp-image-* class. The image id is needed to do the lookup for the data to use.

#2 in reply to: ↑ 1 @strarsis
21 months ago

Replying to joyously:

The srcset and sizes are added later, for all the images that have a wp-image-* class. The image id is needed to do the lookup for the data to use.

How are these attributes added later? Does WordPress parse the HTML and add them directly?
The function uses a filter, but it doesn't seem to be used elsewhere as the srcset and sizes attributes are missing.
https://github.com/WordPress/WordPress/blob/07139653b9f1b8b1cc88195b971e96597fbc8b10/wp-includes/theme.php#L1200

Last edited 21 months ago by strarsis (previous) (diff)

#3 follow-up: @joyously
21 months ago

Let me amend my statement. For post content, the srcset and sizes are added later, by wp_filter_content_tags().
The get_header_image_tag() function adds the attributes itself, just below where you referenced. Does your test case meet the condition?
if ( empty( $attr['srcset'] ) && ! empty( $header->attachment_id ) )

#4 in reply to: ↑ 3 ; follow-up: @strarsis
21 months ago

Replying to joyously:

Let me amend my statement. For post content, the srcset and sizes are added later, by wp_filter_content_tags().
The get_header_image_tag() function adds the attributes itself, just below where you referenced. Does your test case meet the condition?
if ( empty( $attr['srcset'] ) && ! empty( $header->attachment_id ) )

Good point. The test case would meet the condition, as $attr doesn't contain srcset and by default srcset is not added to $attr.

This ticket was mentioned in Slack in #core-test by hellofromtonya. View the logs.


20 months ago

#6 in reply to: ↑ 4 ; follow-up: @hellofromTonya
20 months ago

  • Keywords reporter-feedback added

Hello @strarsis,

Welcome back to Core's Trac! Thank you for the ticket.

Replying to strarsis:

Good point. The test case would meet the condition, as $attr doesn't contain srcset and by default srcset is not added to $attr.

Does this resolve the ticket and your test case? Or is it still not generating the srcset and size?

If the problem remains, check the _wp_attachment_metadata for the attachment (see the code on about L1226). Is it an array? If no, then the generation is skipped.

If it is an array and the generation is not happening, please share step-by-step instructions including any code or attachments for contributors to reproduce the problem. This type of information helps contributors to investigate.

Last edited 20 months ago by hellofromTonya (previous) (diff)

#7 in reply to: ↑ 6 @strarsis
20 months ago

Replying to hellofromTonya:

Hello @strarsis,

Welcome back to Core's Trac! Thank you for the ticket.

Replying to strarsis:

Good point. The test case would meet the condition, as $attr doesn't contain srcset and by default srcset is not added to $attr.

Does this resolve the ticket and your test case? Or is it still not generating the srcset and size?

If the problem remains, check the _wp_attachment_metadata for the attachment (see the code on about L1226). Is it an array? If no, then the generation is skipped.

If it is an array and the generation is not happening, please share step-by-step instructions including any code or attachments for contributors to reproduce the problem. This type of information helps contributors to investigate.

I prepared a minimal sample theme that demonstrates the issue:
https://github.com/strarsis/wp-test-theme-customheader-srcsetsizes

When a custom header image is specified, the default WordPress functions output an <img element without the srcset and sizes attributes.

#8 @strarsis
20 months ago

Currently I have to use the following code to add srcset/sizes to the generated custom header image:

<?php
function get_attachment_id_by_rel_url($url) {
    $url_abs    = home_url($url);
    $attachment = attachment_url_to_postid($url_abs);
    return $attachment;
}

add_filter('get_header_image_tag', function ($default_html, $header_obj, $attr) {
    $header_image_src = $attr['src'];
    $header_image_attachment_id = get_attachment_id_by_rel_url($header_image_src);

    $header_image_html = wp_get_attachment_image(
        $header_image_attachment_id,
        'header-image',
        false,
        $attr,
    );

    return $header_image_html;
}, 5, 3);

Note that as the passed header object doesn't contain the actual custom image src (this may be a plugin issue and unrelated to this issue), I have to determine the attachment ID by using its URL.

Last edited 20 months ago by strarsis (previous) (diff)
Note: See TracTickets for help on using tickets.