Wp obtiene todas las subpáginas del padre usando wp query

12

Aquí está mi 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' ));

Muestra solo las subpáginas de primer nivel. Necesito toda la subpágina, la subpágina de sub ... y todo. Busqué una solución y puedo obtener todas las subpáginas utilizando get_pages y wp_list_pages.

Pero realmente necesito ordenar el orden por valor meta personalizado de publicación. Así que tengo que usar la consulta personalizada.

por favor ayuda. Gracias

    
pregunta phpuser 30.11.2011 - 11:57

6 respuestas

6

¿Por qué no solo usar get_pages() ?

por ejemplo

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

Pero si realmente debe ser como un objeto WP_Query() , use un método similar:

<?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 );
?>
    
respondido por el Chip Bennett 30.11.2011 - 18:22
4

El problema

Lo que estás teniendo problemas para entender es "¿Cómo hago X?" Esto no es una acción de 1 paso, es un proceso de varios pasos y debe ser separado.

No necesitas hacer esto:

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

Necesitas hacer esto:

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 solución general

Entonces, para entender cómo hacerlo infinitamente hasta que llegues al final, sin codificarlo, necesitas entender las funciones recursivas.

por ejemplo

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

Aplicando la recursión a este problema para una solución

Entonces, tu padre es $parid , y tu meta meta tiene una clave de $metakey .

Permite pasarlo a una función para capturar a sus hijos.

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

Luego, ordenaremos la matriz $ children, las claves serán las ID de publicación y los valores serán los valores meta.

asort($children);

y permite definir la función 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();
    }
}

Esto le da una serie de ID y valores de publicación, ordenados de menor a mayor. Puedes usar otras funciones de clasificación de PHP para hacerlo de mayor a menor.

Ahora, ¿qué pasa con los niños de los niños?

En el medio de nuestro bucle, necesitamos hacer una llamada recursiva, pasando el hijo en lugar de la identificación del padre.

Entonces esto:

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

Se convierte en esto:

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

Con esta modificación, la función ahora recupera a los niños, a los niños de los niños, a los niños de los niños de los niños ..... etc.

Al final, puedes recortar los valores de la matriz para obtener ID de esta manera:

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

Usando esta estrategia, puede reemplazar el valor de la clave de metaclave con cualquier otra métrica, o usar funciones recursivas de otras maneras.

Dado que el código completo requiere solo unos pocos segundos de comprensión básica y una copia de pegado rápida, no voy a insultar tu inteligencia con un bloque de código de pegado de copia completo.

Ventajas

  • Con trabajos de modificación para cualquier tipo de publicación y forma de datos
  • Se puede modificar para generar un marcado anidado
  • Caché fácilmente para acelerar al poner los arreglos devueltos en transitorios
  • Se puede configurar con la paginación aplicando la paginación al final WP_Query

Problemas que encontrarás

  • No tiene forma de saber cuántos hijos hay hasta que los haya encontrado, por lo que los costos de rendimiento no se escalan
  • Lo que desea generará muchas consultas y es inherentemente costoso debido a las profundidades potenciales involucradas.

Mi recomendación

Recomendaría que alise la jerarquía de su página o use una taxonomía en su lugar. P.ej. si está calificando publicaciones, tenga una taxonomía de Clasificación de página con los términos 1,2,3,4 y 5, etc. Esto le proporcionará una lista de publicaciones fuera de la caja.

Alternativamente, use los menús de navegación y evite este problema por completo

    
respondido por el Tom J Nowell 19.04.2013 - 16:46
3

Obtenga recursivamente todas las subpáginas actuales

Aquí hay un enfoque recursivo utilizando get_children . Ponga lo siguiente en su 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;
}

Cómo usarlo

Utilice la función anterior donde desee, por ejemplo, como esto:

$all_current_subpages = get_all_subpages(0);

La función admite un parámetro args (cadena de consulta o matriz) y un tipo output (ver arriba).

Para que también puedas usarlo así:

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

Y debido a la dependencia get_children = > get_posts = > WP_Query puede usar valores meta, como lo solicitó inicialmente el autor de esta pregunta.

    
respondido por el tfrommen 14.04.2013 - 03:22
2

No estoy seguro de si esto es exactamente lo que está buscando, pero puede usar la función wp_list_pages y los parámetros 'child_of' y 'depth'.

Vea la siguiente página en el Codex para más información: enlace

    
respondido por el Kris Nielsen 30.11.2011 - 15:58
2

He hecho una función recursiva que obtiene todos los identificadores secundarios de una página principal. Después de que tengamos los identificadores, hacemos una consulta para las páginas y podemos ordenar los resultados por meta clave / 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 );

Si necesita ordenar los valores por clave / valor meta de manera jerárquica, debe pasar los valores meta_key y order_by a WP_Query en la función _get_children_ids (en lugar de WP_Query final).

Si no, un método más sencillo para obtener todos los ID de niños es:

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

$children_ids = array();
if ( ! empty( $children ) )
    foreach ( $children as $post )
        $children_ids[] = $post->ID;
    
respondido por el Nicü 18.04.2013 - 11:08
-1

HAGO ESTO FUNCIONAR, SOLO COPIE EL CÓDIGO A SU PÁGINA.PHP ARCHIVO

//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;   
}
    
respondido por el Bipin Sapkota 26.09.2013 - 13:36

Lea otras preguntas en las etiquetas