Use cases of ACF Bidirectional Relationships:
- Related Posts
- Related Posts from Different Post Type
- Connect 2 Different Relationship field in Different Post Type
Prerequisite:
Install Custom Post Type UI and Advanced Custom Fields
Different Post items with Same Post Type Shares Same Relationship field
Use case: Related Post
Sample:
- Create field group named Post
- Create field named Related Post and set type as Relationship.
- Make sure you only assign it to specific post type e.g. Post.
- Add the code in functions.php in the theme directory
function bidirectional_acf_update_value( $value, $post_id, $field ) {
// vars
$field_name = $field['name'];
$field_key = $field['key'];
$global_name = 'is_updating_' . $field_name;
// bail early if this filter was triggered from the update_field() function called within the loop below
// - this prevents an inifinte loop
if( !empty($GLOBALS[ $global_name ]) ) return $value;
// set global variable to avoid inifite loop
// - could also remove_filter() then add_filter() again, but this is simpler
$GLOBALS[ $global_name ] = 1;
// loop over selected posts and add this $post_id
if( is_array($value) ) {
foreach( $value as $post_id2 ) {
// load existing related posts
$value2 = get_field($field_name, $post_id2, false);
// allow for selected posts to not contain a value
if( empty($value2) ) {
$value2 = array();
}
// bail early if the current $post_id is already found in selected post's $value2
if( in_array($post_id, $value2) ) continue;
// append the current $post_id to the selected post's 'related_posts' value
$value2[] = $post_id;
// update the selected post's value (use field's key for performance)
update_field($field_key, $value2, $post_id2);
}
}
// find posts which have been removed
$old_value = get_field($field_name, $post_id, false);
if( is_array($old_value) ) {
foreach( $old_value as $post_id2 ) {
// bail early if this value has not been removed
if( is_array($value) && in_array($post_id2, $value) ) continue;
// load existing related posts
$value2 = get_field($field_name, $post_id2, false);
// bail early if no value
if( empty($value2) ) continue;
// find the position of $post_id within $value2 so we can remove it
$pos = array_search($post_id, $value2);
// remove
unset( $value2[ $pos] );
// update the un-selected post's value (use field's key for performance)
update_field($field_key, $value2, $post_id2);
}
}
// reset global varibale to allow this filter to function as per normal
$GLOBALS[ $global_name ] = 0;
// return
return $value;
}
add_filter('acf/update_value/name=related_posts', 'bidirectional_acf_update_value', 10, 3);
Note: Code snippet can be found in ACF main site
- Make sure that field name is same with the acf/update_value
- Go to the Post 1 item and select the related post the Post 2
- Try to go to Post 2, you will see that it automatically adds the Post 1
Note: Same what happen if you remove any items from the relationship field. It also automatically removed it from other post related to it
Different Post Type Share Same Relationship Field
Prerequisite:
- Install ACF Post-2-Post by John A. Huebner II
Case:
Connect items from different post type e.g. Post Type=Tutor, Post Type=Textbook with one relationship field.
Note: Same process from the steps above. In this procedure, I only added the difference that needs to be tweak.
- Create two post type in CPT UI. e.g. Post Type Tutor, Post Type Textbook
- Create one field with relationship type e.g. post. Make sure it is assigned to Post type that needs to connect
Different Post Type with Different Relationship Field
Prerequisite:
- Install ACF Post-2-Post by John A. Huebner II
Use case:
You need to attached the student from teacher and vise versa but it will list the opposite post. For instance, list of students will display under the relationship field when you open the teachers post, vise versa.
Two Post types:
Post type 1 = Teacher
Post type 2 = Student
Two Custom Group Field:
Relationship field 1 = Student to be handled (attached to Teacher post type)
Relationship field 2 = Professors to attend (attached to Student post type)
Relationship field 1 and Relationship field 2 should share same Name e.g. teacher_student_relation
Go to the Teacher item and attach the student to be handle
e.g. Ms. Science Teacher selected Student 1
Go to the Student 1 and attach the professors to attend
e.g. You will view that it automatically add Ms.Science Teacher under the Professors to attend
References: https://support.advancedcustomfields.com/forums/topic/bidirectional-relationships-and-multiple-post-types/