WordPress.org

Make WordPress Core

Opened 5 years ago

Closed 5 years ago

#34477 closed defect (bug) (fixed)

Pass the named image size to the filter in `wp_get_attachment_image_sizes()`

Reported by: joemcgill Owned by: azaozz
Milestone: 4.4 Priority: normal
Severity: normal Version: 4.4
Component: Media Keywords: has-patch
Focuses: Cc:

Description

Prior to #34430, themes could filter the sizes attribute based on the named size (e.g. medium, post-thumbnail, etc). This ability was broken in 35412 because the named sizes are converted to width/height arrays before being passed to wp_get_attachment_image_sizes().

We already have the ability within wp_get_attachment_image_sizes() to convert a named size into the size array so we should pass the named size when possible.

Attachments (3)

34477.patch (1.9 KB) - added by joemcgill 5 years ago.
34477.1.patch (3.0 KB) - added by azaozz 5 years ago.
34477.2.patch (2.9 KB) - added by joemcgill 5 years ago.

Download all attachments as: .zip

Change History (10)

@joemcgill
5 years ago

#1 @joemcgill
5 years ago

  • Owner set to azaozz
  • Status changed from new to assigned

34477.patch Adds the test Tests_Media::test_wp_get_attachment_image_with_sizes_named_filter() which illustrates the issue.

The patch also includes a change that passes the named size to wp_get_attachment_image_sizes() from wp_get_attachment_image() instead of the size array. It does not change the values passed to wp_get_attachment_image_sizes() from wp_image_add_srcset_and_sizes() at this time.

This ticket was mentioned in Slack in #feature-respimg by joemcgill. View the logs.


5 years ago

#3 @azaozz
5 years ago

I'm still somewhat uncomfortable with this change.

To generate the sizes attribute value we need the image width as set in the width attribute (in the tag). All other arguments passed to wp_get_attachment_image_sizes() are purely for use in the filter.

When this function is used in core we know the image width, but we wouldn't use it because a plugin eventually may need the named image size. However in some cases we won't know the image size name, and in some rare cases the width calculated from the name may be different than the actual image width, resulting in wrong sizes value.

Logically we should use the "proper" width that we have, and pass the named image size as an optional argument. I know that brings the number of parameters on that function to 1 required and used, plus 3 optional and not used, but still thinking that's better.

Last edited 5 years ago by azaozz (previous) (diff)

@azaozz
5 years ago

#4 @azaozz
5 years ago

In 34477.1.patch:

  • Add another optional parameter $size_name to wp_get_attachment_image_sizes().
  • Pass it in core when available.

This adds two more preg_match() to the display filter function. The matching is done only on the image tags, which is quite fast as the strings are short. Still wp_image_add_srcset_and_sizes() is a bit slower than before.

Last edited 5 years ago by azaozz (previous) (diff)

#5 follow-up: @joemcgill
5 years ago

After thinking through this some more, in many cases, the sizes attribute can be filtered using the wp_get_attachment_image_attr filter, which already passes the named size.

The only place where that's not possible is when we call wp_get_attachment_image_sizes() in the display filter. In that case, we could pass the file name—which we already have—in order to get the same result without the need to add any new preg_match() calls. 34477.2.patch adds $image_url as an optional param to wp_get_attachment_image_sizes(), which gets passed to the filter.

@joemcgill
5 years ago

#6 in reply to: ↑ 5 @azaozz
5 years ago

Replying to joemcgill:

Yep, that works better. We always know the image URL so this will be consistent. It will be a bit harder for themes/plugins to get the size name, but any regexp will only run when needed, so it is more efficient.

#7 @azaozz
5 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 35481:

Responsive images: add $image_url parameter to wp_get_attachment_image_sizes() and use it in the filter. This allows themes and plugins to identify the image.

Props joemcgill.
Fixes #34477.

Note: See TracTickets for help on using tickets.