Ottenere tutte le sottopagine della pagina principale usando WP Query

30 nov 2011, 12:57:46
Visualizzazioni: 37.7K
Voti: 15

Ecco il mio codice

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

Questo mostra solo le sottopagine di primo livello. Ho bisogno di tutte le sottopagine, sottopagine delle sottopagine... e così via. Ho cercato una soluzione e posso ottenere tutte le sottopagine usando get_pages e wp_list_pages.

Ma ho davvero bisogno di ordinare in base al valore di un meta campo personalizzato. Quindi devo usare una query personalizzata.

Per favore aiutatemi. Grazie

2
Commenti

Qui sotto dici di aver trovato una risposta, qual è?

Drew Baker Drew Baker
17 ago 2012 21:41:18

Hai controllato get_page_children?

t31os t31os
13 apr 2013 16:17:47
Tutte le risposte alla domanda 6
5

Perché non usare semplicemente get_pages()?

Ad esempio:

<?php
// Determina l'ID della pagina genitore
$parent_page_id = ( '0' != $post->post_parent ? $post->post_parent : $post->ID );
// Ottieni le pagine figlie come array
$page_tree_array = get_pages( array(
    'child_of' => $parent_page_id;
) );
?>

Ma se deve assolutamente essere un oggetto WP_Query(), usa un metodo simile:

<?php
// Determina l'ID della pagina genitore
$parent_page_id = ( '0' != $post->post_parent ? $post->post_parent : $post->ID );
// Costruisci l'array di argomenti per WP_Query()
$page_tree_query_args = array(
    'post_parent' => $parent_page_id;
);
// Ottieni le pagine figlie come oggetto WP_Query()
$page_tree_query = new WP_Query( $page_tree_query_args );
?>
30 nov 2011 19:22:11
Commenti

Se utilizziamo la funzionalità get_pages() non potremmo implementare l'ordinamento (sort_column) per i campi personalizzati. Accetta solo i campi della tabella dei post. Ho bisogno di implementare l'ordinamento per un campo personalizzato. Ecco perché uso wp_query(). Esiste un metodo alternativo?

phpuser phpuser
1 dic 2011 06:07:29

Hai visto la seconda parte della mia risposta, in cui uso WP_Query()?

Chip Bennett Chip Bennett
1 dic 2011 15:59:53

Ho provato questo codice ma restituisce solo le sottopagine di primo livello. Ho bisogno di sottopagine >> sottopagine delle sottopagine >> ecc... (più livelli inferiori di pagine). Alla fine ho trovato la soluzione. Grazie per la tua risposta

phpuser phpuser
3 dic 2011 07:15:48

qual è la tua soluzione!?

JCHASE11 JCHASE11
11 mar 2013 22:12:57

Ci sono alcuni punti e virgola all'interno delle definizioni di array sopra che causano errori di sintassi.

ptrin ptrin
22 gen 2014 05:49:11
0

Il Problema

Ciò che ti risulta difficile comprendere è "Come faccio a fare X?" Questa non è un'azione in un solo passaggio, ma un processo in più fasi che deve essere scomposto.

Non devi fare questo:

ottieni tutti i post che sono figli di X ordinati per meta

Devi fare questo:

ottieni tutti i post che sono figli di X
    per ogni figlio, ottieni tutti i post che sono figli
        per ogni figlio di quel figlio ottieni tutti i post che sono figli
            ...
                hmmm non abbiamo più figli rimasti

Prendi la nostra lista di post e ordinali per meta

La Soluzione Generale

Quindi, per capire come farlo all'infinito fino a raggiungere la fine, senza hardcodarlo, devi comprendere le funzioni ricorsive.

Ad esempio:

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

Applicare la Ricorsione a Questo Problema per una Soluzione

Quindi il tuo genitore è $parid, e il tuo post meta ha una chiave $metakey.

Passiamolo in una funzione per ottenere i suoi figli.

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

Poi ordineremo l'array $children, le chiavi saranno gli ID dei post e i valori saranno i valori meta.

asort($children);

e definiamo la funzione come:

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 {
        // non ci sono figli!!
        return array();
    }
}

Questo ti dà un array di ID post e valori, ordinati dal più basso al più alto. Puoi usare altre funzioni di ordinamento PHP per farlo dal più alto al più basso.

E i Figli dei Figli?

Nel mezzo del nostro loop, dobbiamo fare una chiamata ricorsiva, passando l'ID del figlio invece che del genitore.

Quindi questo:

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

Diventa questo:

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

// ora ottieni i figli dei figli
$grandchildren = get_children_with_meta( get_the_ID(), $metakey );

// unisci i nipoti e i figli nella stessa lista
$children = array_merge( $children, $grandchildren );

Con questa modifica la funzione ora recupera i figli, i figli dei figli, i figli dei figli dei figli..... ecc.

Alla fine puoi tagliare i valori dall'array per ottenere gli ID così:

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

