Home › Forums › Feature Requests › 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;
}
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);
You must be logged in to reply to this topic.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Cookie Policy. If you continue to use this site, you consent to our use of cookies.