14 Jul

The Beginner’s Guide to WordPress Custom Fields

By Matt Shaw

You may already be familiar with Advanced Custom Fields, a popular plugin we develop that makes adding custom fields to your WordPress site as easy as clicking a few buttons.

But did you know that WordPress has its own version of custom fields? In this article, I will take a closer look at the WordPress implementation of custom fields, then compare them to the custom fields possible with ACF.

What are WordPress Custom Fields?

To sum it up briefly, custom fields are additional inputs you can add to posts or pages that save the values to the metadata for that post or page.

If you’re at all familiar with WordPress options or other metadata, custom fields will likely seem very familiar to you – it stores the custom fields as key -> value pairs in the wp_postmeta table. That data can then be used in your theme or plugins to render custom content in your theme or perform additional logic based on the field values.

Using Custom Fields

Fortunately, WordPress custom fields are quite simple to use, even with minimal knowledge of PHP and the WordPress database. In this section, I’ll go over how to add custom fields and update existing fields, as well as how to pull them into WordPress themes or plugins.

Enabling Custom Fields

If you haven’t seen the custom field interface before, it’s likely because it’s hidden away from the edit screens by default! If you’re using the classic editor, you can enable the custom fields metabox by editing a post and clicking Screen Options:

Enabling custom fields in Screen Options.

If you’re using the new block editor (also known as Gutenberg), you’ll have to click the three dots at the top of a post or page to open the editor settings and click Preferences. Next, head to the “Panels” section and enable the Custom Fields toggle:

Enabling custom fields in the block editor.

Once enabled, the editor should reload and you’ll now see a custom fields section at the bottom:

The custom fields UI.

If you’ve tried enabling custom fields but aren’t seeing the option for it in the classic editor’s “Screen Options” or the block editor preferences, there are a couple of reasons why that might be happening. The first is if you’re using a custom post type that hasn’t declared support for custom fields. To fix that up, you’ll need to either add custom-fields to the supports array in register_post_type(), or pass custom-fields to the add_post_type_support().

Another reason the custom fields UI might not show up is if you’re using ACF. ACF hides these settings to speed up load times and prevent confusion between the WordPress core custom fields functionality and the ACF custom fields functionality. If you’d like to display the WordPress core custom fields in addition to ACF fields, you can add the following snippet into your theme’s functions.php or in a custom plugin:

add_filter('acf/settings/remove_wp_meta_box', '__return_false');

Adding or Updating Custom Fields

The WordPress custom fields UI is very simple. There’s just a “Name” field (which is also used as the field “key”) and a “Value” field. To get started, enter a name for the custom field. Don’t worry about having to do this every time—your previous field names are saved and will be available via a dropdown the next time you add a custom field.

In this quick tutorial, we’re going to use custom fields to create a basic “Related Posts” section for a post. To do that, you’ll need to add a new custom field with “Related Posts” as the name, and enter a post ID for another post as the value:

Adding a new custom field.

Once you save the page and reload, you can then select from any existing custom fields you have saved. You can even use the same field multiple times, which is helpful if there are multiple related posts you want to attach to a post:

Adding multiple custom fields.

Once you’ve added a few related posts, it’s time to pull that functionality into a theme!

Using Custom Fields in Your Theme

WordPress core has several helpful functions that can be used to get and render custom field values in a theme or plugin. In the example below, we use get_post_meta() to retrieve an array of the related posts and display them at the bottom of a post template.

functions.php

function hellfish_related_posts() {
    $related_post_ids = get_post_meta( get_the_ID(), 'Related Posts' );

    // Bail out early if there are no related posts.
    if ( ! is_array( $related_post_ids ) || empty( $related_post_ids ) ) {
        return;
    }

    // Loop over the posts and render the HTML for the related posts section.
    $related_posts = array();
    foreach ( $related_post_ids as $post_id ) {
        $post_id    = (int) $post_id;
        $permalink  = get_the_permalink( $post_id );
        $post_title = get_the_title( $post_id );
        $thumbnail  = get_the_post_thumbnail( $post_id );

        if ( ! $permalink || !$post_title ) {
            continue;
        }

        $related_posts[] = sprintf(
            '<div class="hfm-related-post">
                <a href="%s">%s%s</a>
            </div>',
            $permalink,
            $thumbnail,
            $post_title
        );
    }

    if ( empty( $related_posts ) ) {
        return;
    }

    printf(
        '<div class="hfm-related-posts>
            <h4>Related Posts</h4>
            %s
        </div>',
        implode( '', $related_posts )
    );
}

The get_post_meta() function will always return an array of metadata if found, or false on failure. So the above function checks if the “Related Posts” custom field has an array of data, and then loops through them to generate the necessary HTML for our related posts functionality. Here’s what that looks like on the frontend after a little CSS magic:

The related posts section created with custom fields.

Querying by Custom Fields

If you need to query a post or page by a field value, you can do so with the WordPress get_posts() function or by using WP_Query directly. With our previous example of related posts in mind, we could use get_posts() like this to get a list of the posts that have one or more of a specific related post:

functions.php

$args = array(
    'meta_key'    => 'Related Posts',
    'meta_value' => array( 17, 19 ),
    'meta_type'   => 'NUMERIC'
);
$posts = get_posts( $args );

