WP使用WP查询获取父级的所有子页面


13

这是我的代码

$my_wp_query = new WP_Query();
$all_wp_pages = $my_wp_query->query(array('post_type' => 'page','post_parent'=>$parid,'orderby'=>'title','order'=>'ASC' ));

它仅显示第一级子页面。我需要所有子页面,子页面的子页面...以及全部。我搜索了一个解决方案,并且可以使用get_pages和wp_list_pages获取所有子页面。

但是我确实需要按自定义发布元值对订单进行排序。所以我必须使用自定义查询。

请帮忙。谢谢


1
在下面您说找到答案了,这是什么?
德鲁·贝克

4
您检查过get_page_children吗?
t31os 2013年

Answers:


6

为什么不只是使用get_pages()

例如

<?php
// Determine parent page ID
$parent_page_id = ( '0' != $post->post_parent ? $post->post_parent : $post->ID );
// Get child pages as array
$page_tree_array = get_pages( array(
    'child_of' => $parent_page_id;
) );
?>

但是,如果确实必须将其作为WP_Query()对象,则使用类似的方法:

<?php
// Determine parent page ID
$parent_page_id = ( '0' != $post->post_parent ? $post->post_parent : $post->ID );
// Build WP_Query() argument array
$page_tree_query_args = array(
    'post_parent' => $parent_page_id;
);
// Get child pages as a WP_Query() object
$page_tree_query = new WP_Query( $page_tree_query_args );
?>

如果使用get_pages()功能,则无法对自定义字段实施排序(sort_column)。它仅接受发布表字段。我需要实现自定义字段的排序。所以只有我使用wp query()。还有其他方法吗?
phpuser 2011年

您是否看到了我使用的答案的后半部分WP_Query()
Chip Bennett

我尝试了这段代码,但它仅返回第一级子页面。我需要子页面>>子的子>>等...(多个较低级别的页面。)。终于我找到了解决方案。感谢您的答复
phpuser 2011年

7
您有什么解决方案!?
JCHASE11 2013年

上面的数组定义内有一些分号会导致语法错误。
ptrin

4

问题

您在掌握问题时遇到的问题是“我怎么做X?” 这不是第一步操作,而是一个多步骤过程,需要分解。

您不需要这样做:

get all the posts that are a child of X ordered by meta

您需要这样做:

get all the posts that are a child of X
    for each child, get all the posts that are a child
        foreach child of that child get all the posts that are a child
            ...
                hmmm we don't have any more children left

Take our list of posts and order them by meta

通用解决方案

因此,要了解如何无限执行直到结束,而无需对其进行硬编码,则需要了解递归函数。

例如

function make_zero( $amount ) {
    $amount = $amount - 1;
    if ( $amount > 1 ){
        return make_zero( $amount );
    }
    return $amount;
}

将递归应用于此问题以寻求解决方案

因此,您的父母是$parid,并且您的帖子元密钥为$metakey

让我们将其传递给一个函数以获取其子级。

$children = get_children_with_meta( $parid, $metakey );

然后,我们将对$ children数组进行排序,键将是发布ID,而值将是元值。

asort($children);

并将函数定义为:

function get_children_with_meta( $parent_id, $metakey ) {
    $q = new WP_Query( array( 'post_parent' => $parent_id, 'meta_key' => $metakey ));
    if ( $q->have_posts() ) {
        $children - array();
        while ( $q->have_posts() ) {
            $q->the_post();
            $meta_value = get_post_meta(get_the_ID(), $metakey, true );
            $children[get_the_ID() ] = $meta_value;
        }
        return $children;
    } else {
        // there are no children!!
        return array();
    }
}

这为您提供了一个帖子ID和值的数组,按从低到高的顺序排列。您可以使用其他PHP排序功能从最高到最低进行排序。

现在孩子们的孩子呢?

在循环的中间,我们需要进行递归调用,传入子代而不是父代ID。

所以这:

$q->the_post();
$meta_value = get_post_meta(get_the_ID(), $metakey, true );
$children[get_the_ID() ] = $meta_value;

变成这个:

$q->the_post();
$meta_value = get_post_meta(get_the_ID(), $metakey, true );
$children[get_the_ID() ] = $meta_value;

// now get the childrens children
$grandchildren = get_children_with_meta( get_the_ID(), $metakey );

// merge the grandchildren and the children into the same list
$children = array_merge( $children, $grandchildren );

通过此修改,该功能现在可以检索孩子,孩子的孩子,孩子的孩子的孩子……等

最后,您可以修剪数组上的值以获取如下所示的ID:

