WPLake > Learning Hub > ACF Relationship Field: Complete Guide with Code Snippets

ACF Relationship Field: Complete Guide with Code Snippets

Discover how the ACF Relationship field enhances linking content in WordPress, offering flexible display options, and supporting dynamic queries.

Key Points at a Glance

  1. About the ACF Relationship field: It allows you to link posts, pages, or custom post types, creating meaningful content connections within your WordPress site.
  2. Field settings: The field offers filters by Post Type, Post Status, and Taxonomy, along with options to enable or disable search, filtering, and order selection.
  3. Flexibility: Supports single or multiple selections, allowing various relationship types like one-to-one or many-to-many, making it versatile for different content scenarios.
  4. Bidirectional Relationships: This feature enables automatic reciprocal connections between related items, like linking employees to companies and vice versa.
  5. Display Methods: The field’s values can be displayed as lists, grids, or sliders, depending on the desired presentation style.
  6. Querying Related Content: You can query items based on the ACF Relationship field values, allowing you to dynamically retrieve and display related content across your site.

Table of Contents

The ACF Relationship field, part of the Advanced Custom Fields plugin and classified under the Relational group, is a powerful tool for linking various types of content. This field enables you to establish meaningful connections between posts, pages, or custom post types, enhancing the way content is interrelated within your WordPress site.

Bridging content with ease

Imagine managing a portfolio website where artists and their artworks are handled separately. Using the Relationship field, you can seamlessly connect each artwork to its respective artist. This linkage creates a coherent and interconnected display of your content, making it easy for visitors to navigate between artists and their creations.

Similarly, in an e-commerce setup with WooCommerce, the Relationship field can be used to associate products with relevant companies or managers. This functionality allows for a more organized presentation of information, connecting products to the entities responsible for them.

Flexibility and control

Field settings of the ACF Relationship field include Filters by Post Type, Post Status, and Taxonomy.
Field settings of the ACF Relationship include Filters by Post Type, Post Status, and Taxonomy.

One of the standout features of the ACF Relationship field is its flexibility. Editors can choose between single or multiple selections, allowing them to connect a post or page to one or more related items. This versatility supports various scenarios, from simple one-to-one relationships to complex one-to-many connections.

Organizing and filtering content

ACF Relationship field. Editors can easily find and attach the target posts using the search input and filters.
Editors can easily find and attach the target items using the search input and filters.

To ensure that your content is displayed in an orderly fashion, the ACF Relationship field provides options for ordering and filtering. You can arrange related content by dragging and dropping within the selection area, setting a logical sequence that reflects your desired presentation. Additionally, the filtering option helps narrow down the list of available content, making it easier to find and link relevant items.

Note: It's worth noting that the ACF Relationship field is not designed for use with taxonomies. If you need to link content with taxonomies, such as categories or tags, you should use the ACF Taxonomy field instead.

ACF Relationship field-related addons

ACF addons can be an important part of the workflow, and there are several addons especially useful for the ACF Relationship field:

  • ACF to Custom Database Tables is an add-on for Advanced Custom Fields that saves your custom field data in a dedicated, structured database table, improving organization and performance.
  • ACF Quick Edit Fields enhances the WordPress admin experience by adding Quick Edit functionality to Advanced Custom Fields. This plugin allows you to quickly view and edit ACF field values directly from the list views.
  • ACF Tooltip enhances the user experience by managing lengthy instruction texts in ACF fields. Instead of cluttering the edit screen, this plugin allows you to add tooltips to field labels, keeping the interface clean and space-efficient.
  • WPGraphQL for ACF allows you to expose ACF fields and field groups to GraphQL, enabling seamless querying of ACF data within your GraphQL queries.

Relationship fields in other meta-field plugins

If you're exploring alternatives to ACF, consider that the Relationship field in ACF is similar to features in other plugins. For example, the Meta Box Relationships feature and MB Post field offer comparable functionality, as does the Pods Relationship field.

To gain a deeper understanding of how these options stack up against each other, check out our detailed meta-field plugin comparison. This guide will help you navigate the differences and select the best tool for your needs.

1. ACF Relationship field essentials

1.1) Field settings

In addition to the standard field settings such as the field name and label, the ACF Relationship field offers several specific settings:

