Skip Navigation

[Resolved] Using Views with Advanced Custom Fields Relationship Field

This thread is resolved. Here is a description of the problem and solution.

Problem: I am using ACF relationship fields to create links between two custom post types - Practices and Events. The Events CPT contains a Repeating Field Group (RFG) from Types. One of the fields in that RFG is a custom date field. On the Practice Area single post, I would like to display all the RFGs that occur on or after today, and also belong to an Event related to the current Practice Area post in the ACF relationship.

Solution: Use custom code to determine the IDs of the Event posts that are related to the current Practice Area. Not sure how that works, so consult the ACF documentation.

RFGs are essentially children in a parent/child relationship with the post where they are saved. Use the toolset_get_related_posts API to determine which RFG post IDs are associated with those Event IDs, and push those RFG IDs into an array. Pass those IDs into a View of RFG's post ID filter using render_view. Add a custom field date filter to the View of RFGs by date in addition to post ID. If no related RFG IDs are found, do not render the View.

Relevant Documentation:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts
http://php.net/manual/en/function.sizeof.php

This support ticket is created 6 years, 3 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 20 replies, has 2 voices.

Last updated by keithW 6 years, 3 months ago.

Assisted by: Christian Cox.

Author
Posts
#1071555

We need to add events to the practice area pages but only events that are associated to that area. Inside Views there's no way to use the ACF relationship field in the Query Filter so how would we go about accomplishing this?

I need to query the events CPT, get the events that are associated to the Practice Area via the ACF relationship field and then display the events that are upcoming via the RFG's event date.

This is a follow up after getting a solution from Minesh with regards to ACF via a shortcode: https://toolset.com/forums/topic/split-using-types-to-create-events/

#1071625

Inside Views there's no way to use the ACF relationship field in the Query Filter so how would we go about accomplishing this?
Hi, it sounds like you will need to figure out how to determine related posts using ACF fields. That's something you should ask their support team, because post relationships are handled differently in different systems. Ideally if you are able to use some ACF shortcode to display the related post IDs, then you could pass those values into a Views shortcode post ID filter. This technique is called passing arguments into Views: https://toolset.com/documentation/user-guides/passing-arguments-to-views/

For example, let's say there is an ACF shortcode called get-related-acf-posts that returns a comma-separated list of related post IDs like 123, 456, 789. You could set up a View that is filtered by post ID, provided by a shortcode attribute "ids". Then insert the ACF shortcode inside the View's ids shortcode attributes like this:

[wpv-view name="your-view-slug" ids="[get-related-acf-posts]"]

Register the ACF shortcode in Toolset > Settings > Frontend Content > Third party shortcode arguments.

If ACF does not provide a shortcode that produces such a list of post IDs, then it will require custom code. I will be glad to help filter a View by post IDs if you can provide a code sample showing how to get a comma-separated list of related post IDs from ACF. That's something you'll need to ask of their support team.

#1071633

Christian,

Thanks for the reply.

I can create a comma-separated list of related post IDs with the following PHP code:

<?php
               $posts = get_posts(array(
					'post_type' => 'event',
					'showposts' => 3,
					'meta_query' => array(
						array(
							'key' => 'practice_areas', // name of custom field
							'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
							'compare' => 'LIKE'
						)
					)
				));
			
				$num = count($posts); ?>
        <?php  foreach( $posts as $post): // variable must be called $post (IMPORTANT) ?>
						<?php setup_postdata($post);
			    		$event_id = get_the_ID();
						$event_ids .= "$event_id,"; ?>
					<?php endforeach; ?>
         <input type="hidden" value="<?php echo "$event_ids"; ?>">

Does this help?

I'm pretty good when it comes to PHP but have very little experience when it comes to shortcodes and Views. If we could create this all via PHP and I insert that into my theme, I'm all for that.

#1071672

Okay sure, we offer the Views API method render_view that will output the results of an existing View using PHP instead of shortcodes. You can pass any attributes you would use in the shortcode into this function. So create a View of these Event posts, filtered by post ID, where the post ID is set by a shortcode attribute "ids". In the Loop, insert a wpv-post-title shortcode for now so you can confirm it's working as expected. Then in your PHP code to display the results:

// your code before this to get $event_ids, which should be a comma-separated list of post IDs
if( function_exists('render_view') ){
  echo render_view( 'id' => 12345, 'ids' => $event_ids);
}

https://toolset.com/documentation/programmer-reference/views-api/#render_view

#1072393

Christian,

Thanks... this is pointing me in the right direction. I'm getting some events to display but it doesn't seem 100% correct. The events display on some practices but not on others that they should. Is there a way to output the queries in some way to see exactly what is happening or not happening so we can troubleshoot further?

