您的结果正在发生变化get_ancestors() 或者某些内容正在更改您的查询,当在页面上查询时,会将子页面“更改”为孙页面。从评论中也可以看出,帖子ID在页面上并没有保持不变。
我从更新的代码中立即注意到的是,自定义查询在完成后不会重置。你必须记住,the_post() 设置$post 全局到循环中循环的当前帖子,循环完成后,$post 将保留循环的最后一个post对象。
您可以添加var_dump( $post ); 在当前代码之前和之后,您将看到$post 不同。这就是为什么你必须always 完成后重置自定义查询。只需添加wp_reset_postdata(); 直接在之后endwhile 就在之前endif. 正在执行var_dump( $post ); 现在,循环前后应该呈现相同的值。
$post 是一个全局变量,它会被许多事情改变,而错误代码(如您问题中的代码)会改变$post global,这反过来又会返回错误的信息,这反过来又会让你大吃一惊,想找出原因。更可靠的方法是使用get_queried_object() 返回当前页面对象。有关解释,请随时查看my question 答案接受了@gmazzap的回答。注意,尽管这是可靠的,query_posts 断开保存查询对象的主查询对象。
我还注意到,您硬编码ID,不要这样做。每个帖子/页面都有post_parent 所有物如果帖子类型是非层次结构的,如帖子,则post_parent 值始终为0 因为非层次结构的帖子类型没有任何层次结构。像页面这样的分层帖子类型0 像post_parent 如果它是顶级页面,或者如果它是子/孙页面,则具有数字值,则post_parent 将表示页面直接父级的ID。
要正确获取正在查看的页面的页面id,请使用get_queried_object()->ID 或get_queried_object_id() 而不是$post->ID.
要获取正在查看的当前页面的即时post父ID,请使用get_queried_object()->post_parent
要获取顶级父级,请使用end( get_ancestors( get_queried_object()->ID, \'page\' ) ). 请记住,顶级父级将是返回的ID数组中的最后一个IDget_ancestors, 第一个ID将是直接父级。
要重写代码,请使用类似的方法获取所查看页面的直接子级:
$page_object = get_queried_object();
// Check if page is top level or not and set $args accordingly
if ( $page_object->post_parent == 0 ) { // Top level page
$parent_ID = (int) $page_object->ID;
} else { // Page is a child/grandchild page
$parent_ID = (int) $page_object->post_parent;
}
// Setup query args
$args = [
\'post_parent\' => $parent_ID,
\'post_type\' => \'page\'
];
$q = new WP_Query( $args );
if ( $q->have_posts() ) {
while ( $q->have_posts() ) {
$q->the_post();
// Run your code to display posts
}
wp_reset_postdata(); // EXTEMELY IMPORTANT!!!!!!!
}
总之,要确定页面的当前层次结构,请执行以下操作
$current_page = get_queried_object();
if ( $current_page->post_parent == 0 ) {
echo \'This is a parent\';
} else {
$hierarchy = get_ancestors( $current_page->ID, \'page\' );
$count = count( $hierarchy );
$child = ( $count == 1 ) ? \'child\' : \'grandchild\';
echo \'This is a \' . $child . \' page\';
}