General tab

  1. Filter By:
    This section includes default filters that narrow down the list of posts available in the relationship field. These filters include Post Type, Post Status, and Taxonomy. They are predefined and cannot be modified by editors, ensuring consistency in the types of content displayed.
  2. Filters:
    This setting allows you to enable or disable additional filters for editors. Options include:
    Search: Adds a search box to help editors quickly locate specific posts.
    Post Type: Allows editors to filter posts by type, such as posts, pages, or custom post types.
    Taxonomy: Enables filtering by taxonomies like categories or tags.
    When enabled, these filters can streamline the process of finding and selecting related content for content editors.

Validation tab

  1. Minimum Posts:
    Set a minimum number of posts that must be selected. This ensures that users select at least a certain amount of related content.
  2. Maximum Posts:
    Set a maximum limit on the number of posts that can be selected. This helps control the number of items linked and prevents overload.

Presentation tab

  1. Featured Image:
    Toggle this option to display the featured image of the selected posts in the relationship field. When enabled, this provides a visual representation of the related content, enhancing the user interface and making it easier to identify items at a glance.

Advanced tab

  1. Bidirectional:
    This setting allows you to create a two-way relationship between posts. When enabled, selecting a post in one relationship field will automatically create a corresponding link in the related post’s relationship field. This is useful for maintaining reciprocal connections between content pieces, such as linking a project to its related team members and vice versa. We'll review this feature in detail in a short time.

1.2) Storage format and supported field locations

The ACF Relationship field stores its selected choices as a serialized array of post IDs. For example, a serialized array might look like this:

a:2:{i:0;s:1:"1";i:1;s:4:"1131";}

This array indicates that two posts are selected, with IDs 1 and 1131.

ACF Relationship value in the DB
Serialized IDs are stored in the metadata.

If you're new to WordPress, you might be curious about how this system interacts with various content types such as Pages, Custom Post Types (CPTs), WooCommerce products, and others. Here's how it works:

In WordPress, all content types, including standard posts, pages, custom post types, and even WooCommerce products, are stored in the same wp_posts table in the database. The key differentiator between these types is stored in the post_type column of this table.

Since everything is stored in the same table, the IDs used by the ACF Relationship field are universal across content types. Regardless of whether a post ID refers to a page, a custom post type, or a WooCommerce product, the ID itself is a unique identifier that ACF uses to link and retrieve content.

Supported field locations

You can use the ACF Relationship field in various contexts, and it consistently stores the selected post IDs regardless of where you apply the field:

  1. Post Objects (Post, Page, Media Attachment, CPT Item, WooCommerce Product):
    The IDs selected in the ACF Relationship field are stored in the wp_postmeta table, associated with the relevant post or custom post type item.
  2. Options page
    The ACF Relationship field can be used on an ACF Options Page. In this context, the selected post IDs are stored in the wp_options table. This makes the related content accessible as a global site-wide setting, useful for consistent references across the entire site.
  3. User profiles
    When the Relationship field is added to user profiles, the selected post IDs are saved in the wp_usermeta table. This links the related content to the specific user profile, allowing for user-specific content relationships.
  4. Terms (e.g. Post Categories)
    For terms like post categories, tags, or custom taxonomies, the ACF Relationship field can be attached, with selected post IDs stored in the wp_termmeta table. This associates the related content with specific terms, enhancing taxonomy-based content organization.
  5. ACF Gutenberg block
    When used within an ACF Gutenberg Block, the Relationship field’s selected post IDs are stored within the post_content of the wp_posts table as part of the block’s JSON data structure. This integrates the related content into the block’s content, ensuring that the relationships are preserved within the block.

1.3) Return value formats

The ACF Relationship field always returns an array of items, even if only one item is selected. The format of these items, however, is determined by the Return Value setting, which specifies how the data is returned when using the ACF get_field() function. The available formats are:

  1. Post object
    When this option is selected, each item in the returned array is a WP_Post instance. This provides access to all post properties and methods, allowing you to interact with the posts directly.
  2. Post id
    With this setting, the return value consists of an array of post IDs. Each ID corresponds to a specific post or custom post type. You can use these IDs with functions like get_the_title() or get_post() to retrieve additional information or manipulate the posts as needed.

2. ACF Relationship field vs. Post Object field

