Mostrar solo un nivel de páginas hijas, problemas con wp_list_pages
Estoy trabajando en un sitio que tiene una estructura de páginas bastante grande con varios niveles de profundidad - en algunas secciones hay muchas páginas.
La estructura básica es algo así...
Padre Padre Padre -Hijo -Hijo --Nieto --Nieto --Nieto ---Bisnieto -Hijo -Hijo --Nieto --Nieto --Nieto ---Bisnieto -Hijo Padre -Hijo Padre Padre -Hijo -Hijo --Nieto ---Bisnieto --Nieto
Ya te haces una idea - ¡imagínate muchas más páginas!
Mi solución normal de submenús funciona bien normalmente (tomada directamente del Codex), porque trabajo en sitios mucho más pequeños. Este sitio resulta en un menú extremadamente largo que es demasiado grande para ser útil.
Lo que me gustaría hacer es mostrar solo el nivel directamente debajo de la página que se está viendo actualmente. Básicamente un menú tipo 'En esta sección...'.
No importa qué combinación de fragmentos de wp_list_pages haya encontrado, solo he podido obtener todo o nada.
Además, como hay algunas secciones que no tienen hijos, necesita mostrar solo los enlaces de nivel superior cuando no hay hijos presentes.
Espero que tenga sentido - ¡Me he estado arrancando el pelo todo el día por esto! Cualquier ayuda es muy apreciada!
EDICIÓN
Bien, lo añadiré aquí. ¡Perdón por ser novato!
¡Muchísimas gracias a @chip-bennet por ayudarme a llegar hasta aquí!
Ahora tengo este código que hace casi todo lo que necesito.
$output = wp_list_pages('echo=0&depth=1&title_li=Secciones' );
if (is_page( )) {
$page = $post->ID;
if ($post->post_parent) {
$page = $post->post_parent;
}
$children=wp_list_pages( 'echo=0&child_of=' . $page . '&title_li=' );
if ($children) {
$output = wp_list_pages( array(
// Solo páginas que son hijas de la página actual
'child_of' => $post->ID,
// Mostrar solo un nivel de jerarquía
'depth' => 1,
'title_li' => 'En esta Sección'
) );
}
}
echo $output;
Esto funciona exactamente como quiero hasta que llego al final del árbol, cuando no muestra nada.
Chip me ha dado el código nuevamente para mostrar las páginas del mismo nivel en lugar de buscar más hijos - sin embargo, mi falta de habilidades en PHP está haciendo que tenga problemas para añadirlo a este código.

Esto debería funcionar, usando nada más que los parámetros disponibles del array de argumentos para wp_list_pages()
: específicamente, depth
y child_of
.
Para mostrar un nivel de jerarquía, para las páginas descendientes de la página actual:
<?php
// Globalizar la variable $post;
// probablemente ya está disponible en este contexto, pero por si acaso...
global $post;
wp_list_pages( array(
// Solo páginas que son hijas de la página actual
'child_of' => $post->ID,
// Solo mostrar un nivel de jerarquía
'depth' => 1
) );
?>
No debería ser necesario recurrir a una clase walker personalizada.
EDITAR
Para mostrar también los enlaces de nivel superior, simplemente cambia un par de parámetros:
<?php
// Globalizar la variable $post;
// probablemente ya está disponible en este contexto, pero por si acaso...
global $post;
wp_list_pages( array(
// Solo páginas que son hijas del padre de la página actual
'child_of' => $post->post_parent,
// Solo mostrar dos niveles de jerarquía
'depth' => 2
) );
?>
Observa el cambio de 'child_of' => $post->ID
a 'child_of' => $post->post_parent
, que incluirá las páginas del padre de la página actual, y el cambio de 'depth' => 1
a 'depth' => 2
, que incluirá los hermanos de la página actual y sus hijos.
EDITAR 2
Bien, así es como manejaría el código que acabas de añadir. Primero, usaría un array adecuado, en lugar de una cadena de array. Luego, consultaría las páginas hijas/contexto antes de construir el array de argumentos de wp_list_pages()
, y luego simplemente llamaría a wp_list_pages()
una vez:
// Usar la página padre si existe, de lo contrario usar la página actual
$child_of_value = ( $post->post_parent ? $post->post_parent : $post->ID );
// Profundidad de 2 si es página padre, de lo contrario profundidad de 1
$depth_value = ( $post->post_parent ? 2 : 1 );
// Construir el array de argumentos
$wp_list_pages_args = array(
'child_of' => $child_of_value,
'depth' => $depth_value,
'title_li' => 'Secciones'
);
// Ahora, mostrar el resultado
wp_list_pages( $wp_list_pages_args );
Necesitaremos código más complejo si realmente necesitas mostrar listas separadas.

