是否使用WP_QUERY返回父帖子及其子帖子?

时间:2016-03-23 作者:luukvhoudt

在某些情况下,使用多个post&;可能有用;中的页面参数WP_Query 对象在我的例子中,我希望显示父页面的子页面,包括父页面本身。

可视化我想要实现的目标。设想以下页面按层次结构排序如下:

第A页page B

  • Child page A
  • Child page B
  • Child page Cbold list items 是我要检索的帖子/页面。

    我的第一个想法是使用以下两个参数WP_Query:

    $args = array(
       \'post_id\' => $parent->ID,
       \'post_parent\' => $parent->ID,
    );
    
    不幸的是,这里它只使用一个参数。使用$args 上面(如果我错了请更正)它将输出父帖子的所有子帖子和not 父帖子本身也是如此。

    这个问题可以通过收集所有需要的帖子并将它们放入参数中来解决post__in 像这样:

    $args = array(
       \'post__in\' => $children_and_parent_ids,
    );
    
    然而,有wp_list_pages() 允许您include 并指定要在其中包含的子级的帖子(child_of). 为什么WP_Query?

    我试图通过使用wp_list_pages():

    wp_list_pages(array(
        \'include\' => $parent->ID,
        \'child_of\' => $parent->ID,
    ));
    
    看看the documentation 属于WP_Query.

6 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

我们可以过滤posts_where 子句来返回父帖子/页,而不仅仅是父帖子/页的子帖子/页。在这里,我们将设置自己的自定义参数wpse_include_parent, 当设置为true, 将相应地更改生成的SQL。

我们需要做的就是posts_where 筛选器用于检查是否设置了自定义参数,以及post_parent 参数已设置。然后,我们获取该值并将其传递给过滤器以扩展SQL查询。这里有什么好东西,post_parent 除非只有一个整数值,所以我们只需要将该值验证为整数。

查询

$args = [
    \'wpse_include_parent\' => true,
    \'post_parent\'         => 256,
    \'post_type\'           => \'page\'
    // Add additional arguments
];
$q = new WP_Query( $args );
正如你所看到的,我们已经\'wpse_include_parent\' => true “激活”我们的过滤器。

过滤器

add_filter( \'posts_where\', function ( $where, \\WP_Query $q ) use ( &$wpdb )
{
    if ( true !== $q->get( \'wpse_include_parent\' ) )
        return $where;

    /**
     * Get the value passed to from the post parent and validate it
     * post_parent only accepts an integer value, so we only need to validate
     * the value as an integer
     */
    $post_parent = filter_var( $q->get( \'post_parent\' ), FILTER_VALIDATE_INT );
    if ( !$post_parent )
        return $where;

    /** 
     * Lets also include the parent in our query
     *
     * Because we have already validated the $post_parent value, we 
     * do not need to use the prepare() method here
     */
    $where .= " OR $wpdb->posts.ID = $post_parent";

    return $where;
}, 10, 2 );
你可以根据自己的需要进行扩展,但这是最基本的想法。这将返回传递给的父级post_parent 是孩子们

SO网友:Adam

如果您只想得到“page”post\\u类型的结果,请按照@birgire的建议执行。

或者,您可以调整以下内容,以获得类似的结果page post_type 但任何自定义帖子类型。

$parent = 2;      //change as desired
$type   = \'page\'; //change as desired

$child_args = array( 
    \'post_type\'   => $type, 
    \'post_parent\' => $parent 
);

$ids = array($parent);
$ids = array_merge($keys, array_keys( get_children( $child_args ) ));

$query = new WP_Query( 
    array( 
        \'post_type\'      => \'page\', 
        \'post_status\'    => \'publish\', 
        \'post__in\'       => $ids, 
        \'posts_per_page\' => -1 
    ) 
);
上述内容本质上与挂在posts_where 过滤和解析SQL子句但是,这实现了完全相同的功能。

SO网友:luukvhoudt

使用global $wpdb 与…结合[get_results()][1] 也是一种选择。性能方面,我认为这是最好的解决方案,因为它只运行一个查询。

这是我的最终代码。

<ul class="tabs"><?php

    global $wpdb, $post;

    $parent = count(get_post_ancestors($post->ID))-1 > 0 ? $post->post_parent : $post->ID;

    $sql = "SELECT ID FROM `{$wpdb->prefix}posts`";
    $sql.= " WHERE ID=\'{$parent}\' OR post_parent=\'{$parent}\' AND post_type=\'page\'";
    $sql.= " ORDER BY `menu_order` ASC";

    $tabs = $wpdb->get_results($sql);

    $output = \'\';
    foreach ($tabs as $tab) {
        $current = $post->ID == $tab->ID ? \' class="active"\' : \'\';

        $output .= \'<li\'.$current.\'>\';
        $output .= empty($current) ? \'<a href="\'.get_permalink($tab->ID).\'">\' : \'\';
        $output .=   get_the_post_thumbnail($tab->ID, \'menu-24x24\');
        $output .=   \'<span>\'.get_the_title($tab->ID).\'</span>\';
        $output .= empty($current) ? \'</a>\' : \'\';
        $output .= \'</li>\';
    }
    print $output;

?></ul>

SO网友:EBennett

如果我理解正确,您希望获得父页面和任何后续子页面的ID。Wordpress具有获取页面子级的函数,例如:

https://codex.wordpress.org/Function_Reference/get_page_children

我的理解是,由于您正在执行WP\\u查询,您已经在获取父页面的ID,因此您所需要做的就是将相关ID传递给上述函数,以获得所需的内容。

注意:我应该指出,此函数不执行DB查询,因此性能更好,因为您只对DB进行查询。

SO网友:egauvin

    $args = array(
        \'post_type\' => \'tribe_events\',
        \'posts_per_page\' => \'-1\',
        \'orderby\' => \'ID\',
        \'order\' => \'ASC\',
        \'post_parent\' => $postID,
    );

    $children = new WP_Query($args);
    $parent[] = get_post($postID);
    $family = array_merge($parent, $children->get_posts());
这似乎奏效了。评论?

SO网友:Lalji Nakum

您可以使用get_pages() 具有child_of 参数如下:

<?php
   get_pages( array(
     \'child_of\' => $parent_page_id;
   ) );
?>