The Advanced Custom Fields plugin offers two powerful field types to establish relationships between different content items: the Relationship field and the Post Object field. While both fields serve similar purposes, they have distinct characteristics that cater to different use cases. In this chapter, we will explore the differences between these two field types to help you decide which one best suits your needs.

Relationship field

The Relationship field is specifically designed to create associations between posts of different post types. It allows you to establish many-to-many relationships, meaning a single post can be linked to multiple related posts, and vice versa. This field is perfect for scenarios where you want to showcase related content, create custom post relationships, or build a network of interconnected content.

Key Features of the Relationship Field:

  • Many-to-many relationships between different post types.
  • Enables bidirectional linking of posts.
  • Perfect for building custom post relationships and interconnected content.
  • Provides an intuitive interface to search, select, and order related posts.

Post Object Field

On the other hand, the Post Object field serves similar needs but provides a more simple interface, without the filters. It may be useful if you don't want to provide filtering options for editors. In addition, by default, the field allows us to choose only a single item. So it's similar to a traditional "foreign key" concept in databases.

The ACF Post Object field looks like a select. Only the search box by post titles is available for filtering.
The Post Object field looks like a select. Only the search box by post titles is available for filtering.

Key Features of the Post Object Field:

  • Simple UI
  • No filters for editors
  • Better suited for a single relationship

Choosing the Right Field Type

The decision to use either the Relationship field or the Post Object field depends on the nature of your content and the specific requirements of your project.

Use the Relationship field when:

  • You need to create many-to-many relationships between different post types.
  • Your content structure involves interconnected or related posts that need bidirectional linking.
  • You want a user-friendly interface to easily search, select, and manage related posts.

Use the Post Object field when:

  • You only need to associate a single post with another post, page, or custom post type.
  • The relationships between your content items are more straightforward and do not require bidirectional linking.

In conclusion, both the Relationship field and the Post Object field are powerful tools for establishing relationships between content items in WordPress. By understanding their differences and knowing your specific project requirements, you can confidently choose the field type that best fits your needs and create a seamless and efficient content management experience.

3. Bidirectional Relationship feature

The task of querying posts that have a relationship with the current one is so common that the ACF plugin developers have introduced a dedicated feature to address this scenario. How does it work?

Let's illustrate this with an example involving Company and Employee custom post types (CPTs). A company can have multiple employees, which is represented by an 'Employees' Relationship field in the Company CPT. This part is fairly straightforward.

Now, let's delve into the task itself. We aim to retrieve a list of all companies where the current employee is associated. With the introduction of the Bidirectional feature, we can achieve this without creating a custom WP_Query. Here's how:

  1. Create a New Relationship Field:
    Add another Relationship field, perhaps named 'Companies', to the Employee CPT.
  2. Enable Bidirectional Relationship:
    Go to the 'Employees' Relationship field, and enable the Bidirectional feature. Set the target field as the new 'Companies' field.

With these steps completed, ACF will now automatically track changes. When you update the 'Employees' Relationship field, ACF will automatically update the related company in the associated employee's 'Companies' field.

This approach allows you to always obtain an up-to-date list of the companies associated with each employee, just like the value of the original relationship field.

Pro tip: You can take it a step further by enabling the Bidirectional feature for the 'Companies' Relationship field as well. This way, any additions or removals of companies on the employee's side will be automatically mirrored on the company's side too.

ACF Company Group with the Bidirectional Employees Relationship
Company Group with Bidirectional Employees Relationship. ACF will automatically add or remove the current Company from the target field when you add or remove an Employee.
ACF Company Group with the Bidirectional Employees Relationship
Employee Group with Bidirectional Companies Relationship. ACF will automatically add or remove the current Employee from the target field when you add or remove a Company.

How to display values from the bidirectional field

Displaying values from the Bidirectional field doesn't differ from working with a regular field. You can follow the instructions in the 'Display Relationship Field' chapter of this article to showcase the selected items. The significant advantage is that you can now interact with the field directly, eliminating the need for any WP_Queries.

Important note about existing fields

Enabling the feature doesn't automatically update the related fields. It merely activates the monitoring and automatic updating going forward. Consequently, if you already have items with filled data, they won't automatically appear in the target field.

Even pressing 'Update' for the items won't trigger this behavior, as ACF specifically tracks changes in the fields, such as additions or removals of items. Therefore, if you intend to employ this feature for pre-existing items, you will need to repopulate the fields or resort to the WP_Query approach.

4. Use cases of the ACF Relationship field

ACF Relationship field is a powerful tool for any content relation scenarios, including the following:

  1. Portfolio and Artist connections
    In a portfolio website, where artists and their artworks are managed separately, the ACF Relationship field allows you to link each artwork to its respective artist. This connection helps display a comprehensive profile for each artist, showcasing their portfolio pieces in one place.
  2. Related products in e-commerce
    For WooCommerce sites, the Relationship field can link products to specific manufacturers, managers, or related products. This setup can enhance product pages by showing related items or providing additional context about the product’s origin.
  3. Team Member Profiles
    On a company website, you can use the Relationship field to connect team members to projects they’ve worked on or departments they belong to. This relationship helps in organizing team-related content and displaying relevant information in an accessible format
  4. Content Hierarchies and Relationships
    For sites with complex content structures, such as news websites or educational platforms, the Relationship field helps establish connections between related articles, courses, or categories. This setup enhances content navigation and allows users to discover related or sequential information easily.
  5. Event Management
    When managing events, the Relationship field can link events to speakers, venues, or sponsors. This connection makes it easy to display detailed event information, including speaker profiles or venue details, on event pages.

5. ACF Relationship field support in Themes and Builders

ACF is one of the most popular WordPress plugins, and it's supported by many page builders right out of the box. However, most of these integrations are basic, providing limited control over layout or lacking support for advanced field types like Gallery or Repeater.

To achieve universal compatibility with any theme and page builder while gaining advanced control over your layout, consider using the Advanced Views Framework or custom code snippets as discussed in the following chapter.

Here's a snapshot of the built-in features offered by some of the most popular WordPress themes and page builders for displaying ACF Relationship fields:

Theme/BuilderACF-related featureACF Relationship type support
Astra-no
AvadaDynamic Contentyes
BeaverACF Moduleyes
BricksDynamic datayes
DiviACF Moduleno (not declared)
ElementorDynamic Tagsno (not declared)
GeneratePress-no
Gutenberg-no
KadenceDynamic Contentno (not declared)
OceanWP-no
Visual ComposerDynamic Contentno (not declared)
WPBackery-no

While this list may seem brief, many themes come with their own page builders. Check your theme’s documentation for guidance on displaying ACF Relationship fields, or refer to the universal methods outlined below for a more flexible approach.

6. Code snippets for the ACF Relationship field

ACF functions and their responses are essentially wrappers around built-in WordPress features. This means that to load and display field values, you need to be familiar not only with ACF but also with core WordPress classes and functions. Additionally, writing markup from scratch and manually escaping data can be time-consuming.

To streamline development, you can use the Advanced Views Framework. This WordPress framework offers smart templates for the front end, simplifying post queries and template creation. It generates default markup and automatically loads the escaped data into the template, allowing you to focus on the layout itself.

Unlike drag-and-drop page builders, smart templates in Advanced Views are modular and based on a template engine (Twig or Blade), providing full control over the markup and helping you avoid the pitfalls of global CSS and JavaScript files. The framework natively supports all ACF field types, along with other data sources.

Below are examples for both Advanced Views and custom code:

6.1) Loading and displaying items

The simplest way to display the chosen items is to turn them into a list of clickable titles.

Example of displaying the Relationship field using ACF Views. ACF Views (Basic) automatically displays the items of the relationship field as post links.
Example: list of the related articles.

Using Advanced Views Framework

  1. Navigate to the Views section and create a new View.
  2. Select the Relationship field in the Fields tab.
  3. Save the View; a template will be automatically generated. You can copy and modify this template as needed.
  4. To integrate it into your page, paste the generated shortcode or use the Custom Gutenberg block option.

The default template presents items as links, so you can leave it as is:

{% if relationship.value %}
    <div class="relationship">
        {% for post_item in relationship.value %}
            <a class="relationship__item" target="{{ post_item.target }}" href="{{ post_item.value }}">
                {{ post_item.linkLabel|default(post_item.title) }}
            </a>
        {% endfor %}
    </div>
{% endif %}

Visit the page to see the result. If it needs, you can add CSS rules to the CSS field of your View, to get the desired look.

