Wp obtiene todas las subpáginas del padre utilizando la consulta wp

13

Aqui esta mi codigo

$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 del 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 usando get_pages y wp_list_pages.

Pero realmente necesito ordenar el orden por el metavalor personalizado. Entonces tengo que usar una consulta personalizada.

por favor ayuda. Gracias

phpuser
fuente
1
Debajo de usted dice que encontró una respuesta, ¿qué es?
Drew Baker el
44
¿Has echado un vistazo a get_page_children ?
t31os

Respuestas:

6

¿Por qué no solo usar get_pages()?

p.ej

<?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 WP_Query()objeto, 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 );
?>
Chip Bennett
fuente
Si utilizamos la funcionalidad get_pages () no podríamos implementar la clasificación (sort_column) para campos personalizados. Solo acepta los campos de la tabla de publicación. Necesito implementar la clasificación para el campo personalizado. Entonces solo uso la consulta wp (). ¿Hay alguna forma alternativa?
phpuser
¿Viste la segunda mitad de mi respuesta, en la que uso WP_Query()?
Chip Bennett
Intenté este código pero solo devuelve las subpáginas del primer nivel. Necesito subpágina >> sub's sub >> etc ... (múltiples niveles inferiores de páginas). Finalmente encontré la solución. Gracias por su respuesta
phpuser
77
¿Cuál es tu solución?
JCHASE11
Hay algunos puntos y comas dentro de las definiciones de matriz anteriores que causan errores de sintaxis.
ptrin
4

El problema

Lo que tiene problemas para comprender es "¿Cómo hago X?" Esta no es una acción de 1 paso, es un proceso de varios pasos y debe separarse.

No necesitas hacer esto:

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

Usted necesita hacer ésto:

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 solucion general

Entonces, para entender cómo hacerlo infinitamente hasta llegar al final, sin codificarlo, debe comprender las funciones recursivas.

p.ej

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 de publicación tiene una clave de $metakey.

Pasemos a una función para agarrar a sus hijos.

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

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

asort($children);

y definamos 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 brinda una variedad de ID y valores de publicaciones, ordenados de menor a mayor. Puede usar otras funciones de clasificación de PHP para hacerlo de mayor a menor.

¿Qué pasa con los niños de los niños?

En el medio de nuestro bucle, necesitamos hacer una llamada recursiva, pasando el niño en lugar del ID de padre.

Así que 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 los hijos, los hijos de los niños, los hijos de los niños ..... etc.

Al final, puede recortar los valores en la matriz para obtener ID como este:

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

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

Dado que el código completo requiere solo unos segundos de comprensión básica y una copia rápida de pegar, no insultaré su inteligencia con un bloque de código completo.

Ventajas

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

Problemas que encontrarás

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

Mi recomendación

Te recomendaría que aplanes la jerarquía de tu página o que uses una taxonomía. Por ejemplo, si está calificando publicaciones, tenga una taxonomía de calificación de página con los términos 1,2,3,4 y 5, etc. Esto le proporcionará una lista de publicaciones lista para usar.

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

Tom J Nowell
fuente
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

Use la función anterior donde desee, por ejemplo, así:

$all_current_subpages = get_all_subpages(0);

La función admite un argsparámetro (cadena o matriz de consulta) y un outputtipo (ver arriba).

Entonces también puedes 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_Querypuede usar meta valores, como lo solicitó inicialmente el autor de esta pregunta.

tfrommen
fuente
2

Hice una función recursiva que obtiene todos los identificadores secundarios de una página principal. Una vez que tenemos 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 hijos por meta clave / valor 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 la WP_Query final).

Si no, un método más simple para obtener toda la identificación secundaria es:

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

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

HAGO ESTE FUNCIONAMIENTO, SOLO COPIE Y PEGUE EL CÓDIGO EN SU 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
fuente
Esto es A) no funciona ( $post -> ID?), B) no es lo que se pidió, C) no se explica muy bien.
tfrommen