Usando questa strategia puoi sostituire il valore della meta key con qualsiasi altra metrica, o usare funzioni ricorsive in altri modi.

Dato che il codice completo richiede solo pochi secondi di comprensione di base e un veloce copia incolla, non insulto la tua intelligenza con un blocco di codice completo da copiare.

Vantaggi

  • Con modifiche funziona per qualsiasi tipo di post e formato di dati
  • Può essere modificato per generare markup annidato
  • Facilmente memorizzabile in cache per velocizzare salvando gli array restituiti in transient
  • Può essere configurato con impaginazione applicandola al WP_Query finale

Problemi che Incontrerai

  • Non hai modo di sapere quanti figli ci sono finché non li hai trovati, quindi i costi di performance non scalano
  • Ciò che vuoi genererà molte query, ed è intrinsecamente costoso per le potenziali profondità coinvolte.

La Mia Raccomandazione

Ti consiglierei di appiattire la gerarchia delle pagine o usare una tassonomia invece. Ad esempio, se valuti i post, crea una tassonomia Valutazione Pagina con i termini 1,2,3,4 e 5 ecc. Questo ti fornirà un elenco di post già pronto.

In alternativa, usa i menu di navigazione e bypassa completamente questo problema

19 apr 2013 17:46:12
0

Ottenere ricorsivamente tutte le sottopagine correnti

Ecco un approccio ricorsivo utilizzando get_children. Inserisci il seguente codice nel tuo functions.php:

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

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

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

    // Ottenimento 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];

        // Ottenimento sottopagine tramite ricorsione
        $subpages = array_merge($subpages, get_all_subpages($page, $args, $output));
    }

    return $subpages;
}

Come utilizzarla

Utilizza la funzione sopra dove preferisci, ad esempio così:

$all_current_subpages = get_all_subpages(0);

La funzione supporta un parametro args (stringa di query o array) e un tipo di output (vedi sopra).

Quindi puoi anche usarla così:

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

E grazie alla dipendenza get_children => get_posts => WP_Query puoi utilizzare meta valori, come richiesto inizialmente dall'autore di questa domanda.

14 apr 2013 04:22:48
0

Ho creato una funzione ricorsiva che ottiene tutti gli ID dei figli di una pagina genitore. Dopo aver ottenuto gli ID, eseguiamo una query per le pagine e possiamo ordinare i risultati per chiave/valore meta.

// Ottiene tutti gli ID dei figli di 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 ) // aggiunge ogni ID figlio all'array
            $child_ids[] = $post->ID;

    if ( ! empty( $child_ids ) )
        foreach ( $child_ids as $child_id ) // aggiunge ulteriori figli all'array
            $child_ids = array_merge( $child_ids, _get_children_ids( $child_id ) );

    return $child_ids;
}

$children_ids = _get_children_ids( 9 ); // usa il tuo ID pagina numerico o get_the_id()

$results = new WP_Query( array(
    'post_type'   => 'page',
    'post__in'   => $children_ids
    #'meta_key'   => 'meta_key', // tua chiave meta
    #'orderby'    => 'meta_key',
    /* 'meta_query' => array( // meta_query opzionale
        array(
            'key' => 'meta_key', // chiave
            'value' => array(3, 4), // valori
            'compare' => 'IN', // operatore
        )
    ) */
) );

var_dump( $results );

Se hai bisogno di ordinare i figli per chiave/valore meta in modo gerarchico, dovresti passare i valori meta_key e order_by alla WP_Query nella funzione _get_children_ids (invece che alla WP_Query finale).

Altrimenti, un metodo più semplice per ottenere tutti gli ID dei figli è:

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

$children_ids = array();
if ( ! empty( $children ) )
    foreach ( $children as $post )
        $children_ids[] = $post->ID;
18 apr 2013 12:08:52
0

Non sono sicuro che sia esattamente ciò che stai cercando, ma potresti utilizzare la funzione wp_list_pages, usando i parametri 'child_of' e 'depth'.

Consulta la seguente pagina sul Codex per maggiori informazioni: http://codex.wordpress.org/Function_Reference/wp_list_pages

30 nov 2011 16:58:57
1
-2

FUNZIONA, BASTA COPIARE E INCOLLARE IL CODICE NEL TUO FILE PAGE.PHP

//REINDIRIZZAMENTO AL PRIMO FIGLIO DALLA PAGINA GENITORE

// Costruisci l'array di argomenti per WP_Query()
$page_tree_query_args = array(
    'post_parent' => $post->ID,
    'post_type' => 'page',
    'order' => 'asc'
);
// Ottieni le pagine figlie come oggetto WP_Query()
$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;   
}
26 set 2013 14:36:14
Commenti

Questo è A) non funziona ($post -> ID?), B) non quello che è stato chiesto, C) non spiegato molto bene.

tfrommen tfrommen
26 set 2013 14:58:00