Loading from different locations: To load a field from different locations (e.g., user profile), use the object-id shortcode argument.

Using custom code

To load the field value, you should use the ACF get_field function. Its response will differ based on the chosen return format. By default, it's the Post Object, but in case you've changed it to Post ID, you'll need to use the get_post() function to get the Post Instance.

By default, the get_field() function loads the value from the current object (page/post). In case you need to load from the other source, pass it as a second argument, as shown in the code snippet:

// Replace 'relationship_field' with the name of your Relationship Field
$related_items = get_field( 'relationship_field' ); // from the current post
$related_items = get_field( 'relationship_field', 10 ); // from a specific post by ID
$related_items = get_field( 'relationship_field', 'option' ); // from the options page
$related_items = get_field( 'relationship_field', 'user_1' ); // from the user by ID
$related_items = get_field( 'relationship_field', 'category_2' ); // from the category term with ID 2
$related_items = get_field( 'relationship_field', 'genre_3' ); // from the custom genre term with ID 3

if ( $related_items ) {
	printf( '<div class="relationship">' );
	foreach ( $related_items as $related_item ) {
		// todo uncomment, if return format is ID
		// $related_item = get_post($related_item);

		// Display post title as a link
		printf( '<a class="relationship__item" href="%s">%s</a>',
			esc_url( get_permalink( $related_item ) ),
			esc_html( $related_item->post_title ) );
	}
	printf( '</div>' );
} 

To style the items in the ACF Relationship field, you can add CSS rules to your theme's style.css file. However, keep in mind that this will enqueue the styles sitewide. A better approach is to add the CSS to the specific template assets or use the modular Advanced Views.

6.2) Displaying items as a Grid

Displaying items in a one-row or multi-row grid is one of the most popular ways to showcase related content. Each item typically includes a clickable title, a featured image, and additional details like the updated date or an excerpt.

The CSS grid feature is the simplest way to display items as a grid, so we'll employ it.

Example of displaying the Relationship field using ACF Views Pro. The plugin allows the creation of custom layouts. Choose the target post and meta fields, and the plugin will automatically display them.
Example of the Relationship items grid.

Using Advanced Views Framework

AVF Pro Edition allows you to load extra data of the objects, which is essential in this scenario. Begin by repeating the steps outlined in the previous case:

  1. Navigate to the Views section and create a new View.
  2. Select the Relationship field in the Fields tab.
  3. Save the View

Next, create a new View that will control the detailed layout of each item, as demonstrated in the AVF Relationship documentation. Once your detailed View is ready, return to the master View and select the newly created View in the 'View' setting of the Relationship field, then press save.

AVF will automatically update the default template, resulting in a layout that looks like this:

{% if relationship.value %}
    <div class="relationship">
        {% for post_item in relationship.value %}
            [avf_view view-id="{{ relationship.view_id }}" object-id="{{ post_item.value }}"]
        {% endfor %}
    </div>
{% endif %}

After that, you can add the CSS code to turn the layout into the grid:

#view__relationship {
 display: grid;
 grid-template-columns: 1fr;
 gap: 20px;
}

@media screen and (min-width:992px) {
#view__relationship {
  grid-template-columns: repeat(3, 1fr);
 }
}

Make sure the class in the CSS fits the field class from the markup. By changing the value of the grid-template-columns property, you can control the number of columns in your grid.

Using custom code

Initially, we need to create the layout markup. Add the following code to the target template:

$related_items = get_field( 'relationship_field' );

if ( $related_items ) {
	echo '<div class="relationship">';
	
	foreach ( $related_items as $related_item ) {
		printf( '<div class="related-item">' );

		// Display featured image if available
		if ( has_post_thumbnail( $related_item ) ) {
			printf( '<div class="related-item__image"><a href="%s">%s</a></div>',
				esc_url( get_permalink( $related_item ) ),
				get_the_post_thumbnail( $related_item, 'thumbnail' ) );
		}

		// Display post title
		printf( '<h2 class="related-item__title"><a href="%s">%s</a></h2>',
			esc_url( get_permalink( $related_item ) ),
			esc_html( $related_item->post_title ) );

		// Display post excerpt
		printf( '<div class="related-item__excerpt">%s</div>', wp_kses_post( $related_item->post_excerpt ) );

		printf( '</div>' );
	}
	
	echo '</div>';
}

