ResponsiveImagesCG / wp-tevko-responsive-images

Fully responsive image plugin for wordpress
449 stars 53 forks source link

Use custom sizes attribute with the_post_thumbnail #268

Closed fr-olivier closed 8 years ago

fr-olivier commented 8 years ago

Hello,

I'm really excited about responsive images being merged into the WordPress core, and I've been testing it this morning. It's hard to find real documentation about it as I've seen many times "No configuration is needed" and I hope I'm at the right place to ask questions. So. I've used the_post_thumbnail() on a page but the rendered image is the full size one. Sure I could pass a custom size, like the_post_thumbnail('medium'), but then I have no control over the sizes attribute. Is there a way to pass custom sizes attributes to the_post_thumbnail()? Without having to manually rewrite all the output.

Thanks a lot for your work!

jaspermdegroot commented 8 years ago

Hi @fr-olivier

The documentation of this plugin also applies to WordPress core 4.4 since the code is the same.

So. I've used the_post_thumbnail() on a page but the rendered image is the full size one.

This happens when your theme doesn't set a post thumbnail size with set_post_thumbnail_size(). If you do set it, the image size 'post-thumbnail' will be used.

Sure I could pass a custom size, like the_post_thumbnail('medium'), but then I have no control over the sizes attribute.

I do not understand what you mean. What image size do you want to use? Why does passing a specific image size makes you have no control over the sizes attribute?

In case of post thumbnails the srcset and sizes attributes are added by wp_get_attachment_image(). You can use the wp_get_attachment_image_attributes hook to set a custom sizes attribute. Be aware that this filter also applies to gallery images, not only post thumbnails. The image size will be passed as variable to your filter function so if you use image size 'post-thumbnail' for your post thumbnails you can make your function only override the sizes attribute when the image size is 'post-thumbnail'.

You could also use the wp_calculate_image_sizes hook which filters the output of wp_calculate_image_sizes(). This filter applies to both images in the content and post thumbnails (and gallery images). Again the image size is one of the variables that will be passed to your filter function, but in this case it will be an array of width and height values (not the image size name).

I hope this helps.

fr-olivier commented 8 years ago

Hello @jaspermdegroot,

Thanks a lot for your quick reply. Obviously I'm only scratching the surface here, I'm not familiar with the hooks and filters you're talking about but I get the picture if I can say so ;)

So. I've used the_post_thumbnail() on a page but the rendered image is the full size one.

This happens when your theme doesn't set a post thumbnail size with set_post_thumbnail_size(). If you do set it, the image size 'post-thumbnail' will be used.

What I have now:

  function remove_default_image_sizes( $sizes) {
    unset( $sizes['thumbnail']);
    unset( $sizes['medium']);
    unset( $sizes['large']);

    return $sizes;
  }
  add_filter('intermediate_image_sizes_advanced', 'remove_default_image_sizes');

  add_image_size('xs', 51, '', false);
  add_image_size('sm', 167, '', false);
  add_image_size('md', 300, '', false);
  add_image_size('lg', 400, '', false);

So as you suggest, I should do

set_post_thumbnail_size('300');

but what if my Featured image has to be 300px wide on regular pages but 600px on a specific template or custom post?

Thanks again for your help.

jaspermdegroot commented 8 years ago

Hi @fr-olivier

I just realized that when you call the_post_thumbnail() you can pass attributes as second parameter. So you don't have to use a filter.

Here is a code example. Removing the default image sizes like you did is not relevant so I left that code out of my example.

In your functions.php:

// Set image size 'post-thumbnail'.
set_post_thumbnail_size(300,9999, false);

// Set custom image sizes.
add_image_size('xs', 51, 9999, false);
add_image_size('sm', 167, 9999, false);
add_image_size('md', 300, 9999, false);
add_image_size('lg', 400, 9999, false);
add_image_size('lg-thumbnail', 600, 9999, false);

// Make custom image sizes available in the editor to insert them in the content.
function my_custom_sizes( $sizes ) {
    return array_merge( $sizes, array(
        'xs' => __('Extra small'),
        'sm' => __('Small'),
        'md' => __('Medium'),
        'lg' => __('Large'),
    ) );
}
add_filter( 'image_size_names_choose', 'my_custom_sizes' );

In your template file:

$attr_md = array(
    'sizes' => '(max-width: 300px) 100vw, 300px' ),
);
the_post_thumbnail( 'post-thumbnail', $attr_md );

$attr_lg = array(
    'sizes' => '(max-width: 600px) 100vw, 600px' ),
);
the_post_thumbnail( 'lg-thumbnail', $attr_lg );

Just to give you an idea how the filter works I will also show an example of that.

Add to your functions.php:

// Filter the sizes attribute of post thumbnails.
function my_attachment_image_attributes( $attr, $attachment, $size ) {
    if ( $size === 'post-thumbnail' ) {
        $attr['sizes'] = '(max-width: 300px) 100vw, 300px';
    } elseif ( $size === 'lg-thumbnail' ) {
        $attr['sizes'] = '(max-width: 600px) 100vw, 600px';
    }
    return $attr;
}
add_filter( 'wp_get_attachment_image_attributes', 'my_attachment_image_attributes', 10, 3 );

In your template file:

// If you don't pass an image size, 'post-thumbnail' will be used
// if it has been set with `set_post_thumbnail_size()`.
the_post_thumbnail();

the_post_thumbnail( 'lg-thumbnail' );

I am going to close this ticket, but let me know in a comment if something is still not clear.

marcosmyara commented 8 years ago

@jaspermdegroot could you paste exactly what the output of that the_post_thumbnail() would be like?

Because, I'm assuming it will output an img tag with width and heigh attributes included, is that right? where does that come in? are these attributes supposed to be there even if the size of the image will be variable? and how can I test which image from the srcset was the one that was rendered in the browser once i load the page?

jaspermdegroot commented 8 years ago

@marcosmyara

Yes, the_post_thumbnail() outputs an img element with height and width attributes, and now also with srcset and sizes attributes (if more than one image source with same aspect ratio is available).

where does that come in? are these attributes supposed to be there even if the size of the image will be variable?

The height and width attributes are styles for the image element. The srcset and sizes attributes are about what source to load in that image element. Those are different things.

and how can I test which image from the srcset was the one that was rendered in the browser once i load the page?

Use the dev tools of your browser. In Chrome for example right click on the image and in the code inspector hover over the URLs in the img element. You'll see it shows "currentSrc". Or go to the network tab in the code inspector and see which image is downloaded.