Wp pobierz wszystkie podstrony rodzica za pomocą zapytania wp

13

Oto mój kod

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

Wyświetla tylko strony podrzędne pierwszego poziomu. Potrzebuję całej podstrony, podstrony podrzędnej ... i wszystkich. Szukałem rozwiązania i mogę pobrać wszystkie podstrony za pomocą get_pages i wp_list_pages.

Ale naprawdę muszę posortować zamówienie według niestandardowej wartości meta post. Więc muszę użyć niestandardowego zapytania.

proszę pomóż. Dzięki

phpuser
źródło
1
Poniżej mówisz, że znalazłeś odpowiedź, co to jest?
Drew Baker,
4
Czy sprawdziłeś get_page_children ?
t31os

Odpowiedzi:

6

Dlaczego nie po prostu użyć get_pages()?

na przykład

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

Ale jeśli naprawdę musi to być WP_Query()obiekt, użyj podobnej metody:

<?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 );
?>
Chip Bennett
źródło
Jeśli użyjemy funkcji get_pages (), nie będziemy mogli zaimplementować sortowania (sort_column) dla pól niestandardowych. Akceptuje tylko pola tabeli postu. Muszę zaimplementować sortowanie dla pola niestandardowego. Więc tylko używam zapytania wp (). Czy jest jakiś alternatywny sposób?
phpuser,
Czy widziałeś drugą połowę mojej odpowiedzi, w której korzystam WP_Query()?
Chip Bennett
Próbowałem tego kodu, ale zwraca on tylko strony podrzędne pierwszego poziomu. Potrzebuję podstrony >> podsieci pod >> >> ... (wiele niższych poziomów stron.). Wreszcie znalazłem rozwiązanie. Dzięki za odpowiedź
phpuser
7
jakie jest twoje rozwiązanie !?
JCHASE11
W powyższych definicjach tablic znajdują się średniki powodujące błędy składniowe.
ptrin
4

Problem

Problem z chwytaniem to „Jak zrobić X?” To nie jest jednoetapowe działanie, to wieloetapowy proces i należy go rozdzielić.

Nie musisz tego robić:

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

Musisz to zrobić:

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

Ogólne rozwiązanie

Tak więc, aby zrozumieć, jak to robić w nieskończoność, dopóki nie osiągniesz końca, bez twardego kodowania, musisz zrozumieć funkcje rekurencyjne.

na przykład

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

Zastosowanie rekurencji do tego problemu w celu rozwiązania

Więc twój rodzic jest $parid, a twoja meta post ma klucz $metakey.

Przekazujemy go do funkcji, aby złapać swoje dzieci.

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

Następnie posortujemy tablicę $ dzieci, klucze będą identyfikatorami postów, a wartości będą meta wartościami.

asort($children);

i pozwala zdefiniować funkcję jako:

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();
    }
}

Daje to tablicę identyfikatorów postów i wartości, uporządkowanych od najniższej do najwyższej. Możesz użyć innych funkcji sortowania PHP, aby to zrobić od najwyższej do najniższej.

Co teraz z dziećmi dla dzieci?

W środku naszej pętli musimy wykonać połączenie rekurencyjne, przekazując dziecko, a nie identyfikator rodzica.

Więc to:

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

Staje się to:

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

Dzięki tej modyfikacji funkcja pobiera teraz dzieci, dzieci dzieci, dzieci dzieci ..... itd

Na koniec możesz przyciąć wartości z tablicy, aby uzyskać takie identyfikatory:

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

Korzystając z tej strategii, możesz zastąpić wartość klucza meta dowolną inną metryką lub użyć funkcji rekurencyjnych na inne sposoby.

Ponieważ pełny kod wymaga tylko kilku sekund podstawowego zrozumienia i szybkiego wklejenia, nie obrażę twojej inteligencji blokiem wklejania pełnego kodu.

Zalety

  • Dzięki modyfikacji działa na dowolny typ postu i formę danych
  • Można go zmodyfikować, aby wygenerować zagnieżdżone znaczniki
  • Łatwo buforuj, aby przyspieszyć, umieszczając zwrócone tablice w stanach nieustalonych
  • Może być skonfigurowany ze stronicowaniem poprzez zastosowanie stronicowania na końcu WP_Query

Problemy, które napotkasz

  • Nie możesz dowiedzieć się, ile jest dzieci, dopóki ich nie znajdziesz, więc koszty wydajności nie są skalowane
  • To, czego chcesz, wygeneruje wiele zapytań i jest z natury kosztowne z uwagi na potencjalną głębokość.

Moja rekomendacja

Polecam albo spłaszczyć hierarchię stron, albo zastosować taksonomię. Np. Jeśli oceniasz posty, zastosuj taksonomię oceny strony z terminami 1,2,3,4 i 5 itd. W ten sposób otrzymasz post z pudełka.

Możesz też użyć menu nawigacji i całkowicie ominąć ten problem

Tom J Nowell
źródło
3

Rekurencyjnie pobierz wszystkie bieżące podstrony

Oto podejście rekurencyjne przy użyciu get_children. Umieść w swoim 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;
}

Jak tego użyć

Użyj powyższej funkcji w dowolnym miejscu, na przykład w następujący sposób:

$all_current_subpages = get_all_subpages(0);

Ta funkcja obsługuje argsparametr (ciąg zapytania lub tablicę) i outputtyp (patrz wyżej).

Możesz więc użyć go w następujący sposób:

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

A ze względu na zależność get_children=> get_posts=> WP_Querymożesz używać meta wartości, jak początkowo zażądał autor tego pytania.

tfrommen
źródło
2

Zrobiłem funkcję rekurencyjną, która pobiera wszystkie identyfikatory potomne strony nadrzędnej. Po uzyskaniu identyfikatorów wykonujemy zapytanie o strony i możemy uporządkować wyniki według meta klucza / wartości.

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

Jeśli chcesz posortować dzieci według meta klucza / wartości w sposób hierarchiczny, powinieneś przekazać meta_key i wartości order_by do WP_Query w funkcji _get_children_ids (zamiast końcowej WP_Query).

Jeśli nie, prostszą metodą uzyskania całego identyfikatora potomnego jest:

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

$children_ids = array();
if ( ! empty( $children ) )
    foreach ( $children as $post )
        $children_ids[] = $post->ID;
Nicü
źródło
-1

ROBIĘ TEN PRACĘ, TYLKO KOPIUJ WKLEJ KOD DO SWOJEJ STRONY.

//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;   
}
Bipin Sapkota
źródło
To jest A) nie działa ( $post -> ID?), B) nie to, o co został poproszony, C) nie wyjaśniono zbyt dobrze.
tfrommen