The code displays a thumbnail, title, and excerpt for each chosen item. Now, we can turn it into the grid, by adding the following CSS code:

.relationship {
 display: grid;
 grid-template-columns: 1fr;
 gap: 20px;
}

@media screen and (min-width:992px) {
.relationship {
  grid-template-columns: repeat(3, 1fr);
 }
}

By changing the value of the grid-template-columns property, you can control the number of columns in your grid.

Note: You can add these CSS rules to your theme's style.css file. However, keep in mind that this will enqueue the styles sitewide. A better approach is to add the CSS to the specific template assets or use the modular Advanced Views.

6.3) Displaying items as a Slider

Another great way to showcase the relationship items is to display them in a slider. We can display one item at a time, or opt for multiple at once, as well as enable the auto slide option.

Splide slider
The horizontal slider allows you to showcase one or multiple items at a time and smoothly scroll to the next set of items.

The first thing to do is to select the target slider library. In this article, we've opted for Splide, which is a well-known library with rich options and excellent performance.

The simplest way to turn the repeater into the slider is to use AVF Pro edition, as the framework comes with pre-configured Slider, Masonry, and Image gallery libraries.

Using Advanced Views Framework

After adding the repeater field to the target View, change the 'Enable Slider' option to 'Splide v4' and press the Save button, as described on the AVF Relationship Docs page. The framework will automatically change the field markup to incorporate the necessary classes, and add the default JS instance:

var repeater = this.querySelector('.acf-view__repeater');
if (repeater_inner) {
	/* https://splidejs.com/guides/options/ */
	new Splide(repeater, {
		type: 'loop',
		perPage: 1,
		perMove: 1,
	}).mount();
}

Now you can customize the settings according to your needs, using any available Splide options.

Using custom code

In this case, you need to download the CSS and JS code of the Splide library to your theme. Then, print the relationship items in the target template with the necessary splide classes:

$related_items = get_field('relationship_field');

if ($related_items) {
    // Main Splide container
    echo '<div class="splide">'; 
    
    // Splide track container
    echo '<div class="splide__track">';
    
    // List of slides
    echo '<ul class="splide__list">';
    
    foreach ($related_items as $related_item) {
        // Each slide item
        echo '<li class="splide__slide related-item">';
        
        // Display featured image if available
        if (has_post_thumbnail($related_item)) {
            printf(
                '<div class="related-item__image"><a href="%s">%s</a></div>',
                esc_url(get_permalink($related_item)),
                get_the_post_thumbnail($related_item, 'thumbnail')
            );
        }

        // Display post title
        printf(
            '<h2 class="related-item__title"><a href="%s">%s</a></h2>',
            esc_url(get_permalink($related_item)),
            esc_html(get_the_title($related_item))
        );

        // Display post excerpt
        printf(
            '<div class="related-item__excerpt">%s</div>',
            wp_kses_post(get_the_excerpt($related_item))
        );

        echo '</li>'; // Close slide item
    }

    echo '</ul>'; // Close splide__list
    echo '</div>'; // Close splide__track
    echo '</div>'; // Close splide container
}

Then enqueue the library's CSS using the wp_enqueue_style function, and add the following JS to your theme's script.js:

import '/wp-content/themes/YOUR_THEME/assets/js/splide.js';

document.addEventListener('DOMContentLoaded', function () {
    var slider = document.body.querySelector('.splide');
    if (slider) {
        /* https://splidejs.com/guides/options/ */
        new Splide(slider, {
            type: 'loop',
            perPage: 1,
            perMove: 1,
        }).mount();
    }
});

Now you can customize the settings according to your needs, using any available Splide options.

6.4) Updating the Relationship field programmatically

To update the Relationship field programmatically, you can use the ACF update_field function. Since this field stores the post IDs as an array, the data you pass must be an array of post IDs.

add_action( 'acf/init', function () {
	// Replace 'my_relationship_field' with your field name, 100 and 200 with your chosen post ids,
	// and 1 with the source post ID (where the value will be updated)
	update_field( 'my_relationship_field',
		[100, 200],
		1
	);
} );

If you need to update the Relationship field on a user or term object, you must add the appropriate prefix, just as shown in the "loading" field value section.

