Steve Grunwell

Open-source contributor, speaker, and electronics tinkerer

Using Advanced Custom Fields for WordPress

Update 8/30/12: As Sean Butze pointed out in the comments, the $id parameter of grunwell_get_custom_field() should be able to accept strings as well as integers to work with the ACF Options Page add-on. Furthermore, the_repeater_field() has been deprecated since ACF version 3.3.4.

If you regularly build WordPress sites and haven’t tried Elliot Condon’s Advanced Custom Fields plugin, I’d highly recommend checking it out as it will forever change the way you use WordPress.

With Advanced Custom Fields, you can easily define custom field templates for particular post types, page templates, or even individual posts/pages. With the help of some paid add-ons, you can quickly add support for repeaters (useful for carousels/sliders), a site options page (hello Google Analytics profile ID), or any of a dozen other official and third-party add-ons.

Advanced Custom Fields particularly shines when handling WordPress custom post types. If you look at the source of this site, I’m using a custom post type of grunwell_portfolio for all of my portfolio entries. With Advanced Custom Fields I’m able to register metaboxes for client information, agency information, and manage the screenshot carousel from the post edit screen.

Wrapper functions

In order to retrieve ACF data, Elliot has built-in the get_field(), the_repeater_field(), and the_sub_field() functions. They work fine, but since a lot of my projects are client sites that may not always be under my control, it’s important to ensure that if ACF is ever broken or deactivated for any reason the site won’t completely blow up. In order to achieve this, I have a couple wrapper functions that I’ve written and refined over several projects to streamline the process:

Individual custom fields

Since I use ACF so heavily, it’s not really feasible to wrap every call in if ( function_exists( 'get_field' ) ) :. Instead, I wrote this wrapper function:

This makes it simple to access a custom field with key $key, regardless of the current loop’s post ID. With the $default parameter, I can even specify a value to return if the custom field is undefined, null, or the plugin is inactive. In practice, about 90% of the time my $default parameter is a boolean false, which makes it easy to test for a custom field:

I also like to add the following function to prevent having to type echo grunwell_get_custom_field(...) over and over

Repeater content

When dealing with repeater fields, I use the following function:

By running my repeater requests through grunwell_get_repeater_content(), I accomplish three things:

  1. Specify what keys I expect to retrieve (which helps remind me of my field names as I’m iterating over the retrieved content)
  2. Ensure that my page won’t break if ACF is disabled or the repeater add-on is disabled
  3. Most importantly, I eliminate the need to check the type of the returned content. My function will always return an array, which means I’ll never risk passing an invalid data type to a foreach statement.


Let’s say I have a carousel where each slide had the following pieces of data: an image, a caption, and a link. I might create a repeater field named slides with the following sub-fields: slide_image, slide_caption, slide_link where slide_image is an attachment and the other two are text fields. To retrieve this data, my code might look something like this:

Additional resources

Wrapping up

If you haven’t used Advanced Custom Fields yet, I’d suggest looking into it on your next project. It’s really a well-built plugin that receives regular updates and enhancements.

Have you used Advanced Custom Fields on a project? What are some of the cool things you’ve done with it?


Using jScrollPane with jQuery UI Draggable


Using Git Checksums to Invalidate Browser Caches


  1. Really awesome! I’ve got quite a few sites that rely heavily on ACF and these wrapper functions will definitely help put me at ease.

    A couple of suggestions:

    1) get_field() needs to be able to accept IDs in string format to accommodate the Options Panel addon. I changed the conditional on line 17 to:

    if ( isset( $post->ID ) && !$id ) {
    $result = get_field( $key );
    } else {
    $result = get_field( $key, $id );

    And that seemed to do the trick.

    2) the_repeated_field() is depreciated. ACF now uses has_sub_field, get_sub_field & the_sub_field

    Thanks for sharing.

  2. This is sweet. It has always been a concern of mine. You never know what your clients might do when you turn the site over to them!!

  3. am using the_field() in wordpress loop via query_post () on index page. but its now working. only displaying value of field in very last post from loop ? any solution for this?

  4. Lore

    Having an issue where, if I deactivate ACF, I can no longer manually enter a new custom field name on a regular page.

    If you’ve had this issue, would love to see solution expanded.

    • It’s likely that the Custom Fields meta box is just hidden. Locate the “Screen Options” pull-down menu on the post edit screen (it should be in the top right corner just below the admin bar where it says “Howdy, Lore”) and enable the “Custom Fields” checkbox. That should restore the meta box to its usual place.

  5. Bo

    Hi Works great thanks
    But facing an issue with the repeater code example . I have a select box as one of my repeater fields , it does not get both the value and choice ? how would I make that work ?
    Can you check on a fieldtype ?
    so instead of get_sub_field( $field )
    I guess it should be like below for a select: ( just can’t get it working )
    $field = get_field_object(‘field_name’);
    $value = get_field(‘field_name’);
    $label = $field[‘choices’][ $value ];

    Can you help me get this working ?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Be excellent to each other.