Support

Account

Home Forums Feature Requests Add condition: page parent for custom post types

Solved

Add condition: page parent for custom post types

  • If you could add a condition to set page-parent ID also for custom post types and not only pages, it would be awesome. Currently if you set condition to “Page parent”, one can only choose from pages. But not from any other hierarchical custom post types 🙁

  • Created a workaround for this by adding a new selection called “custom post types”

    If anyone else need it, or have a suggestion on how to improve it, feel free to hollar 🙂

    add_filter('acf/location/rule_types', 'acf_location_rules_types');
    function acf_location_rules_types( $choices )
    {
        $choices['Custom Post types']['cpt_parent'] = 'Custom post type parent';
     
        return $choices;
    }
    add_filter('acf/location/rule_values/cpt_parent', 'acf_location_rules_values_cpt_parent');
    function acf_location_rules_values_cpt_parent( $choices )
    {
    	$args = array(
    		'hierarchical' => true,
    		'_builtin' => false
    	);
        $posttypes = get_post_types( $args );
     
        if( $posttypes )
        {
            foreach( $posttypes as $posttype ):
            
    if( $posttype != 'acf' ):
    $args = array(
    'post_type' => $posttype,
    'posts_per_page' => -1,
    'post_status' => 'publish'
    );
    $customposts = get_posts( $args );  
    if ( $customposts  ) {
    foreach( $customposts as $custompost ){
    $choices[ $custompost->ID] = $custompost->post_title;
    }
    }
    endif;
            endforeach;
        }
     
        return $choices;
    }
  • Hey so i’ve pasted this and just seem to get the name of hierarchical CPT but not the posts in them. Iv’e tried selecting the post before this on location options and still I just get these options, is this what it’s meant for? if so, can you guide me through listing the posts inside these Custom Post Types?

  • Piojos: I’ve updated the above code. It should now display all custom posts. I have not testet the code though.. But I guess you get the point when you have a look at it. You might wanna add some kind of seperator or alternate display method to show the post types which the posts belong to.

  • Oh!! It works, thank you so much, it does show every hierarchical post in every CPT listed. I haven’t got that far on php but I’ll try and work on it this weekend to see it separated by each CPT.

    This is great thou, thanks!

  • The code above was missing the $match rules so although you could see the correct pages in the location rules, the ACF rule wouldn’t get applied to anything. This should work:

    /*
    * ACF post parent
    */
    
    add_filter('acf/location/rule_types', 'acf_location_rules_types');
    function acf_location_rules_types( $choices )
    {
        $choices['Custom Post types']['cpt_parent'] = 'Custom post type parent';
     
        return $choices;
    }
    add_filter('acf/location/rule_values/cpt_parent', 'acf_location_rules_values_cpt_parent');
    function acf_location_rules_values_cpt_parent( $choices )
    {
    	$args = array(
    		'hierarchical' => true,
    		'_builtin' => false
    	);
        $posttypes = get_post_types( $args );
     
        if( $posttypes )
        {
            foreach( $posttypes as $posttype ):
            
    			if( $posttype != 'acf' ):
    				$args = array(
    				'post_type' => $posttype,
    				'posts_per_page' => -1,
    				'post_status' => 'publish'
    				);
    				$customposts = get_posts( $args );  
    				if ( $customposts  ) {
    					foreach( $customposts as $custompost ){
    						$choices[ $custompost->ID] = $custompost->post_title;
    					}
    				}
    			endif;
    		endforeach;
    	}
     
        return $choices;
    }
    
    //MATCH THE RULE
    add_filter('acf/location/rule_match/cpt_parent', 'acf_location_rules_match_cpt_parent', 10, 3);
    function acf_location_rules_match_cpt_parent( $match, $rule, $options )
    {
    	
    	global $post;
    	$selected_post = (int) $rule['value'];
    
    	// post parent
    	$post_parent = $post->post_parent;
    	if( $options['page_parent'] ) {
    	
        	$post_parent = $options['page_parent'];
        	
    	}
    
    	if ($rule['operator'] == "=="){
    		$match = ( $post_parent == $selected_post );
    	}
    	elseif ($rule['operator'] != "!="){
    		$match = ( $post_parent != $selected_post );
    	}
     
        return $match;
    }
  • I fixed the rule_match function operator for != matches. It was set to

    elseif ($rule['operator'] != "!="){

    Instead of

    elseif ($rule['operator'] == "!="){

    This now works for me:

    /*
    ACF POST PARENT
    */
    add_filter('acf/location/rule_types', 'acf_location_rules_types');
    function acf_location_rules_types( $choices ) {
        $choices['Custom Post Types']['cpt_parent'] = 'Custom Post Type Parent';
        return $choices;
    }
    add_filter('acf/location/rule_values/cpt_parent', 'acf_location_rules_values_cpt_parent');
    function acf_location_rules_values_cpt_parent( $choices ) {
    	$args = array(
    		'hierarchical' => true,
    		'_builtin' => false,
    		'public' => true
    	);
        $posttypes = get_post_types( $args );
    
        if( $posttypes )
        {
            foreach( $posttypes as $posttype ):
    
    			if( $posttype != 'acf' ):
    				$args = array(
    				'post_type' => $posttype,
    				'posts_per_page' => -1,
    				'post_status' => 'publish'
    				);
    				$customposts = get_posts( $args );
    				if ( $customposts  ) {
    					foreach( $customposts as $custompost ){
    						$choices[ $custompost->ID] = $custompost->post_title;
    					}
    				}
    			endif;
    		endforeach;
    	}
    
        return $choices;
    }
    
    //MATCH THE RULE
    add_filter('acf/location/rule_match/cpt_parent', 'acf_location_rules_match_cpt_parent', 10, 3);
    function acf_location_rules_match_cpt_parent( $match, $rule, $options ) {
    
    	global $post;
    	$selected_post = (int) $rule['value'];
    
    	// post parent
    	if($post) {
      	$post_parent = $post->post_parent;
      	if( $options['page_parent'] ) {
          	$post_parent = $options['page_parent'];
      	}
      	if ($rule['operator'] == "=="){
      		$match = ( $post_parent == $selected_post );
      	}
      	elseif ($rule['operator'] == "!="){
      		$match = ( $post_parent != $selected_post );
      	}
    	}
      return $match;
    
    }
  • Thanks @ethicka , confirmed working on ACF Pro latest

  • This was a super helpful piece of code. I made one small addition which is to allow for an option for “No Parent” i.e. when the current custom post has no parent set. This was literally one line but I also made some tiny cleanups to the code so I’ve included it below.

    Thanks again!

    function acf_location_rules_types($choices) {
        $choices['Custom Post Types']['cpt_parent'] = 'Custom Post Type Parent';
        return $choices;
    }
    add_filter('acf/location/rule_types', 'acf_location_rules_types');
    
    function acf_location_rules_values_cpt_parent($choices) {
    	$args = array(
    		'hierarchical' => true,
    		'_builtin' => false,
    		'public' => true
    	);
    	$hierarchical_posttypes = get_post_types($args);
    	foreach($hierarchical_posttypes as $hierarchical_posttype) {
    		if ('acf' !== $hierarchical_posttype) {
    			$choices[0] = __('No Parent');
    			$args = array(
    				'post_type' => $hierarchical_posttype,
    				'posts_per_page' => -1,
    				'post_status' => 'publish'
    			);
    			$customposts = get_posts($args);
    			foreach ($customposts as $custompost) {
    				$choices[$custompost->ID] = $custompost->post_title;
    			}
    		}
    	}
    	return $choices;
    }
    add_filter('acf/location/rule_values/cpt_parent', 'acf_location_rules_values_cpt_parent');
    
    function acf_location_rules_match_cpt_parent($match, $rule, $options) {
    	global $post;
    	$selected_post = (int) $rule['value'];
    	if ($post) { // post parent
    		$post_parent = $post->post_parent;
    		if ($options['page_parent']) {
    			$post_parent = $options['page_parent'];
    		}
    		if ('==' == $rule['operator']) {
    			$match = ($post_parent == $selected_post);
    		} elseif ('!=' == $rule['operator']) {
    			$match = ($post_parent != $selected_post);
    		}
    	}
      return $match;
    }
    add_filter('acf/location/rule_match/cpt_parent', 'acf_location_rules_match_cpt_parent', 10, 3);
Viewing 9 posts - 1 through 9 (of 9 total)

The topic ‘Add condition: page parent for custom post types’ is closed to new replies.