Skip to content

Instantly share code, notes, and snippets.

@digiltd
Last active February 4, 2016 01:22
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digiltd/12ccb9429ebf01cd99d3 to your computer and use it in GitHub Desktop.
Save digiltd/12ccb9429ebf01cd99d3 to your computer and use it in GitHub Desktop.
Advanced Custom Fields - Repeater using image fields

ACF Repeater using image fields

This gist is to accompany my comment on Mark's article:

[Build modular content systems in WordPress] (http://www.creativebloq.com/web-design/build-modular-content-systems-wordpress-41514680) by Mark Llobrera

Which if you haven't read (or just stumbled upon this gist by chance) then I highly recomend you do.

It demonstrates some key concepts on how you can use ACF to build your clients mini page builders. By doing so you can avoid all the bloat that the big page builder type plugins use. You will also build up your own mini library of elements that you can reuse depending on the project.

There is nothing wrong with the article, and image objects are perfectly fine.

But I wanted to highlight the difference, so you can be aware why they are not always the best option, certainly when using lots of images in a repeater.

I learned this from experience. Using the image array object all over the place. That data quickly builds up and realistically you only needed one or two attributes anyway.

It is better to just use the id and then use core WordPress functions to get the bits you need.

Below is what is returned when you return an image object

array(18) {
  ["ID"]=>
  int(530)
  ["id"]=>
  int(530)
  ["title"]=>
  string(23) "il_570xN.750608409_tb6f"
  ["filename"]=>
  string(27) "il_570xN.750608409_tb6f.jpg"
  ["url"]=>
  string(73) "http://www.tll01.dev/wp-content/uploads/2014/11/il_570xN.750608409_tb6f.jpg"
  ["alt"]=>
  string(0) ""
  ["author"]=>
  string(1) "1"
  ["description"]=>
  string(0) ""
  ["caption"]=>
  string(0) ""
  ["name"]=>
  string(23) "il_570xn-750608409_tb6f"
  ["date"]=>
  string(19) "2015-04-12 20:32:16"
  ["modified"]=>
  string(19) "2015-04-12 20:32:16"
  ["mime_type"]=>
  string(10) "image/jpeg"
  ["type"]=>
  string(5) "image"
  ["icon"]=>
  string(65) "http://www.tll01.dev/wordpress/wp-includes/images/media/default.png"
  ["width"]=>
  int(570)
  ["height"]=>
  int(661)
  ["sizes"]=>
  array(21) {
    ["thumbnail"]=>
    string(81) "http://www.tll01.dev/wp-content/uploads/2014/11/il_570xN.750608409_tb6f-150x150.jpg"
    ["thumbnail-width"]=>
    int(150)
    ["thumbnail-height"]=>
    int(150)
    ["medium"]=>
    string(81) "http://www.tll01.dev/wp-content/uploads/2014/11/il_570xN.750608409_tb6f-259x300.jpg"
    ["medium-width"]=>
    int(259)
    ["medium-height"]=>
    int(300)
    ["large"]=>
    string(73) "http://www.tll01.dev/wp-content/uploads/2014/11/il_570xN.750608409_tb6f.jpg"
    ["large-width"]=>
    int(570)
    ["large-height"]=>
    int(661)
    ["shop_thumbnail"]=>
    string(81) "http://www.tll01.dev/wp-content/uploads/2014/11/il_570xN.750608409_tb6f-200x150.jpg"
    ["shop_thumbnail-width"]=>
    int(200)
    ["shop_thumbnail-height"]=>
    int(150)
    ["shop_catalog"]=>
    string(81) "http://www.tll01.dev/wp-content/uploads/2014/11/il_570xN.750608409_tb6f-300x300.jpg"
    ["shop_catalog-width"]=>
    int(300)
    ["shop_catalog-height"]=>
    int(300)
    ["shop_single"]=>
    string(81) "http://www.tll01.dev/wp-content/uploads/2014/11/il_570xN.750608409_tb6f-570x576.jpg"
    ["shop_single-width"]=>
    int(570)
    ["shop_single-height"]=>
    int(576)
    ["swatches_image_size"]=>
    string(79) "http://www.tll01.dev/wp-content/uploads/2014/11/il_570xN.750608409_tb6f-32x32.jpg"
    ["swatches_image_size-width"]=>
    int(32)
    ["swatches_image_size-height"]=>
    int(32)
  }
}

All that is from one image.

Note that it will use all the extra thumbnail sizes you have defined, or in this case WooCommerce and a Swatches plugin have also defined.

When you return just the id you get:

int(531)

You can see that when you have multiple images, there is going to be a lot of data being retrieved and stored and it will effect performance. It might also throw up errors due to max memory(depending on your server).

In theory you could just return the url if you wanted the be super efficient. Though I am not that sure that a 4 part array converted to a single var would make any noticable difference. Plus if you did ever want to get the width or height, you would have to use jQuery or some PHP lib to analyse the dimensions of the image becasue you only have the url to work with.

Life is too short to worry about such things. But you can see why you might want to worry about not return object or arrays when using ACF.


In this example I am using [wp_get_attachment_image_src()] (https://codex.wordpress.org/Function_Reference/wp_get_attachment_image_src) with the image ID and the size I want.

<?php $slide_src = wp_get_attachment_image_src( $slide_id, $size ); ?>

You could also use [wp_get_attachment_url()] (https://codex.wordpress.org/Function_Reference/wp_get_attachment_url)

<?php $slide_url = wp_get_attachment_url( $id ); ?>

As well as many other wp_get_... functions that you should familiarise yourself with (see the related functions section at the bottom of the two links)

Have fun

<?php
/**
* The template file for the homepage.
*
* Template Name: Homepage
*
*/
get_header();
/**
* Using ACF custom fields with this structure
*
* 'slides' (repeater)
*
* With these sub fields:
*
* 'slide_title' (text)
* 'slide_intro' (text area)
* 'slide_image' (image)
*
* The image field is set to return only the image ID and not the whole object (sizes, captions, titles, urls)
*
* See the readme to see the differences.
*
* The markup I am using is for a slider using the excellent [Flickity] (http://flickity.metafizzy.co/)
*
* You would mark it up for your own needs
*
*/
if ( have_rows( 'slides' ) ) {
echo '<div class="m-slider js-flickity" data-flickity-options=\'{ "prevNextButtons": true, "pageDots": true }\'>';
while ( have_rows( 'slides' ) ) {
the_row();
// get id
$slide_id = get_sub_field( 'slide_image' );
// define size (thumbnail, medium, large, full or whatever custom sizes you have set in WordPress)
$size = 'large';
/**
* Get the attributes of the required image using wp_get_attachment_image_src
*
* It returns an array
* (url, width, height), or false, if no image is available.
*
*/
$slide_src = wp_get_attachment_image_src( $slide_id, $size );
/**
* Use the data from the array as you need it.
*
* In the example below I only want to use the image as a background image with a bit of inline css
* meaning that I only need the url. So I could have skipped splitting the array into
* seperate variables and instead just use
*
* echo '<div class="m-slider__panel" style="background-image: url('. $slide_src[0] .')">';
*
* I seperated them out to help visualise what is going on a bit more.
*
*/
$slide_url = $slide_src[0];
$slide_width = $slide_src[1];
$slide_height = $slide_src[2];
echo '<div class="m-slider__panel" style="background-image: url('. $slide_url .')">';
echo '<div class="m-slider__contents">';
the_sub_field( 'slide_title' );
the_sub_field( 'slide_intro' );
echo '</div>';
echo '</div>';
}
echo '</div>';
}
get_footer(); ?>
@eblosch
Copy link

eblosch commented Jan 20, 2016

Great advice. Came across a good article by Bill Erickson (http://www.billerickson.net/advanced-custom-fields-frontend-dependency/) on the merits of get_post_meta vs. the_field / the_sub_field. Worth a read.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment