Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Extent the_post_thumbnail() function with a third parameter WordPress

  • SOLVED

Tldr;

Modify the_post_thumbnail() function to allow for parameters to be added to the end of the image URL.

Details

By default the_post_thumbnail() accepts two parameters:

1. Size (string|array)
2. Attributes (string|array)

(https://developer.wordpress.org/reference/functions/the_post_thumbnail/)

I need a third one:

3. Parameters (string|array)

The parameters would be appended to the end of the image URL, just like this example:
https://demo.gumlet.com/lemon.jpeg?mode=fill&fill=solid&width=500&height=500&fill-color=c0c0c0&format=auto


Practical example:

This function:


the_post_thumbnail_extended(
array(
'mode' => 'fill',
'fill' => 'solid',
'w' => '300',
'h' => '200',
),
array(
300,
200
),
array(
'class' => 'my-image'
),
);



Would output:

<img src="https://www.example.com/wp-content/uploads/post-thumbnail.jpg?mode=fill&fill=solid&w=300&h=200" class="my-image wp-post-image" alt="alt text" width="300" height="200">

Answers (4)

2020-06-30

John Cotton answers:

You can modify the image src using a filter:


function filter_image_attributes( $attr, $attachment, $size ) {
$attr['src'] .= '?mode=fill&fill=solid&w=300&h=200';
return $attr;
}
add_filter( 'wp_get_attachment_image_attributes', 'filter_image_attributes', 10, 3 );


Since you're also getting the attachment details (a WP Post) and the size (eg 'post-thumbnail'), you could put conditions in there to act how/when you need.

If you only need this one-off, consider an in-line function immediately prior to the the_post_thumbnail() call, like this:


$params = ['mode' => 'mode', 'fill' => 'solid', 'w' => 300, 'h' => 200];

add_filter( 'wp_get_attachment_image_attributes', function ( $attr, $attachment, $size ) use ( $params ) {
$attr['src'] .= sprintf( '?mode=%s&fill=%s&w=%d&h=%d', $params['mode'], $params['fill'], $params['w'], $params['h'] );
return $attr;
}, 10, 3 );

the_post_thumbnail();


moonshotmedia comments:

Thank you, this is great, I didn't know this option existed.

The only issue is that when I use this function with a conditional, all other featured images that don't meet the condition are now missing the src-attribute.

Code:

function filter_image_attributes( $attr, $attachment, $size ) {
if ( is_post_type_archive( 'my_post_type' ) ) {
$attr['src'] .= '?w=300&h=200&mode=crop&crop=smart';
return $attr;
}
}
add_filter( 'wp_get_attachment_image_attributes', 'filter_image_attributes', 10, 3 );


The images on the post-type archive page now show the correct markup, including the "src" with attributes.

However on all other posts/pages/archives the image "src" is now missing, so no featured images are displayed.

Do you have an idea what could be happening?


John Cotton comments:

You need to return $attr regardless of whether you change it or not (that's how filters work in WP).

So:

function filter_image_attributes( $attr, $attachment, $size ) {
if ( is_post_type_archive( 'my_post_type' ) ) {
$attr['src'] .= '?w=300&h=200&mode=crop&crop=smart';
}
// Outside the if statement
return $attr;
}
add_filter( 'wp_get_attachment_image_attributes', 'filter_image_attributes', 10, 3 );

2020-06-30

Arnav Joy answers:

or you can use following all functions.
function the_post_thumbnail_extended( $aj_args, $size = 'post-thumbnail', $attr = '' ) {
echo get_the_post_thumbnail_extended( $aj_args, null, $size, $attr );
}

function get_the_post_thumbnail_extended( $aj_args, $post = null, $size = 'post-thumbnail', $attr = '' ) {
$post = get_post( $post );
if ( ! $post ) {
return '';
}
$post_thumbnail_id = get_post_thumbnail_id( $post );


$size = apply_filters( 'post_thumbnail_size', $size, $post->ID );

if ( $post_thumbnail_id ) {


do_action( 'begin_fetch_post_thumbnail_html', $post->ID, $post_thumbnail_id, $size );
if ( in_the_loop() ) {
update_post_thumbnail_cache();
}
$html = wp_get_attachment_image_extended( $aj_args, $post_thumbnail_id, $size, false, $attr );


do_action( 'end_fetch_post_thumbnail_html', $post->ID, $post_thumbnail_id, $size );

} else {
$html = '';
}

return apply_filters( 'post_thumbnail_html', $html, $post->ID, $post_thumbnail_id, $size, $attr );
}



function wp_get_attachment_image_extended( $aj_args, $attachment_id, $size = 'thumbnail', $icon = false, $attr = '' ) {
$html = '';
$image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
if ( $image ) {
list( $src, $width, $height ) = $image;
$hwstring = image_hwstring( $width, $height );
$size_class = $size;
if ( is_array( $size_class ) ) {
$size_class = join( 'x', $size_class );
}
$attachment = get_post( $attachment_id );

$src = $src.'?mode='.$aj_args['mode'].'&fill='.$aj_args['fill'].'&w='.$aj_args['w'].'&h='.$aj_args['h'];


$default_attr = array(
'src' => $src,
'class' => "attachment-$size_class size-$size_class",
'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
);


$attr = wp_parse_args( $attr, $default_attr );

// Generate 'srcset' and 'sizes' if not already present.
if ( empty( $attr['srcset'] ) ) {
$image_meta = wp_get_attachment_metadata( $attachment_id );

if ( is_array( $image_meta ) ) {
$size_array = array( absint( $width ), absint( $height ) );
$srcset = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id );
$sizes = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id );

if ( $srcset && ( $sizes || ! empty( $attr['sizes'] ) ) ) {
$attr['srcset'] = $srcset;

if ( empty( $attr['sizes'] ) ) {
$attr['sizes'] = $sizes;
}
}
}
}


$attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment, $size );
$attr = array_map( 'esc_attr', $attr );
$html = rtrim( "<img $hwstring" );
foreach ( $attr as $name => $value ) {
$html .= " $name=" . '"' . $value . '"';
}
$html .= ' />';
}

