Wp obtém todas as subpáginas do pai usando a consulta wp

13

Aqui está o meu código

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

Ele exibe apenas as subpáginas do primeiro nível. Eu preciso de todas as subpáginas, subpáginas ... e tudo. Procurei uma solução e posso obter todas as subpáginas usando get_pages e wp_list_pages.

Mas eu realmente preciso classificar a ordem pelo meta valor personalizado da postagem. Então, eu tenho que usar a consulta personalizada.

por favor ajude. obrigado

phpuser
fonte
1
Abaixo você diz que encontrou uma resposta, o que é?
Tirou Baker
4
Você verificou get_page_children ?
t31os

Respostas:

6

Por que não usar apenas get_pages() ?

por exemplo

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

Mas se realmente deve ser como um WP_Query()objeto, use um método semelhante:

<?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
fonte
Se usarmos a funcionalidade get_pages (), não poderemos implementar a classificação (sort_column) para campos personalizados. Ele aceita apenas apenas os campos da tabela de postagem. Preciso implementar a classificação para o campo personalizado. Então, apenas eu uso a consulta wp (). Existe alguma maneira alternativa?
Phpuser
Você viu a segunda metade da minha resposta, na qual eu uso WP_Query()?
Chip Bennett
Eu tentei esse código, mas ele retorna apenas as subpáginas de primeiro nível. Preciso da subpágina >> sub's sub >> etc ... (vários níveis inferiores de páginas). Finalmente eu encontrei a solução. Obrigado pela sua resposta
phpuser
7
qual é a sua solução?
JCHASE11
Existem alguns pontos e vírgulas nas definições da matriz acima, causando erros de sintaxe.
Ptrin
4

O problema

O que você está tendo problemas para entender é "Como eu faço o X?" Esta não é uma ação de uma etapa, é um processo de várias etapas e precisa ser dividido.

Você não precisa fazer isso:

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

Você precisa fazer isso:

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

A solução geral

Portanto, para entender como fazê-lo infinitamente até chegar ao fim, sem codificá-lo, você precisa entender as funções recursivas.

por exemplo

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

Aplicando recursão a este problema para uma solução

Portanto, seu pai é $paride sua meta meta tem uma chave de $metakey.

Vamos passar para uma função de agarrar seus filhos.

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

Em seguida, classificaremos o array $ children, as chaves serão os IDs das postagens e os valores serão os meta-valores.

asort($children);

e vamos definir a função como:

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

Isso fornece uma variedade de IDs e valores de postagem, ordenados do menor para o maior. Você pode usar outras funções de classificação PHP para fazer isso do maior para o menor.

Agora, e os filhos das crianças?

No meio do nosso loop, precisamos fazer uma chamada recursiva, passando o filho em vez do ID pai.

Então, é isso:

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

Torna-se isso:

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

Com esta modificação, a função agora recupera os filhos, os filhos das crianças, os filhos das crianças ..... etc

No final, você pode aparar os valores na matriz para obter IDs como este:

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

Usando essa estratégia, você pode substituir o valor da meta-chave por qualquer outra métrica ou usar funções recursivas de outras maneiras.

Como o código completo requer apenas alguns segundos de compreensão básica e uma colagem de cópia rápida, não insultarei sua inteligência com um bloco de código de colagem de cópia completa.

Vantagens

  • Com a modificação funciona para qualquer tipo de post e forma de dados
  • Pode ser modificado para gerar marcação aninhada
  • Faça cache facilmente para acelerar, colocando as matrizes retornadas em transientes
  • Pode ser configurado com paginação aplicando paginação no final WP_Query

Problemas que você encontrará

  • Você não tem como saber quantas crianças existem até encontrá-las, para que os custos de desempenho não aumentem
  • O que você deseja gerará muitas consultas e é inerentemente caro devido às possíveis profundidades envolvidas.

Minha recomendação

Eu recomendo que você aplique a hierarquia da página ou use uma taxonomia. Por exemplo, se você está classificando postagens, tenha uma taxonomia de classificação de página com os termos 1,2,3,4 e 5 etc. Isso fornecerá uma listagem de post pronta para uso.

Como alternativa, use os menus de navegação e ignore esse problema completamente

Tom J Nowell
fonte
3

Obter recursivamente todas as subpáginas atuais

Aqui está uma abordagem recursiva usando get_children. Coloque o seguinte em seu 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;
}

Como usá-lo

Use a função acima onde quiser, por exemplo:

$all_current_subpages = get_all_subpages(0);

A função suporta um argsparâmetro (string ou matriz de consulta) e um outputtipo (veja acima).

Então você também pode usá-lo assim:

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

E devido à dependência get_children=> get_posts=> WP_Queryvocê pode usar meta-valores, conforme solicitado inicialmente pelo autor desta pergunta.

tfrommen
fonte
2

Não tenho certeza se é exatamente isso que você procura, mas você pode usar a função wp_list_pages e os parâmetros 'child_of' e 'depth'.

Consulte a seguinte página no Codex para obter mais informações: http://codex.wordpress.org/Function_Reference/wp_list_pages

Kris Nielsen
fonte
2

Eu criei uma função recursiva que obtém todos os IDs filhos de uma página pai. Depois de termos os IDs, fazemos consultas para as páginas e podemos ordenar os resultados por meta-chave / valor.

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

Se você precisar classificar os filhos por meta-chave / valor de maneira hierárquica, deve passar os valores meta_key e order_by para o WP_Query na função _get_children_ids (em vez do WP_Query final).

Caso contrário, um método mais simples para obter todo o ID filho é:

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

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

FAÇO ESTE FUNCIONAMENTO, APENAS COPIAR COLAR O CÓDIGO NA SUA PÁGINA.

//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
fonte
Isto é A) não está funcionando ( $post -> ID?), B) não é o que foi solicitado, C) não foi explicado muito bem.
tfrommen