Gutenberg javascript get media srcset

Viewed 2458

In WordPress it is easy to get an images srcset and sizes as saved in WordPress using the wp_get_attachment_image_srcset function. I need to have that functionality on the block-editors side in javascript / react. Is that possible?

What I expect is a function that accepts a media id and returns the srcset somehow. If that is not possible, how could I implement a rest api endpoint for doing that? Or is there another way to pipe the function values from php to js?

For some reasons which are not relevant here, I cannot use dynamic php blocks.

4 Answers

I've share my solution here because I've see this post by searshing a solution for a similar problem : I was looking for a solution to get the srcset attribute and the complete generated 'img' tag but from the 'media' object returned by MediaReplaceFlow component (not only by attachment ID). It's probably adaptable to your problem by getting the media object with wp.data.select( 'core').getMedia(media_id).

This media object already contain a 'sizes' array with URL of image in some image sizes. but it's not sufficient because it's hard to build srcset ans size attribute for image tag. So, after many research, I've found a very helpfull php filter : wp_prepare_attachment_for_js

so with this filter, I've writed this PHP code :

function imageTagForJs( $response, $attachment ) {
    foreach ( $response['sizes'] as $size => $datas ) {
      $response['sizes'][$size]['tag']    = wp_get_attachment_image( $attachment->ID, $size );
      $response['sizes'][$size]['srcset'] = wp_get_attachment_image_srcset( $attachment->ID, $size );
    }
    return $response;
  }
add_filter( 'wp_prepare_attachment_for_js', 'imageTagForJs', 10, 2 );

Now, in the 'media' JS object, each sizes get two new properties : tag and srcset. I can now get my img tag in js by simply using media.sizes.medium.tag.

Important : By default, media.sizes array contain only builtin image sizes (thumbnail, medium, etc) but not custom image sizes. You can simply add custom sizes by using image_size_names_choose filter.

You can create an AJAX request that will be calling the wp_get_attachment_image_srcset on an attachment ID and return the result.

This example uses jQuery from the default "Twenty Seventeen" theme

Inside the child theme functions.php we define the AJAX WP method:

add_action("wp_ajax_get_attachment_image_srcset", "get_attachment_image_srcset");
add_action("wp_ajax_nopriv_get_attachment_image_srcset", "get_attachment_image_srcset");

function get_attachment_image_srcset() {

  // Get attachment ID from the request
  $attachment_id = $_REQUEST['attachment_id'];

  // Get attachment srcset
  $srcset = wp_get_attachment_image_srcset($attachment_id);

  // Return JSON with the srcset and the attachment_id
  wp_send_json([
    'srcset' => $srcset,
    'attachment_id' => $attachment_id
  ]);
}

Inside Block Editor, you can add a custom HTML block using AJAX to fetch the attachment srcset using an attachment ID.

Block Editor custom HTML code block:

jQuery(function($) {

  // On a button click
  $('.get-srcset a').on('click', function() {

    // Get the value of a text input to pass as attachment ID
    let attachmentId = $('#attachmentid').val();

    // Make the AJAX call
    jQuery.ajax({
      type : "post",
      dataType : "json",
      url : '/wp-admin/admin-ajax.php',
      data : {
        action: "get_attachment_image_srcset",
        attachment_id : attachmentId
      },
      success: function(response) {
        // If we got an srcset
        if(response.srcset) {
          // Update the result element text with trhe srcset value or use srcset
          $('#result').text(response.srcset);
        }
        else {
          alert("No srcset")
        }
      }
    });
  });

});

This will update the #result element text to something like this:

https://wp.lytrax.net/wp-content/uploads/2020/04/3_ser_conv07-300x225.jpg 300w, 
https://wp.lytrax.net/wp-content/uploads/2020/04/3_ser_conv07-768x576.jpg 768w, 
https://wp.lytrax.net/wp-content/uploads/2020/04/3_ser_conv07.jpg 832w

You can check this working on this demo WP site: https://wp.lytrax.net/test-attachment-srcset/ (Valid attachment IDs are 5, 6, 7, 8, 9, 10)

TO get the featured image first you need featured image id and then pass it to the getmedia function to get the media object. after getting media object you can get relevant items from the object.

const featuredImageId = wp.data.select( 'core/editor' )
.getEditedPostAttribute( 'featured_media' );

const media = featuredImageId 
? wp.data.select( 'core').getMedia( featuredImageId ) 
: null;

console.log(media);
Related