#1074346

Sure, first please edit the View you are using to display the related posts. Take multiple screenshots of this editor screen so I can see how everything is set up. Include these screenshots with your next reply.

Next, output the event IDs variable in your PHP code so I can see exactly what's happening during the render. Like this:

if( function_exists('render_view') ){
  echo 'Event IDs: ' . $event_ids . '<br />';
  echo render_view( 'id' => 12345, 'ids' => $event_ids);
}

Then go to Toolset > Settings > Frontend Content and activate debug mode. Reload the page on the front-end of the site where you can see the View. A popup window should appear with some debug information. If it does not appear, check your popup blocker settings and allow popups for this site, then refresh the page. In the popup, toggle open any closed sections to see all the information, then copy and paste everything in the popup. Post it in your next reply.

Take a screenshot of the results, and include that in your next reply as well.

#1074708
Edit View ‹ Cohen Seglias — WordPress.png

Christian,

I'm having trouble getting the debugger popup to show in any of my browsers. It doesn't seem to be triggering a popup at all.

First, attached is a screenshot of the view setup.

Second, below is the PHP code I'm using on the page:

<?php
               $posts = get_posts(array(
					'post_type' => 'event',
					'showposts' => 3,
					'meta_query' => array(
						array(
							'key' => 'practice_areas', // name of custom field
							'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
							'compare' => 'LIKE'
						)
					)
				)); ?>
					<?php  foreach( $posts as $post): // variable must be called $post (IMPORTANT) ?>
						<?php setup_postdata($post);
			    		$event_id = get_the_ID();
						$event_ids .= "$event_id,"; ?>
					<?php endforeach; ?>
      <?php echo "$event_ids"; ?>
        <?php
				$args2 = array(
					'id' => 3224,
					'ids' => $event_ids,
					'showposts' => 3,
				);
  				echo render_view( $args2 );
			
				$posts2 = get_posts(array(
					'post_type' => 'event',
					'showposts' => -1,
					'meta_query' => array(
						array(
							'key' => 'practice_areas', // name of custom field
							'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
							'compare' => 'LIKE'
						)
					)
				));
			
				$num2 = count($posts2);
		?>
			
          <?php if ($num2 > 3) { ?><a class="button-secondary-blue" href="/events#search-news-capabilities-<?php echo "$pa_title"; ?>">View More</a><?php } ?>

Third, here's the URLs for review.

Event: hidden link
As you can see, this event is associated to three practice areas: Business Transactions, Construction and Wealth Preservation

If you goto hidden link, this is where the above code is used. It displays the event properly. However it should be displaying more events then just the two. And if you goto hidden link or hidden link you won't see that event at all.

#1075039

I'm having trouble getting the debugger popup to show in any of my browsers. It doesn't seem to be triggering a popup at all.
This may indicate a JavaScript error is occurring before the popup code is executed. I can see an error related to an audio player script here:
hidden link
This error may be blocking execution of code beneath it in the page source, preventing the popup from being displayed. Check the browser console and resolve any JS errors, or comment out any errors temporarily, then try again.

First, attached is a screenshot of the view setup.
I see there is a post relationship filter set up on this View. To display Event posts, you should remove the post relationship filter and replace it with a post ID filter, where the post ID is set by a shortcode attribute "ids". A post relationship filter will only work with relationships defined in Types, not relationships defined with ACF relationships fields. That's why we created the custom shortcode that returns the related post IDs - we will pass those related IDs into a post ID filter.

I see the View is also set up to display Event Date(s) RFGs. A post relationship filter is required to determine which RFGs are related to a parent post. However, we know that a post relationship filter will break the Events filter. So either you can show Event Date(s) RFG posts filtered by a Types post relationship, or you can show related Events using the post ID filter and the custom shortcode you created. If you want to combine these two things in a single View, you can create another custom shortcode that returns the post IDs of all the related RFG posts, and pass those values into the same post ID shortcode attribute as the Events IDs. Here's an example of some code that will help you access RFGs using the toolset_get_related_posts API:
https://toolset.com/forums/topic/repeatable-group-with-php/
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

#1075077

Christian,

We need to do the post relationship filter because we the Events CPT is setup with the ability to have multiple event dates within it and we want each instance to display as an item.

How should we go about setting this up so we can display the events that are specific to each practice area?

#1076371

Okay you know a list of numeric IDs of the Events related to the current Practice Area. You have already created this. You need to display a list of Event RFGs, connected to those related Event posts, and sorted/filtered by a custom field date. Each result shown in the View is one RFG instance, so you should change the View to only show Event RFGs, not Events. Then you should configure your date filter and sorting options to display Event RFGs occurring or after today, in ascending order based on the custom date field.