return $html;
}

2020-06-30

Reigel Gallarde answers:

Please try this, it's the same with the_post_thumbnail but added third parameter to accept arrays of attribute for the image src.

function the_post_thumbnail_extended( $size = 'post-thumbnail', $attr = '', $params = array() ) {

$thumbnail = get_the_post_thumbnail( $size, $attr ); // get the thumbnail

if (empty($params)) echo $thumbnail; // return the thumbnail if $params is empty

$thumbnail_src = get_the_post_thumbnail_url( $size ); // get the image url for this thumbnail

$thumbnail_src_new = add_query_arg( $params, $thumbnail_src ); // create a new url by adding $params to the url of the image

echo str_replace($thumbnail_src, $thumbnail_src_new, $thumbnail); // replace the old url with the new one.
}


Reigel Gallarde comments:

Function references:

https://developer.wordpress.org/reference/functions/get_the_post_thumbnail/
https://developer.wordpress.org/reference/functions/get_the_post_thumbnail_url/
https://developer.wordpress.org/reference/functions/add_query_arg/

2020-06-30

Monit Jadhav answers:

I tried Arnav's code it works, great job Arnav.

But if the third parameter is left blank you can get these warnings showing on the frontend.

Warning: Illegal string offset 'mode' in

Warning: Illegal string offset 'fill' in

Warning: Illegal string offset 'w' in

Warning: Illegal string offset 'h' in

this happened on line number 48, So Here I suggest a correction that checks if the array is not empty


if(!empty($aj_args)){



if(!empty($aj_args)){

$imgquery = '?';
$counter = 0;
// More flexible way to build the image query

foreach($aj_args as $key=>$value){

$imgquery.=$key;
$imgquery.='=';
$imgquery.=$value;
// Removes the last & sign
if( $counter != count( $aj_args ) - 1) {
$imgquery .= '&';
}
$counter++;
}
print_r($imgquery);

//Old code $src = $src.'?mode='.$aj_args['mode'].'&fill='.$aj_args['fill'].'&w='.$aj_args['w'].'&h='.$aj_args['h'];

$src = $src.$imgquery

}


Also another issue with the solution is that the query was hard coded, so if the third array has more elements they wont render in the query to counter that I did the loop that goes through the third array paramenter and builds a query which then can be added to the image source.


foreach($aj_args as $key=>$value){

$imgquery.=$key;
$imgquery.='=';
$imgquery.=$value;
// Removes the last & sign
if( $counter != count( $aj_args ) - 1) {
$imgquery .= '&';
}
$counter++;
}
print_r($imgquery);

//Old code $src = $src.'?mode='.$aj_args['mode'].'&fill='.$aj_args['fill'].'&w='.$aj_args['w'].'&h='.$aj_args['h'];

$src = $src.$imgquery



Arnav's Code

function wp_get_attachment_image_extended( $aj_args, $attachment_id, $size = 'thumbnail', $icon = false, $attr = '' ) {
$html = '';
$image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
if ( $image ) {
list( $src, $width, $height ) = $image;
$hwstring = image_hwstring( $width, $height );
$size_class = $size;
if ( is_array( $size_class ) ) {
$size_class = join( 'x', $size_class );
}
$attachment = get_post( $attachment_id );

Corrections that remove the offset warnings and also abstracts the third argument and builds the image query

if(!empty($aj_args)){

$imgquery = '?';
$counter = 0;
// More flexible way to build the image query

foreach($aj_args as $key=>$value){

$imgquery.=$key;
$imgquery.='=';
$imgquery.=$value;
// Removes the last & sign
if( $counter != count( $aj_args ) - 1) {
$imgquery .= '&';
}
$counter++;
}

//Arnav's code $src = $src.'?mode='.$aj_args['mode'].'&fill='.$aj_args['fill'].'&w='.$aj_args['w'].'&h='.$aj_args['h'];

// New $src with abstracted $imagequery

$src = $src.$imgquery

}



$default_attr = array(
'src' => $src,
'class' => "attachment-$size_class size-$size_class",
'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
);


$attr = wp_parse_args( $attr, $default_attr );

// Generate 'srcset' and 'sizes' if not already present.
if ( empty( $attr['srcset'] ) ) {
$image_meta = wp_get_attachment_metadata( $attachment_id );

if ( is_array( $image_meta ) ) {
$size_array = array( absint( $width ), absint( $height ) );
$srcset = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id );
$sizes = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id );

if ( $srcset && ( $sizes || ! empty( $attr['sizes'] ) ) ) {
$attr['srcset'] = $srcset;

if ( empty( $attr['sizes'] ) ) {
$attr['sizes'] = $sizes;
}
}
}
}


$attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment, $size );
$attr = array_map( 'esc_attr', $attr );
$html = rtrim( "<img $hwstring" );
foreach ( $attr as $name => $value ) {
$html .= " $name=" . '"' . $value . '"';
}
$html .= ' />';
}

return $html;
}