如何针对特定的自定义帖子类型帖子及其所有子孙帖子?

时间:2020-05-03 作者:Victor

我非常感谢您帮助创建一个函数,该函数将通过给定的$my_custom_post_type_name$post_name 和返回true 如果当前页面/帖子是$post_name$post_name_child$post_name_grandchild 等等,基于提供的父slug和自定义post类型。

假设结构如下:

my_custom_post_type_name

-first_page (example.com/my_custom_post_type_name/first_page)
--first_page_child
---first_page_grandchild
--first_page_child_2

-second_page
--second_page_child
---second_page_grandchild
我希望能够针对所有first_page 或其子女/孙子等。

类似于:

if( my_custom_function(\'my_custom_post_type_name\', \'first_page\') ){

//do stuff if the current page is \'first_page\' OR \'first_page_child\' OR \'first_page_grandchild\' OR \'first_page_child_2\'

}
经过一些研究,我得出以下结论(仍需更改first_page ID 成为一个鼻涕虫,摆脱in_array() 选中此复选框,以便自定义函数一次完成所有操作):

function get_posts_children($CPT, $parent_id){

        $children = array();
        $children[] = $parent_id;

        // grab the posts children
        $posts = get_posts( 
            array( 
                \'numberposts\' => -1, 
                \'post_status\' => \'publish\', 
                \'post_type\' => $CPT, 
                \'post_parent\' => $parent_id
            )
        );

        // now grab the grand children
        foreach( $posts as $child ){

            // call the same function again for grandchildren   
            $gchildren = get_posts_children($CPT, $child->ID);
            // merge the grand children into the children array
            if( ! empty($gchildren) ) {
                $children = array_merge($children, $gchildren);
            }
        }

        // merge in the direct descendants we found earlier
        $children = array_merge($children, $posts);

        return $children;
    }

//and then (where 3060 is the first_page ID):

global $post;

if( in_array( $post->ID, get_posts_children( \'my_custom_post_type_name\', 3060 ) ) ) {
  //do stuff. As it is now, it is working fine. But would really like to simplify it and to change the first_page ID to be a slug for obvious reasons.
}

2 个回复
最合适的回答,由SO网友:Victor 整理而成

好的,我找到了一个方法。我希望它能帮助那些面临同样问题的人。如果您想根据父slug或ID(两者都可以)和给定的帖子类型(custom\\u post\\u type或页面或帖子)仅针对特定帖子。

在这种情况下,仅影响:

my_custom_post_type_name

-first_page (example.com/my_custom_post_type_name/first_page)
--first_page_child
---first_page_grandchild
--first_page_child_2
但不影响:

my_custom_post_type_name

-second_page
--second_page_child
---second_page_grandchild
以下是您需要的功能:

function get_posts_children($CPT, $post_slug){

    //check if the $post_slug is a string.
    if(is_string($post_slug)){
        $parent_page_obj = get_page_by_path( $post_slug, \'\', $CPT );
        if ( ! empty( $parent_page_obj ) ) {
            $parent_id = $parent_page_obj->ID; //assign $parent_id to be an integer.
        }
    }

    //check if the $post_slug is an integer(ID) for when the function is calling itself (for grandchildren check).
    if( is_int ( $post_slug ) ){
        $parent_id = $post_slug; //if $post_slug is an integer assign it to $parent_id
    }

    $group = array();
    $group[] = $parent_id; //add $post_slug (in this case coverted to $parent_id already) to be a part of the array. (you can remove it if you only need the children and grandchildren of a given post ID or slug).

    // grab the direct children of the post by given $post_slug or post ID.
    $direct_children = get_posts( 
        array( 
            \'numberposts\' => -1, 
            \'post_status\' => \'publish\', 
            \'post_type\' => $CPT, 
            \'post_parent\' => $parent_id
        )
    );

    // now grab the grandchildren
    foreach( $direct_children as $child ){
        $grandchildren = get_posts_children($CPT, $child->ID); // call the same function again  for grandchildren   

        if( ! empty($grandchildren) ) {
            $group = array_merge($group, $grandchildren); // merge the grandchildren into the children array
        }
    }

    $group = array_merge($group, $direct_children); // merge in the $direct_children into the group array.

    return $group; //return an array of all the IDs found.
}
然后从任何地方定位这些帖子/页面,并将其与您需要的当前显示的页面/帖子进行比较:

global $post;

if(in_array($post->ID, get_posts_children(\'my_custom_post_type_name\', \'first_page\'))){
  //do something. If the current displayed page is \'first_page\' OR \'first_page_child\' OR \'first_page_grandchild\' OR \'first_page_grandchild\'.

  //But it will not affect if the current displayed page is \'second_page\' OR \'second_page_child\' OR \'second_page_grandchild\'.

  //This is handy to do many things. 
  //I\'m currently using it to redirect some specific custom user capabilities from restricted areas. 
  //But allowing them to access second_page and its children for that matter.    
}

SO网友:HU ist Sebastian

我想您应该检查活动页面是否为a)您的自定义帖子类型,b)其中一个祖先是您的参数。

首先,我建议你继续使用ID,因为slug和title可能不是唯一的,所以一个slug可能是不同的帖子。

其次,你可以使用wordpress自己的get_post_ancestors-作用使用方法如下:

function wpse365743_has_ancestor($postid,$ancestor_id){
  //get all parents and ancestors of $postid
  $ancestors = get_post_ancestors($postid);
  //add in the current post id
  $ancestors = array_merge(array($postid),$ancestors);
  //is the searched ancestor id in the ancestors?
  return in_array($ancestor_id,$ancestors); 
}
现在,您可以在页面上的任何位置使用此选项,如下所示:

if((\'my_post_type_name\' == get_post_type($check_post_id)) && wpse365743_has_ancestor($check_post_id,$searched_ancestor_id)){
   //do something
}
快乐的编码!