To further filter the View of Event RFGs, we need to specify which parent Event they are related to. We could do that with a post relationship filter if there is only the possibility of one parent Event. However, there could be multiple parent Events related to the current Practice Area, so a post relationship filter is not possible. Delete it from the query filter. The only other option is to use a post ID filter. This means we need to determine the post IDs of the related Event RFGs to filter the results.

To determine the post IDs of all the Event RFGs related to some Event, you will use the post relationships API toolset_get_related_posts(). Repeating Field Groups are basically the children in a parent/child relationship. The slug of the relationship is the slug of the RFG, and the parent is the post where the RFGs are saved. I can help with this code if necessary. The example here describes querying RFGs in PHP: https://toolset.com/forums/topic/repeatable-group-with-php/

So with that in mind, you will loop over the list of Event IDs you already have and call the toolset_get_related_posts API to determine the related Event RFGs for each Event. Push those related Event RFG IDs onto an array. After the loop is complete, the array will contain all the Event RFG IDs that are related to all the Events that are related to the current Practice Area, replacing your original post relationship filter. Now you can pass that array into the post ID filter of the Event RFGs View. The results will also be filtered and sorted by your custom date field based on the settings you defined in the View editor.

#1076475

Christian,

I'm struggling to put all these pieces together. Here's my code:

<?php
               $posts = get_posts(array(
					'post_type' => 'event',
					'showposts' => 3,
					'meta_query' => array(
						array(
							'key' => 'practice_areas', // name of custom field
							'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
							'compare' => 'LIKE'
						)
					)
				)); ?>
					<?php  foreach( $posts as $post): // variable must be called $post (IMPORTANT) ?>
						<?php setup_postdata($post);
			    		$event_id = get_the_ID(); 
			
						$event_ids .= "$event_id,"; ?>
						
						<?php
			
						$pulsanti = toolset_get_related_posts(
						  $event_id,        // the parent RFG
						  'event_dates',  // the RFG slug
						  'parent',     // the sezioni role in this relationship is 'parent'
						  1000000,     // the maximum number of results
						  0,           // the offset
						  array(),     // additional query arguments
						  'post_id',   // return format
						  'child'    // role to return
						);
						?>
						
					<?php endforeach; ?>
       
       <?php print_r($pulsanti); ?>
        <?php
				$args2 = array(
					'id' => 3224,
					'ids' => $pulsanti,
					'showposts' => 3,
				);
  				echo render_view( $args2 );
		?>

Right now $pulsanti only contains the RFG post_ids for the last event found in the loop and nothing is being displayed in terms of an event on the front end.

#1076489

Okay it looks like you are defining the $pulsanti variable inside the loop. When you do that, each iteration of the loop overwrites the previous iteration. Instead, initialize the variable as an array outside the loop. Then inside the loop, push the results onto that array, like this:

<?php  
$pulsanti = array();
foreach( $posts as $post): // variable must be called $post (IMPORTANT) ?>
    <?php setup_postdata($post);
    $event_id = get_the_ID(); 

    $event_ids .= "$event_id,"; ?>
     
    <?php

    $pulsanti[]= toolset_get_related_posts(
      $event_id,        // the parent RFG
      'event_dates',  // the RFG slug
      'parent',     // the sezioni role in this relationship is 'parent'
      1000000,     // the maximum number of results
      0,           // the offset
      array(),     // additional query arguments
      'post_id',   // return format
      'child'    // role to return
    );
    ?>
     
<?php endforeach; ?>

Now the loop appends results to the $pulsanti array instead of overwriting them. If this doesn't get the results you expect, I'll need to take a closer look.

#1076492

Thanks!

I printed the array and now have this:

Array ( [0] => Array ( [0] => 1463 ) [1] => Array ( [0] => 1419 ) [2] => Array ( [0] => 1437 [1] => 1438 ) )

hidden link

How do I feed this into a View now to return events to the page?

#1076502

Merge those arrays after the endforeach:

<?php endforeach; ?>
<?php 
$pulsanti = array_merge(... $pulsanti);
?>

Now you should have a single, flat array of post IDs:
[1463,1419,1437,1438]

You can pass the $pulsanti variable into the ids attribute of a render_view function.

#1076508
Edit View ‹ Cohen Seglias — WordPress.png

Okay, now I've:

Array ( [0] => 1463 [1] => 1419 [2] => 1437 [3] => 1438 )

How do I adjust my view now? Screenshot attached

The code calling the view looks like this:

$args2 = array(
'id' => 3224,
'ids' => $pulsanti,
'showposts' => 3,
);
echo render_view( $args2 );