$post_ids = array_keys( $children );
$q = new WP_Query( array( 'post__in' => $post_ids );
// etc

使用此策略,您可以将meta键值替换为任何其他指标,或者以其他方式使用递归函数。

由于完整的代码只需要几秒钟的基本理解和快速的复制粘贴,因此我不会用完整的复制粘贴代码块来侮辱您的智慧。

优点

  • 修改后适用于任何帖子类型和数据形式
  • 可以修改以生成嵌套标记
  • 通过将返回的数组置于瞬态状态,轻松缓存以加快速度
  • 可以通过将分页应用于末尾WP_Query来进行分页设置

您会遇到的问题

  • 在找到孩子之前,您无法知道他们有多少个孩子,因此性能成本不会增加
  • 您想要的内容会产生很多查询,并且由于涉及的潜在深度,其固有的成本很高。

我的建议

我建议您要么展平页面层次结构,要么改用分类法。例如,如果您要对帖子进行评分,请使用第1,2、3、4和5等术语进行页面评分分类。这将为您提供开箱即用的帖子列表。

或者,使用导航菜单并完全绕开此问题


3

递归获取所有当前子页面

这是使用的递归方法get_children。将以下内容放入您的functions.php

function get_all_subpages($page, $args = '', $output = OBJECT) {
    // Validate 'page' parameter
    if (! is_numeric($page))
        $page = 0;

    // Set up args
    $default_args = array(
        'post_type' => 'page',
    );
    if (empty($args))
        $args = array();
    elseif (! is_array($args))
        if (is_string($args))
            parse_str($args, $args);
        else
            $args = array();
    $args = array_merge($default_args, $args);
    $args['post_parent'] = $page;

    // Validate 'output' parameter
    $valid_output = array(OBJECT, ARRAY_A, ARRAY_N);
    if (! in_array($output, $valid_output))
        $output = OBJECT;

    // Get children
    $subpages = array();
    $children = get_children($args, $output);
    foreach ($children as $child) {
        $subpages[] = $child;

        if (OBJECT === $output)
            $page = $child->ID;
        elseif (ARRAY_A === $output)
            $page = $child['ID'];
        else
            $page = $child[0];

        // Get subpages by recursion
        $subpages = array_merge($subpages, get_all_subpages($page, $args, $output));
    }

    return $subpages;
}

如何使用它

可以在任何需要的地方使用上述功能,例如:

$all_current_subpages = get_all_subpages(0);

该函数确实支持args参数(查询字符串或数组)和output类型(请参见上文)。

因此,您也可以像这样使用它:

$args = array(
    'post_status' => 'private',
    'order_by' => 'post_date',
    'order' => 'DESC',
);
$all_current_subpages = get_all_subpages(42, $args, ARRAY_A);

由于依赖关系get_children=> get_posts=>,WP_Query您可以使用此问题的作者最初要求的元值。



2

我做了一个递归函数,它获取父页面的所有子代ID。获得ID后,我们将查询页面,并可以按meta键/值对结果进行排序。

// Gets all the children ids of post_parent
function _get_children_ids( $post_parent ) {
    $results = new WP_Query( array(
        'post_type' => 'page',
        'post_parent' => $post_parent
    ) );

    $child_ids = array();
    if ( $results->found_posts > 0 )
        foreach ( $results->posts as $post ) // add each child id to array
            $child_ids[] = $post->ID;

    if ( ! empty( $child_ids ) )
        foreach ( $child_ids as $child_id ) // add further children to array
            $child_ids = array_merge( $child_ids, _get_children_ids( $child_id ) );

    return $child_ids;
}

$children_ids = _get_children_ids( 9 ); // use your numeric page id or get_the_id()

$results = new WP_Query( array(
    'post_type'   => 'page',
    'post__in'   => $children_ids
    #'meta_key'   => 'meta_key', // your meta key
    #'orderby'    => 'meta_key',
    /* 'meta_query' => array( // optional meta_query
        array(
            'key' => 'meta_key', // key
            'value' => array(3, 4), // values
            'compare' => 'IN', // operator
        )
    ) */
) );

var_dump( $results );

如果需要按元键/值对子级进行分层排序,则应将meta_key和order_by值传递给_get_children_ids函数中的WP_Query(而不是最终的WP_Query)。

如果不是,则获取所有子ID的更简单方法是:

$children = get_pages( 'child_of=9');

$children_ids = array();
if ( ! empty( $children ) )
    foreach ( $children as $post )
        $children_ids[] = $post->ID;

-1

我需要进行此工作,只需将代码粘贴到您的PAGE.PHP文件中

//REDIRECT TO FIRST CHILD FROM PARENT PAGE

// Build WP_Query() argument array
$page_tree_query_args = array(
    'post_parent' => $post -> ID,
    'post_type' => 'page',
    'order' => 'asc'
);
// Get child pages as a WP_Query() object
$page_tree_query = new WP_Query( $page_tree_query_args );
if(!empty($page_tree_query -> posts)){
    $first_subpage = $page_tree_query -> posts[0] -> ID;
    wp_redirect( get_permalink( $first_subpage ) );
    exit;   
}

这是A)不能正常工作($post -> ID?),B)没有要求什么,C)没有很好地解释。
tfrommen 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.