Wp récupère toutes les sous-pages du parent en utilisant la requête wp

13

Voici mon code

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

Il affiche uniquement les sous-pages de premier niveau. J'ai besoin de toute la sous-page, de la sous-page de sub ... et tout. J'ai cherché une solution et je peux obtenir toutes les sous-pages en utilisant get_pages et wp_list_pages.

Mais j'ai vraiment besoin de trier la commande par valeur méta de poste personnalisée. Je dois donc utiliser une requête personnalisée.

veuillez aider. Merci

phpuser
la source
1
Ci-dessous, vous dites que vous avez trouvé une réponse, quelle est-elle?
Drew Baker
4
Avez-vous vérifié get_page_children ?
t31os

Réponses:

6

Pourquoi ne pas simplement utiliser get_pages()?

par exemple

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

Mais s'il doit vraiment être un WP_Query()objet, utilisez une méthode similaire:

<?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
la source
Si nous utilisons la fonctionnalité get_pages (), nous ne pourrions pas implémenter le tri (sort_column) pour les champs personnalisés. Il accepte uniquement les champs de table de publication. J'ai besoin d'implémenter le tri pour le champ personnalisé. Donc, seulement j'utilise la requête wp (). Y a-t-il une autre manière?
phpuser
Avez-vous vu la deuxième moitié de ma réponse, dans laquelle j'utilise WP_Query()?
Chip Bennett
J'ai essayé ce code mais il ne renvoie que les sous-pages de premier niveau. J'ai besoin d'une sous-page >> d'une sous-sous >> etc ... (plusieurs niveaux inférieurs de pages.). Enfin, j'ai trouvé la solution. Merci pour votre réponse
phpuser
7
quelle est votre solution!?
JCHASE11
Il y a des points-virgules à l'intérieur des définitions de tableau ci-dessus, provoquant des erreurs de syntaxe.
ptrin
4

Le problème

Ce que vous rencontrez des problèmes à saisir est "Comment faire X?" Ce n'est pas une action en une étape, c'est un processus en plusieurs étapes, et il doit être séparé.

Vous n'avez pas besoin de faire ceci:

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

Vous devez faire ceci:

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

La solution générale

Donc, pour comprendre comment le faire à l'infini jusqu'à la fin, sans le coder en dur, vous devez comprendre les fonctions récursives.

par exemple

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

Application de la récursivité à ce problème pour une solution

Donc, votre parent est $parid, et votre méta-message a une clé de $metakey.

Permet de le passer dans une fonction pour saisir ses enfants.

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

Ensuite, nous trierons le tableau $ children, les clés seront les ID de publication et les valeurs seront les méta-valeurs.

asort($children);

et permet de définir la fonction comme:

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

Cela vous donne un tableau d'ID et de valeurs de publication, classés du plus bas au plus élevé. Vous pouvez utiliser d'autres fonctions de tri PHP pour le faire du plus élevé au plus bas.

Qu'en est-il maintenant des enfants pour enfants?

Au milieu de notre boucle, nous devons effectuer un appel récursif, en passant l'enfant plutôt que l'ID parent.

Donc ça:

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

Devient ceci:

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

Avec cette modification, la fonction récupère maintenant les enfants, les enfants enfants, les enfants enfants enfants ..... etc

À la fin, vous pouvez couper les valeurs du tableau pour obtenir des ID comme celui-ci:

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

En utilisant cette stratégie, vous pouvez remplacer la valeur de la méta-clé par toute autre métrique ou utiliser les fonctions récursives de différentes manières.

Étant donné que le code complet ne nécessite que quelques secondes de compréhension de base et un copier-coller rapide, je ne vais pas insulter votre intelligence avec un bloc de code copier-coller complet.

Les avantages

  • Avec modification fonctionne pour tout type de publication et forme de données
  • Peut être modifié pour générer un balisage imbriqué
  • Cachez facilement pour accélérer en mettant les tableaux retournés en transitoires
  • Peut être configuré avec la pagination en appliquant la pagination à la fin WP_Query

Problèmes que vous rencontrerez

  • Vous n'avez aucun moyen de savoir combien il y a d'enfants jusqu'à ce que vous les ayez trouvés, donc les coûts de performance n'augmentent pas
  • Ce que vous voulez va générer beaucoup de requêtes et est intrinsèquement coûteux en raison des profondeurs potentielles impliquées.

Ma recommandation

Je vous recommande soit d'aplatir votre hiérarchie de pages, soit d'utiliser une taxonomie à la place. Par exemple, si vous évaluez des publications, ayez une taxonomie de classification des pages avec les termes 1, 2, 3, 4 et 5, etc. Cela vous fournira une liste de publications prête à l'emploi.

Vous pouvez également utiliser les menus de navigation et contourner complètement ce problème

Tom J Nowell
la source
3

Récupère récursivement toutes les sous-pages actuelles

Voici une approche récursive utilisant get_children. Mettez ce qui suit dans votre 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;
}

Comment l'utiliser

Utilisez la fonction ci-dessus où vous le souhaitez, par exemple comme ceci:

$all_current_subpages = get_all_subpages(0);

La fonction prend en charge un argsparamètre (chaîne ou tableau de requête) et un outputtype (voir ci-dessus).

Vous pouvez donc également l'utiliser comme ceci:

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

Et en raison de la dépendance get_children=> get_posts=> WP_Queryvous pouvez utiliser des méta-valeurs, comme initialement demandé par l'auteur de cette question.

tfrommen
la source
2

Je ne sais pas si c'est exactement ce que vous recherchez, mais vous pouvez utiliser la fonction wp_list_pages et utiliser les paramètres 'child_of' et 'depth'.

Voir la page suivante sur le Codex pour plus d'informations: http://codex.wordpress.org/Function_Reference/wp_list_pages

Kris Nielsen
la source
2

J'ai créé une fonction récursive qui récupère tous les identifiants enfants d'une page parent. Une fois que nous avons les identifiants, nous faisons une requête pour les pages et pouvons ordonner les résultats par méta clé / valeur.

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

Si vous devez trier les enfants par méta clé / valeur de manière hiérarchique, vous devez transmettre les valeurs meta_key et order_by à WP_Query dans la fonction _get_children_ids (au lieu de WP_Query final).

Sinon, une méthode plus simple pour obtenir tous les identifiants enfants est:

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

$children_ids = array();
if ( ! empty( $children ) )
    foreach ( $children as $post )
        $children_ids[] = $post->ID;
Nicü
la source
-1

JE FAIS CE TRAVAIL, COPIEZ JUSTE LE CODE SUR VOTRE FICHIER 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;   
}
Bipin Sapkota
la source
C'est A) ne fonctionne pas ( $post -> ID?), B) pas ce qui a été demandé, C) pas très bien expliqué.
tfrommen