Ottenere tutte le sottopagine della pagina principale usando WP Query
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

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

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?

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

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

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

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.

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;

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

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