By passing in an array of post IDs as the meta_value, we can search for posts that have one or more of those IDs set as a value for our “Related Posts” custom fields. Setting the meta_type to NUMERIC casts any meta values found as numbers so that we know we’re making a proper comparison.

If you’re curious about other ways to use get_posts() for custom fields, I’d recommend checking out the official documentation, as well as the documentation for the WP_Query class which is used internally by get_posts().

Pros and Cons of Custom Fields

The biggest pro and the biggest con for the WordPress implementation of custom fields is actually the same thing – simplicity.

I consider it a pro in this case because it’s incredibly easy to add custom fields to a post or page, and the functions for retrieving those fields are relatively basic. Someone with even a minimal knowledge of PHP can get up and running with WordPress custom fields with only a few trips to the documentation.

On the other hand, just having a simple textarea to use for a field value is quite limiting and potentially error-prone. For example, if you need to use the custom fields to store and retrieve things that are true or false, or selected from a predefined list of options, a textarea may not be the best option. Or you just may need something more advanced, with robust APIs and multiple different types of custom fields.

How ACF Fields Are Different

The Advanced Custom Fields plugin takes the spirit of the custom fields functionality in WordPress core and extends it with over 30 different field types and options for those fields.

It also allows you to organize multiple fields into a “Field Group” – a collection of fields that should display on a location of your choosing.

The ACF field group page.

Within the fields you assign to each field type, there are several settings to further customize each field so you can make sure it works exactly as you need it to. For example, you can have an image field that restricts the available image types and has a min/max file size requirement:

The settings for an ACF image field.

You can also set each field to show up conditionally based on the values of other fields – handy for more complex forms or content:

The ACF conditional logic settings.

To make something like the “Related Posts” functionality with less effort, you could use ACF’s relationship field. This lets you select from existing posts, pages, or custom post types. No more having to manually find and remember the post IDs! You can also tell the relationship field to only select from certain post types or from posts that have a certain taxonomy (i.e., category or tag).

The ACF relationship field.

Once you’ve assigned a field group to a post or page, ACF will take care of adding the metaboxes, saving the data, and formatting the values based on the field type selected. Here’s what the new “Related Posts” panel in the post editor looks like after switching to ACF:

A gif showing how the relationship field is used.

Rendering the related posts in PHP is quite similar to how you would do it with WordPress custom fields, so I won’t bore you with the details. Generally, instead of using get_post_meta() to get the field values, you’d use ACF’s function get_field().

Creating Global Fields With the ACF Options Page

The options page feature in ACF Pro allows you to add extra admin pages to edit ACF fields. Unlike WordPress custom fields, this allows you to create global fields that are not attached to a particular post or page. Instead, the data can be displayed on any page throughout your WordPress site. This makes it ideal for a number of use cases, including header and footer data.

Open your functions.php file and add the line of code below to create an options page:

functions.php

if( function_exists('acf_add_options_page') ) {
    acf_add_options_page();
}

This will add a default options page to the sidebar in your admin area. You can add parameters to customize your new options page. For example, adding the code below to your functions.php will create a customized options page with multiple child pages:

functions.php

if( function_exists('acf_add_options_page') ) {
    
    acf_add_options_page(array(
        'page_title'     => 'Theme General Settings',
        'menu_title'    => 'Theme Settings',
        'menu_slug'     => 'theme-general-settings',
        'capability'    => 'edit_posts',
        'redirect'        => false
    ));
    
    acf_add_options_sub_page(array(
        'page_title'     => 'Theme Header Settings',
        'menu_title'    => 'Header',
        'parent_slug'    => 'theme-general-settings',
    ));
    
    acf_add_options_sub_page(array(
        'page_title'     => 'Theme Footer Settings',
        'menu_title'    => 'Footer',
        'parent_slug'    => 'theme-general-settings',
    ));
    
}

All API functions can be used with the option page’s fields, but a second parameter is required to target the options page. This is explored in-depth here.

Using ACF Advanced Field Types

Aside from the relationship field, ACF has a variety of field types that range from a basic checkbox field all the way to more advanced field types like the Repeater field and the Google Map field. These fields can also be inserted into custom blocks or displayed in the WordPress REST API, so the possibilities with ACF are almost endless.

We’ll look at the Repeater field as an example. This is an extremely useful field, as it provides a low-effort solution for repeating content types such as slides, team member bios, or any other data that you want to render in your theme multiple times.

This is because the Repeater field acts as a parent to a set of sub-fields which can be replicated as many times as necessary. Any type of field can be used within a Repeater field:

The settings for an ACF repeater.

When editing a post, you’ll then be able to add multiple rows containing those fields. This is similar to how you can add multiple rows of the same WordPress custom field, except you can do it with multiple fields at once!

Editing a page with a repeater field.

Summary

WordPress custom fields are a useful tool for adding some custom (if relatively basic) functionality to your website. Even being an avid ACF user, I’d still at least consider using the core custom fields if I only needed a basic text field in a few pages. But with anything more than that, I’d have no trouble letting ACF handle the job.

Have you ever used the WordPress custom fields on your websites? If so, would you ever use them again? Let us know in the comments.

About the Author