Note: You should call the update_field function inside the acf/init action, or in any hooks that happen later.

7. Querying by the ACF Relationship field

When working with the ACF Relationship field, you might need to find items that have a specific post assigned. Unlike simply displaying the relationships, querying items based on these values can be more complex due to the varying storage locations of ACF fields.

Additionally, it's important to consider the storage format of the Relationship field, which is a serialized array. This format requires using the LIKE comparison in your query, and you must wrap the target value with surrounding brackets, to avoid mismatched items.

Here's how to handle queries depending on where the Relationship field values are stored:

7.1) By postmeta (Post, Page, Any CPT)

Using Advanced Views Framework:

If you're using the AVF: Pro edition, querying by ACF Relationship field values is straightforward with Meta Queries. You need to create a Card, choose the target Relationship field in the Meta Fields tab, and define the desired value. It can be a static id or pointer to another field. Then the framework will take care of the rest.

Using WP_Query:

$args = array(
    'post_type' => 'post', // Replace with your custom post type if needed
    'post_status' => 'publish',
    'posts_per_page' => -1, // Retrieve all posts
    'meta_query' => array(
        array(
            'key'     => 'your_relationship_field', // Replace with your ACF Relationship field key
            'value'   => '"10"', // Target post ID wrapped in double quotes to match serialized data
            'compare' => 'LIKE',
        )
    )
);

// Execute the query
$query = new WP_Query($args);

// Loop through the results
foreach($query->get_posts() as $post) {
    // Process each WP_Post object here
    // For example, display the post title
    echo '<h2>' . get_the_title($post->ID) . '</h2>';
}

7.2) By termmeta (Terms)

Here we need to employ the WP_Term_Query class:

$args = array(
    'taxonomy'   => 'category', // Replace with your taxonomy
    'meta_query' => array(
        array(
            'key'     => 'your_relationship_field', // Replace with your ACF Relationship field key
            'value'   => '"10"', // Target post ID wrapped in double quotes to match serialized data
            'compare' => 'LIKE',
        )
    )
);

// Execute the query
$term_query = new WP_Term_Query($args);

// Loop through the results
foreach ($term_query->get_terms() as $term) {
    // Process each WP_Term object
    // Example: echo $term->name;
}

7.3) By usermeta (user profile)

In this case, we need to use the WP_User_Query class:

$args = array(
    'meta_query' => array(
        array(
            'key'     => 'your_relationship_field', // Replace with your ACF Relationship field key
            'value'   => '"10"', // Target post ID wrapped in double quotes to match serialized data
            'compare' => 'LIKE',
        )
    )
);

$user_query = new WP_User_Query($args);

// Loop through the results
foreach ($user_query->get_results() as $user) {
    // Process each WP_User object
    // Example: echo $user->user_login;
}

7.4) Inside ACF Blocks

ACF Blocks save their data as JSON in the post_content. This data cannot be queried directly. However, if you enable the "Save in Meta" feature for ACF Blocks, the field values are also saved in post meta, allowing you to query them similarly to other postmeta fields.

8. Related Relationship field filters and hooks

ACF offers a variety of filters and hooks that enable you to modify field data and behavior, extending WordPress's core hooks functionality. You can utilize the standard add_action and add_filter functions to attach custom code to these hooks.

Below are some of the most commonly used hooks along with the ACF Relationship field type:

8.1) acf/fields/relationship/result

Using the acf/fields/relationship/result filter, you can amend the item's presentation in the list. By default, it displays object titles, and e.g. you can add an ID:

add_filter( 'acf/fields/relationship/result',
	function ( string $title, \WP_Post $post, array $field, int $post_id ): string {
		$title .= ' [' . $post->ID . ']';

		return $title;
	},
	10,
	4 );

Note: Pay attention that this snippet doesn't affect the field's search algorithm. If your goal includes allowing to search by the custom addition, you should also use the query filter described below.

8.2) acf/fields/relationship/query

Using the acf/fields/relationship/query filter, you can amend the field's search algorithm. The ACF search query is built on top of the WP_Query class, so you can use any arguments supported by the class.

add_filter( 'acf/fields/relationship/query', function ( array $args, array $field, int $post_id ): array {
	// Restrict results to children of the current post only.
	$args['post_parent'] = $post_id;

	return $args;
}, 10, 3 );

