Tips・WordPress custom fields (ACF / SCF)

ACF field types: a cheat sheet for displaying each one

A cheat sheet of the code that outputs ACF (SCF) fields in your template, organized by field type. Text, image, select, true/false, date, link, post object and more—check what each one returns and how to write it, all in one place.

With ACF (SCF), the shape of what comes back depends on the field type, so the way you write it changes too. This article is a cheat sheet for answering “how do I output this field again?” in a single screen. Scan down and copy just the line you need.

The whole list (what comes back, and the shortest code)

FieldWhat comes backShortest way to write it
Text / TextareaString<?php the_field('name'); ?>
NumberNumber<?php echo number_format((int) get_field('price')); ?>
Rich text (wysiwyg)HTML string<?php the_field('body'); ?>
URLString<a href="<?php the_field('url'); ?>">…</a>
EmailString<a href="mailto:<?php the_field('mail'); ?>">…</a>
ImageID / URL / array (depends on the setting)<?php echo wp_get_attachment_image(get_field('img'), 'large'); ?>
FileID / URL / array (depends on the setting)<a href="<?php echo esc_url($f['url']); ?>"><?php echo esc_html($f['filename']); ?></a>
LinkArray (url, title, target)See “Link” below
Select / RadioString (label or array, depending on the setting)<?php the_field('size'); ?>
CheckboxArray<?php echo esc_html(implode(', ', get_field('tags'))); ?>
True / Falsetrue / false<?php if (get_field('is_new')) : ?>NEW<?php endif; ?>
DateString (Ymd and so on)See “Date” below
ColorString (#ff0000)style="color: <?php the_field('color'); ?>"
Post objectPost object (or ID)See “Post object” below
RelationshipArray of post objectsSee “Relationship” below
TaxonomyTerm object (sometimes an array)<?php echo esc_html($term->name); ?>
UserArray (or user object)<?php echo esc_html($u['display_name']); ?>
GroupAssociative array<?php echo esc_html(get_field('company')['tel']); ?>
RepeaterArray of arrayshave_rows() loop
Flexible contentArray of arrayshave_rows() plus get_row_layout()

Below, real code for just the ones that tend to trip people up.

Image

The way you write it changes with the Return Value setting (ID, URL or array). If you set it to ID, one line gives you a tag complete with alt and srcset.

<?php echo wp_get_attachment_image(get_field('photo'), 'large'); ?>
TipsHow to display images with ACFDetailed code for each return value, plus a fallback image for when the field is empty

File

If you set the return value to an array, you can also show the file name and size.

<?php if ($file = get_field('pdf')) : ?>
  <a href="<?php echo esc_url($file['url']); ?>" download>
    <?php echo esc_html($file['filename']); ?> (<?php echo esc_html(size_format($file['filesize'])); ?>)
  </a>
<?php endif; ?>

size_format() is a WordPress function that turns a byte count into something like “1.2 MB”.

A link field is an array holding three things—url, title and target. It even picks up the “open in a new tab” setting.

<?php $link = get_field('button'); ?>
<?php if ($link) : ?>
  <a class="button" href="<?php echo esc_url($link['url']); ?>"
     target="<?php echo esc_attr($link['target'] ?: '_self'); ?>">
    <?php echo esc_html($link['title']); ?>
  </a>
<?php endif; ?>

?: is shorthand for “if the left side is empty, use the right side” (here it fills in _self when target isn’t set).

Select, radio and checkbox

  • Select and radio—normally a string. Set “Return Value” to Label and you get the text meant for display
  • Checkboxalways an array. Print it directly and you get “Array”
<?php $tags = get_field('features'); ?>
<?php if ($tags) : ?>
  <ul>
    <?php foreach ($tags as $t) : ?>
      <li><?php echo esc_html($t); ?></li>
    <?php endforeach; ?>
  </ul>
<?php endif; ?>

If you set the return value to “Both (Array)”, pull the display name out with $t['label'].

True / False

This is a switch, like “should we show the New badge?” You normally use it for branching rather than printing it.

<?php if (get_field('is_new')) : ?>
  <span class="badge">NEW</span>
<?php endif; ?>

Date

A date field is stored as a string (the default is Ymd, so something like 20260725). To display it nicely, reformat it.

<?php if ($ymd = get_field('event_date')) : ?>
  <?php $d = DateTime::createFromFormat('Ymd', $ymd); ?>
  <time datetime="<?php echo esc_attr($d->format('Y-m-d')); ?>">
    <?php echo esc_html($d->format('F j, Y')); ?>
  </time>
<?php endif; ?>

Post object and relationship

These are fields that let you pick another post, like “articles related to this product.” What comes back is a post object (WP_Post), so you can hand it straight to functions like get_permalink().

<?php $post_obj = get_field('related_post'); ?>
<?php if ($post_obj) : ?>
  <a href="<?php echo esc_url(get_permalink($post_obj)); ?>">
    <?php echo esc_html(get_the_title($post_obj)); ?>
  </a>
<?php endif; ?>

A relationship field lets you pick several, so what comes back is an array.

<?php $items = get_field('related_items'); ?>
<?php if ($items) : ?>
  <ul>
    <?php foreach ($items as $item) : ?>
      <li>
        <a href="<?php echo esc_url(get_permalink($item)); ?>"><?php echo esc_html(get_the_title($item)); ?></a>
      </li>
    <?php endforeach; ?>
  </ul>
<?php endif; ?>
TipsHow to fetch posts outside the loop (WP_Query)Things to watch out for when looping through a separate list of posts

Taxonomy

You get a term object (WP_Term). With multi-select enabled it becomes an array, so either check with is_array() first or confirm the setting.

<?php $term = get_field('genre'); ?>
<?php if ($term) : ?>
  <a href="<?php echo esc_url(get_term_link($term)); ?>"><?php echo esc_html($term->name); ?></a>
<?php endif; ?>
TipsListing categories and terms with get_termsWant to output the list of taxonomy terms itself? Here you go

Escaping cheat sheet

Where you’re printingFunction to use
Text in the bodyesc_html()
Attribute values (alt, class and so on)esc_attr()
URLs for href, src and the likeesc_url()
Rich text (keeping the HTML)the_field() as-is (or wp_kses_post)

the_field() doesn’t escape anything, so when you echo it yourself, follow the table above—it’s the safer habit.

Summary

  1. Each field type returns a different shape—keep the three families in mind: string, array and object
  2. Use the_field() for plain display, and get_field() when you need to test or extract something
  3. Passing an array to the_field() prints “Array”—checkbox, link, group and friends
  4. Dates are strings, so reformat them with DateTime. Pick your escaping function to match where you’re printing

Once you know the shape, the rest is the same pattern over and over. When you’re stuck, one peek with var_dump() clears it up right away.

FAQ

What's the difference between the_field() and get_field()?
the_field() prints the value right there, and get_field() returns the value. Use the_field() when you just want to display a string, and get_field() when you need to test it in an if statement or pull something out of an array.
Which fields come back as arrays?
Image (when the return value is set to array), file, link, checkbox, group, repeater, flexible content, relationship and taxonomy are arrays. If you pass an array to the_field(), it prints "Array".
I want to show the label instead of the value for a select field.
Set the field's "Return Value" to "Label" or "Both (Array)". If you choose the array, you can pull the text out with $v['label'].
I want to change how a date field is displayed.
Take the string from get_field() and pass it to DateTime to reformat it. Write something like $d = DateTime::createFromFormat('Ymd', get_field('date')); echo $d->format('F j, Y'); (check the save format in the field settings).