Wp récupère toutes les sous-pages du parent à l'aide de la requête wp

12

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

Affiche uniquement les sous-pages de premier niveau. J'ai besoin de toutes les sous-pages, sous-pages ... 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 l'ordre par méta valeur de post personnalisé. Je dois donc utiliser une requête personnalisée.

s'il vous plaît aider. Merci

    
posée phpuser 30.11.2011 - 11:57

6 réponses

6

Pourquoi ne pas simplement utiliser get_pages() ?

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 s'agir d'un objet WP_Query() , 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 );
?>
    
réponse donnée Chip Bennett 30.11.2011 - 18:22
4

Le problème

Ce que vous avez du mal à comprendre, c’est "Comment puis-je faire X?" Ce n'est pas une action en 1 étape, c'est un processus en plusieurs étapes, et il faut le séparer.

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.

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 comme solution

Votre parent est donc $parid et votre méta de publication a une clé de $metakey .

Permet de le transmettre à une fonction pour saisir ses enfants.

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

Ensuite, nous allons trier le tableau $ children, les clés seront les identifiants de post 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();
    }
}

Ceci 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 haut au plus bas.

Maintenant, qu'en est-il des enfants?

Au milieu de notre boucle, nous devons effectuer un appel récursif en transmettant l'enfant au lieu de l'ID parent.

Donc ceci:

$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, les enfants, etc .....

À la fin, vous pouvez supprimer les valeurs du tableau pour obtenir des ID tels que:

$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 des fonctions récursives d'une autre manière.

Etant 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 complet pour le copier-coller.

Avantages

  • Avec la modification fonctionne pour tout type d'article et toute forme de donnée
  • Peut être modifié pour générer un balisage imbriqué
  • Mettez facilement en cache pour accélérer en mettant les tableaux renvoyés dans des éléments 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 d'enfants il y a 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 recommanderais d’aplatir votre hiérarchie de pages ou d’utiliser une taxonomie à la place. Par exemple. si vous notez des publications, créez une taxonomie de classification avec les termes 1, 2, 3, 4, 5, etc. Cela vous fournira une liste de publications prêtes à l'emploi.

Vous pouvez également utiliser les menus de navigation et contourner entièrement ce problème

    
réponse donnée Tom J Nowell 19.04.2013 - 16:46
3

Récupérer récursivement toutes les sous-pages en cours

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 voulez, par exemple comme ceci:

$all_current_subpages = get_all_subpages(0);

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

Vous pouvez donc également l'utiliser comme suit:

$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_Query vous pouvez utiliser les méta-valeurs, comme demandé initialement par l'auteur de cette question.

    
réponse donnée tfrommen 14.04.2013 - 03:22
2

Vous ne savez 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 du Codex pour plus d’informations: enlace

    
réponse donnée Kris Nielsen 30.11.2011 - 15:58
2

J'ai créé une fonction récursive qui récupère tous les identifiants enfants d'une page parent. Après avoir obtenu les identifiants, nous effectuons une requête pour les pages et pouvons classer 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 au WP_Query dans la fonction _get_children_ids (au lieu du WP_Query final).

Si ce n'est pas le cas, une méthode plus simple pour obtenir tout l'ID enfant est la suivante:

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

$children_ids = array();
if ( ! empty( $children ) )
    foreach ( $children as $post )
        $children_ids[] = $post->ID;
    
réponse donnée Nicü 18.04.2013 - 11:08
-1

Je fais en sorte que cela fonctionne, il suffit de copier le code sur le fichier de votre 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;   
}
    
réponse donnée Bipin Sapkota 26.09.2013 - 13:36

Lire d'autres questions sur les étiquettes