8.3) acf/load_field

The acf/load_field filter allows you to modify the field settings before it is displayed on the editor's screen. This filter is particularly useful for dynamically adjusting the field's configuration, such as setting default values, changing labels, or customizing available options.

add_filter('acf/load_field/name=my_relationship_field', function (array $field): array {
    // Modify the field settings as needed
    $field['instructions'] = 'Please select related posts.';
    $field['post_type'] = ['post', 'page']; // Limit to posts and pages
    $field['filters'] = ['search', 'post_type']; // Add search and post type filters

    return $field;
});

8.4) acf/render_field

The acf/render_field action allows you to add custom HTML before or after a field's input on the editor's screen in the WordPress admin. This can be particularly useful for adding custom-styled text, icons, styles, or additional interactive elements to enhance the field's functionality.

add_action('acf/render_field/key=field_123456789abc', function (array $field): void {
    // Your custom HTML
    echo '<div class="my-custom-class">Custom field-related element</div>';
});

Note: By default, the acf/render_field action is triggered after the field input has been printed. If you need to print your HTML before the input, you should set the priority number to 9 or lower in the third argument of the add_action WordPress function.

8.5) acf/validate_value

Use the acf/validate_value filter to validate the values entered into the field. You can ensure that the entered value meets specific criteria:

add_filter('acf/validate_value/name=my_relationship_field', function($valid, $value, array $field) {
    if (true !== $valid) {
        return $valid; // Skip validation if there is an existing error
    }

    // Custom validation: Ensure the number of selected posts is greater than 3 and less than 6
    $num_selected_posts = is_array($value) ? count($value) : 0;

    if ($num_selected_posts < 3 || $num_selected_posts > 6) {
        return 'Please select between 3and 6 posts.';
    }

    return $valid;
}, 10, 3);

8.6) acf/validate_save_post

The acf/validate_save_post action allows you to perform custom form validations before saving ACF fields. This is particularly useful when you need to validate one field's value based on another field's input or enforce specific rules across multiple fields.

add_action('acf/validate_save_post', function () {
    // Get the Relationship field values from ACF fields
    $relationship_1 = $_POST['acf']['field_relationship_id_1'] ?? '';
    $relationship_2 = $_POST['acf']['field_relationship_id_2'] ?? '';

    if (empty($relationship_1) && empty($relationship_2)) {
        acf_add_validation_error('field_relationship_id_1', 'At least one Relationship field must be defined.');
        acf_add_validation_error('field_relationship_id_2', 'At least one Relationship field must be defined.');
    }
});

Tip: To find the field key, navigate to the ACF field group in the WordPress admin. Click on the Screen Options button at the top right corner of the page, then check the Field Keys option. Once enabled, the field keys will be displayed next to each field name in the group.

8.7) acf/save_post

The acf/save_post action is triggered when the current item (page/product/user) is saved. You can use it to perform any additional actions, e.g. updating related data.

add_action('acf/save_post', function ($post_id) {
    // Retrieve the relationship field value (replace with your actual relationship field key)
    $related_posts = get_field('related_posts', $post_id); // Field key for relationship field

    if (!$related_posts) {
        return;
    }

    // Loop through each related post and update the 'related_item' field
    foreach ($related_posts as $related_post_id) {
        update_field('related_item', $post_id, $related_post_id); // Replace 'related_item' with your actual field key
    }
});

Stuck with development or facing an issue?

WPLake offers affordable on-demand website development and design.

No matter the size of your project - contact us now, and we'll get it done for you!

Get assistance now

FAQ mode

/

Learning mode

  1. Can I update the ACF Relationship field programmatically?

    Yes, you can update the ACF Relationship field programmatically by adding or removing post IDs using the ACF update_field() function.

Was this article helpful?

Totally useless

Slightly helpful

Very helpful

Course navigation: ACF Plugin

Content links (83)

About the Author

Maxim Akimov

Certified WordPress expert from Ukraine with over 8 years of experience. Advocate of the BEM methodology and the overall modular approach. Loves sporting activities and enjoys going to the gym and regularly plays table tennis.

0 Comments

    Leave a comment

    Reply to 

    Please be considerate when leaving a comment.

    Not shown publicly


    Got it