6

I'm using ACF to output images in an image carousel called Flickity. Flickity supports image srcset with lazy loading.

Here's my basic ACF markup which uses wp_get_attachment_image:

<?php
  $image = get_field('image');
  $size = 'gallery';
  echo wp_get_attachment_image( $image, $size );
?>

This nicely outputs on the front end, like so:

<img
  width="1164"
  height="450"
  src="image-1164x450.jpg"
  srcset="
          image.jpg 1164w,
          image-300x116.jpg 300w,
          image-768x297.jpg 768w,
          image-1024x396.jpg 1024w,
          image-2328x900.jpg 2328w,
          image-1680x649.jpg 1680w,
          image.jpg 3492w
        "
  sizes="(max-width: 1164px) 100vw, 1164px"
>

Flickity Docs specify that you should use data-flickity-lazyload-srcset and data-flickity-lazyload-src. This means changing the output on wp_get_attachment_image.

I've achieved this via functions.php, like so (source):

function gs_change_attachment_image_markup($attributes){

    if (isset($attributes['src'])) {
        $attributes['data-flickity-lazyload-src'] = $attributes['src'];
        $attributes['src']      = '';
    }

    if (isset($attributes['srcset'])) {
        $attributes['data-flickity-lazyload-srcset'] = $attributes['srcset'];
        $attributes['srcset'] = '';
    }

    return $attributes;
}

add_filter( 'wp_get_attachment_image_attributes', 'gs_change_attachment_image_markup' );

This has worked perfectly on the frontend, like so:

<img
  width="1164"
  height="450"
  srcset=""
  data-flickity-lazyload-src="image-1164x450.jpg"
  data-flickity-lazyload-srcset="
          image.jpg 1164w,
          image-300x116.jpg 300w,
          image-768x297.jpg 768w,
          image-1024x396.jpg 1024w,
          image-2328x900.jpg 2328w,
          image-1680x649.jpg 1680w,
          image.jpg 3492w
        "
  sizes="(max-width: 1164px) 100vw, 1164px"
>

Unfortunately, this breaks the images on other custom or native fields using wp_get_attachment_image.

Is it possible to assign gs_change_attachment_image_markup function to a specific custom field so it's not being applied site wide?

1 Answer 1

8

You won't be really able to tell which context the image is being used in in the wp_get_attachment_image_attributes filter, but you can pass custom attributes to wp_get_attachment_image() in the template directly with the 4th argument. Then you can use wp_get_attachment_image_url() and wp_get_attachment_image_srcset() to get the values for those attributes:

$image = get_field('image');
$size = 'gallery';

echo wp_get_attachment_image( $image, $size, false, array(
    'src' => '',
    'srcset' => '',
    'data-flickity-lazyload-src' => wp_get_attachment_image_url( $image, $size ),
    'data-flickity-lazyload-srcset' => wp_get_attachment_image_srcset( $image, $size ),
) );
6
  • Thank you, but this breaks WooCommerce: Notice: Uninitialized string offset: 0 in /Applications/MAMP/htdocs/project/wp-content/plugins/woocommerce/includes/wc-product-functions.php on line 446. Any ideas?
    – Sam
    Jun 4, 2018 at 8:11
  • 1
    That doesn’t make sense. This code wouldn’t effect anything in WooCommerce. This would be caused by your original filter removing the src attribute. Jun 4, 2018 at 9:30
  • I've removed the original filter. I think it has something to do with the empty src and srcset values. Adding 'src' =>'/' and 'srcset' => '/' removes the error.
    – Sam
    Jun 4, 2018 at 9:38
  • Yeah your right sorry. The affected WooCommerce function was a filter applies to all images. It expects them to all have a src attribute. Jun 4, 2018 at 10:12
  • The little hack I've used should do the trick :) Thanks for your help, you don't know how long I've spent on this!
    – Sam
    Jun 4, 2018 at 10:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.