Key points:
- Managing custom post type relationships in WordPress requires extra effort due to limited native support.
- Developers can implement relationships through custom code, but Advanced Custom Fields (ACF®)’s Relationship field simplifies creating and managing one-way or bidirectional relationships.
- ACF offers a scalable, efficient solution with an intuitive interface and reliable performance for dynamic WordPress sites.
Managing relationships between WordPress custom post types is a nuanced challenge for developers working on dynamic projects. While the average WordPress expert could create custom post types in their sleep, building structured, scalable relationships between them often feels unnecessarily complicated.
As always, there’s the manual approach, but Advanced Custom Fields (ACF®)’s Relationship field provides a manageable, scalable solution for managing both one-way and bidirectional connections.
In this article, we’ll explore how to handle these challenges head-on. We’ll begin by clarifying the different types of relationships and their practical use cases. Then, we’ll dive into implementation, showcasing how to build relationships both programmatically and using ACF.
Whether you’re optimizing for simplicity, scalability, or specific project requirements, this guide will help you evaluate and implement the best solution to manage custom post type relationships effectively.
What are WordPress custom post type relationships?
In WordPress, custom post types allow developers to go beyond default content types like posts and pages by creating tailored structures for specific content, such as books, events, or services. Post relationships connect these custom post types, such as linking a book to its author or an event to its venue, making it easier to manage and display related content.
Bidirectional relationships expand on this by ensuring that both connected post types are aware of each other. For instance, an author profile lists their books, and each book links back to its author.
Common use cases for custom post type relationships include books and authors, movies and directors, events and venues, projects and clients, courses and instructors, and service providers with their services.
Unfortunately, WordPress’s native functionality for custom post types is minimal, and support for managing relationships – especially bidirectional ones – is even more limited. This lack of built-in tools requires developers to rely on custom code or plugins like ACF to implement these connections effectively, which we’ll explore in the next section.
How to create custom post type relationships in WordPress
To add custom post type relationships to WordPress, you have two options: custom code and the ACF plugin.
Custom code offers developers complete control over the data structure and relationships, making it ideal for projects requiring highly specific or scalable solutions. On the other hand, ACF simplifies the process with a user-friendly interface, perfect for streamlining development while maintaining flexibility.
We’ll explore both methods, helping you choose the right approach based on your project’s needs and complexity.
Method 1: Using custom code (warning: advanced)
As is the case for a lot of non-native WordPress functionality, you can build custom post type relationships using custom code. For this walkthrough, we’ll be linking books to their authors:
1. Start by registering the Books and Authors custom post types by adding the following to your functions.php:
function register_custom_post_types() {
// Register "Books" custom post type
register_post_type('books', array(
'label' => 'Books',
'public' => true,
'supports' => array('title', 'editor', 'thumbnail'), // Enable title, editor, and thumbnail features
));
// Register "Authors" custom post type
register_post_type('authors', array(
'label' => 'Authors',
'public' => true,
'supports' => array('title', 'editor', 'thumbnail'), // Enable title, editor, and thumbnail features
));
}
add_action('init', 'register_custom_post_types');
2. Reload your dashboard, where you should see two new post types appear:
3. Add a custom meta box to link books to authors:
function add_custom_meta_box() {
// Add a meta box to the Books post type
add_meta_box(
'related_author', // Meta box ID
'Related Author', // Title
'related_author_meta_box_callback', // Callback function to display the meta box
'books' // Post type to display the meta box on
);
}
add_action('add_meta_boxes', 'add_custom_meta_box');
// Callback function to display the dropdown of Authors
function related_author_meta_box_callback($post) {
// Fetch all authors
$authors = get_posts(array('post_type' => 'authors', 'numberposts' => -1));
// Retrieve the selected author ID from post meta
$selected_author = get_post_meta($post->ID, '_related_author', true);
// Create a dropdown menu of authors
echo '<select name="related_author">';
echo '<option value="">Select an Author</option>'; // Default option
foreach ($authors as $author) {
// Populate dropdown with author titles and mark selected option
echo '<option value="' . $author->ID . '"' . selected($selected_author, $author->ID, false) . '>' . $author->post_title . '</option>';
}
echo '</select>';
}
4. Create a function to save the selected author when the book is saved:
function save_related_author_meta($post_id) {
// Check if the related_author field exists in the request
if (array_key_exists('related_author', $_POST)) {
// Save or update the related author ID as post meta
update_post_meta($post_id, '_related_author', $_POST['related_author']);
}
}
add_action('save_post', 'save_related_author_meta');
5. Add a new author the same way you’d add a new post. Go to Authors > Add New Post and set their name as the title. Next, add a new book using the same method, but this time, use the meta box at the bottom to link it to the relevant author:
6. All that’s left is to display the content on the frontend. You can do this by creating a file called single-books.php in your theme or child theme’s root folder and adding the following code:
<?php
get_header(); // loads header.php
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
?>
<h1><?php the_title(); ?></h1>
<?php if ( has_post_thumbnail() ) : ?>
<div><?php the_post_thumbnail('large'); ?></div>
<?php endif; ?>
<div><?php the_content(); ?></div>
<?php
// Get the saved author ID from post meta
$related_author_id = get_post_meta( get_the_ID(), '_related_author', true );
if ( $related_author_id ) :
$related_author = get_post( $related_author_id );
if ( $related_author && 'authors' === $related_author->post_type ) :
?>
<p><strong>Author:</strong> <?php echo esc_html( $related_author->post_title ); ?></p>
<?php
endif;
endif;
?>
<?php
endwhile;
else :
echo '<p>No book found.</p>';
endif;
get_footer(); // loads footer.php
Now, when you check the book’s page on the frontend, here’s what you should see:
Method 2: Using the Advanced Custom Fields plugin (recommended)
The manual method outlined above gives you 100% control over things, but it’s cumbersome and definitely not scalable. Think of how many things could break if you get one tiny thing wrong in the code.
This is why you should consider using a plugin like ACF, which presents you with a visual interface that makes things infinitely more streamlined and scalable. For this walkthrough, we’ll link movies to directors.
Here’s how to use ACF to create custom post types and build relationships between them:
1. From your dashboard, go to ACF > Post Types > Add New to create the Movies and Directors post types.
2. Click on Save Changes when you’re done creating your custom post type, then hit Add fields from the confirmation dialog that appears.
3. Set the Field Type value to Relationship and assign a Field Label, which will automatically populate the Field Name. Under Filter by Post Type, select the post type you want to connect to. Configure the remaining options as needed and save your changes.
4. Create new posts under each post type. We’ll start by adding a new director from the dashboard through Directors > Add New Director. Next, we’ll create a new movie via Movies > Add New Movie, where we should see a section appear at the bottom to link it to a director.
All that’s left is for you to hit Publish, and you’ve successfully created a relationship between two custom post types! All in a few simple steps with no code!
You can choose to use a bit of custom PHP to display the content on the frontend, or you can keep the no-code party going by connecting ACF to page builders like Bricks, Divi, or Elementor.
Supercharge Your Website With Premium Features Using ACF PRO
Speed up your workflow and unlock features to better develop websites using ACF Blocks and Options Pages, with the Flexible Content, Repeater, Clone, Gallery Fields & More.
Implementing bidirectional relationships for complex content structures
So far, both methods we’ve covered only allow you to create one-way relationships, but if you need more interconnectedness, you should look into bidirectional relationships.
Making an existing relationship two-way in ACF is as easy as hitting Edit on the relationship field you created, then going to Advanced and toggling the Bidirectional option on.
That’s it!
ACF’s Bidirectional feature lets each item automatically update the other side of a Relationship, User, Taxonomy, or Post Object field. When enabled, you specify a Target Field that stores references back to the current item as long as both item types are compatible.
These updates only occur if the field is displayed on a Post, User, or Taxonomy (not on option pages or blocks) and do not chain beyond one hop. Two-way syncing requires enabling bidirectionality on both fields, each pointing back to the other.
Finally, Target Fields must be top-level (not nested in groups), and single-value constraints aren’t enforced during the automatic update.
Why ACF is your best choice for custom post type relationships
ACF should be your go-to solution for managing custom post type relationships in WordPress. It bridges the gap between ease of use and functionality, making it a preferred choice for developers and non-developers alike.
Here’s why ACF stands out:
- It reduces errors by automating much of the relationship management process, minimizing risks from manual coding.
- It’s accessible to non-developers with its intuitive visual interface, enabling relationship setup without coding.
- It future-proofs relationships that remain intact during theme changes or updates, avoiding breakage common with hard-coded solutions.
Below the surface, ACF simplifies complex relationships without compromising on performance or scalability. Its Relationship field abstracts the database complexity, automatically handling post connections with optimized queries.
Developers also benefit from ACF’s functions like get_field()
and update_field()
for retrieving and updating relationships programmatically. Performance remains a priority with built-in query caching and field value optimization, ensuring your site remains fast even with large datasets.
Additionally, ACF provides advanced filtering capabilities, allowing you to define intricate relationship rules based on post status, type, or custom taxonomies.
This combination of power and usability makes ACF an excellent choice for projects requiring flexible yet solid relationship management.
Simplify WordPress custom post type relationships with ACF
Managing content relationships is a real challenge for modern WordPress sites. Native functionality is practically nonexistent, and custom code often becomes a maintenance nightmare. ACF offers a practical solution, turning a complex process into something straightforward and reliable.
With ACF, you get a user-friendly visual interface that’s accessible to non-developers and a powerful API for advanced use cases. It slashes development time, minimizes errors, and keeps your relationships intact through theme changes and updates. Whether it’s simple links or intricate bidirectional connections, ACF handles it all without breaking a sweat.
Stop fighting your tools and start building smarter. Get started with ACF for free today.
For plugin support, please contact our support team directly, as comments aren't actively monitored.