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

回答:


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

私が使用する私の答えの後半を見ましたWP_Query()か?
チップベネット

このコードを試しましたが、最初のレベルのサブページのみを返します。サブページ>>サブのサブ>>など...(複数の下位レベルのページ)が必要です。最後に、私は解決策を見つけました。ご返信いただきありがとうございます
phpuser

7
あなたの解決策は何ですか!?
JCHASE11

上記の配列定義の中には、構文エラーを引き起こすセミコロンがいくつかあります。
ptrin 14年

4

問題

把握に問題があるのは、「どうすればXを実行できますか」です。これは1ステップのアクションではなく、複数ステップのプロセスであり、分解する必要があります。

これを行う必要はありません:

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

この戦略を使用すると、メタキー値を他のメトリックに置き換えるか、他の方法で再帰関数を使用できます。

完全なコードは数秒の基本的な理解と簡単なコピーペーストのみを必要とするため、コードの完全なコピーペーストブロックであなたの知性をin辱しません。

長所

  • すべての投稿タイプおよびデータ形式の修正が有効
  • ネストされたマークアップを生成するように変更できます
  • 返された配列を一時的に配置することにより、簡単にキャッシュして高速化する
  • WP_Queryの最後にページングを適用することにより、ページングでセットアップできます

遭遇する問題

  • あなたは彼らを見つけるまで子供の数を知る方法がないので、パフォーマンスのコストはスケーリングしません
  • あなたが望むものは多くのクエリを生成し、潜在的な深さのために本質的にコストがかかります。

私の推薦

ページ階層をフラットにするか、代わりに分類法を使用することをお勧めします。たとえば、投稿を評価する場合は、1、2、3、4、5などの用語でページ評価の分類を行います。これにより、すぐに投稿の一覧が表示されます。

または、navメニューを使用して、この問題を完全に回避します


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を取得したら、ページのクエリを作成し、メタキー/値で結果を並べ替えることができます。

// 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 );

子をメタキー/値で階層的に並べ替える必要がある場合は、_get_children_ids関数でWP_Queryにmeta_keyとorder_byの値を渡す必要があります(最後の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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.