¡Brillante, eso definitivamente me ha puesto en el camino correcto!
Usando una combinación de otro fragmento de código, he logrado que haga el 90% de lo que necesito que haga...

Lo tengo configurado para que cuando no haya páginas hijas, muestre las páginas de nivel superior. Eso es genial, hasta que llega al final del árbol - actualmente no muestra nada.
Idealmente, en ese caso debería listar sus páginas hermanas (del mismo nivel), o en su defecto, sus páginas padres.

¿No puedo publicar código aquí fácilmente, verdad?
Básicamente, ¡puedo ver cómo funciona todo eso! Pero soy más del frontend, ¡y mi falta de conocimiento en PHP me impide unirlo todo!

¿Qué es eso? ¿Necesitas que lo añada a tu pregunta original? ¿Es código que funciona o no funciona?

He actualizado la publicación para ayudar a arrojar un poco más de luz. El sitio está en etapa de desarrollo en http://cheshirewestlscb-org-uk.temp.connectedcheshire.org.uk/?page_id=365 (ese es un ejemplo al final del árbol).

Bien, puedes usar el argumento depth para controlar cuántos niveles de profundidad deseas mostrar, y he creado un SubMenu walker, que muestra el menú comenzando desde los hijos directos de la página actual. Código:
class My_Walker_Submenu extends Walker_Nav_Menu {
function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) {
if (! $element)
return;
$itemId = null;
if ( $depth == 0) {
if (!isset($args[0]->child_of)){
return;
}
foreach ( $children_elements as $id => $children ) {
$data = get_post_meta ( $id, '_menu_item_object_id', true );
if ($data == $args [0]->child_of) {
$itemId = $id;
break;
}
}
if ($itemId == null) {
return;
}
unset($args [0]->child_of);
foreach ( $children_elements [$itemId] as $child ) {
parent::display_element ( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
}
return;
}
return parent::display_element ( $element, $children_elements, $max_depth, $depth, $args, $output );
}
Y su uso (de hecho lo estoy usando en la barra lateral):
echo wp_nav_menu( array(
'container' => '',
'theme_location' => 'header-menu',
'walker' => new My_Walker_Submenu(),
'child_of' => $page->ID,
'depth' => 2
) );

Este es un problema que veo surgir con bastante frecuencia. Creo que las soluciones con WP_List_Pages que se ven por todas partes son un poco anticuadas ahora que WordPress tiene un administrador de menús adecuado (Apariencia -> Menús).
He probado numerosas soluciones, incluyendo algunos plugins/widgets y walkers como el mencionado anteriormente. Nunca he estado muy satisfecho con las soluciones disponibles. Creé mi propio plugin que maneja estos menús secundarios de la manera que prefiero y a la que estoy acostumbrado. Al mostrar el menú, puedes establecer un start_depth para indicarle al menú que ignore un cierto número de 'niveles' por encima de tu página actual.
Así que para tus necesidades establecerías el start_depth a 1, y automáticamente ignoraría los elementos de navegación de nivel superior al mostrar tu menú.
Llamo al plugin WP Nav Plus porque se basa en el poder y las opciones actuales de wp_nav_menu, solo que con la adición del argumento start_depth para mostrar menús hijos.
Para cualquiera que esté interesado, está disponible en mi sitio web: https://mattkeys.me/products/wp-nav-plus/

He creado una función que utiliza wp_list_pages() para lograr eso. Ajusta los parámetros y estarás listo.
