Soporte » Diseño – Temas y plantillas » Menú por categorías con actualización automática de items
Menú por categorías con actualización automática de items
-
Hola, quisiera pedir una orientación sobre el enfoque correcto para conseguir un menú basado en categorías que sea actualizable automáticamente. Es decir, que todos los posts de una categoría aparezcan dentro de su epígrafe correspondiente:
- Categoría 1
- Post 1
- Post 2
- Post 3
- Categoría 2
- Post 1
- Post 2
- Post 3
- Categoría 3
- Post 1
- Post 2
- Post 3
Lo que a mí se me ocurre es:
1) Crear un array de categorías con
get_categories()
2) Recorrer el array con
foreach
y hacer unaWP_query
de los post de cada categoría.Así me valdría, pero no sé si es correcto, porque prescindo de toda la infraestructura para menús, walker class, etc.
¿Es correcto o hay alguna forma mejor de hacerlo?
-
Este debate fue modificado hace 5 años por
Aitor Méndez.
-
Este debate fue modificado hace 5 años por
Aitor Méndez.
-
Hola,
Esto dependera de tus conocimientos de PHP y WordPress.
Te pongo varios ejemplos de como se podria implementar.
– Crear un menu de categorias y cada vez que se publique una entrada (post) añadirlo al menu.
– Crear un menu de categorias y usar el filtro wp_get_nav_menu_object para añadir el contenido.
– Crear un menu de categorias y un custom Walker para añadir el contenido.
– Hacer una WP_Query y ordenar los posts por categorias, este metodo no usaria los menus del WordPress.Como puedes ver hay posibilidades, ahora es cuestion de saber cual seria la mejor opcion, si el menu es el principal de la web, etc…
@kallookoo, muchas gracias por tu respuesta.
El menú es el menú principal del sitio y yo tengo conocimientos moderados de WordPress y PHP, aunque me gusta aprender cosas nuevas.
De los cuatro enfoques que propones, el primero quedaría descartado por falta de automatización y el último es, según lo entiendo, el que yo proponía.
He revisado la función
wp_get_nav_menu_object
. Parece que la función devuelve un objeto menu que ya existe previamente. Por lo que, según entiendo, el menú se crea a mano y luego se usa el objeto para definir las WP_query, de una forma similar al foreach ¿Correcto?La que me parece más atractiva es la de extender la clase
Walker_Nav_Menu
, pero no me dan los conocimientos. Intentaré leyendo la documentación, a ver qué tal. Si pudieras darme alguna pista, estupendo, si no, doy la pregunta por contestada.-
Esta respuesta fue modificada hace 5 años por
Aitor Méndez.
-
Esta respuesta fue modificada hace 5 años por
Aitor Méndez.
-
Esta respuesta fue modificada hace 5 años por
Aitor Méndez.
Huy,
Me explique mal…El mas automizado es el primer metodo pero te lo explique mal, te explico:
Cuando creas un post, page, cpt se llama a un action save_post y save_post_nombre_del_post_type (recomendado) y desde hay puedes actualizar el menu de categorias que ya tienes creado usandowp_update_nav_menu_item
, usando este metodo tambien tienes que actualizar el menu si borrases un post.Sobre
wp_get_nav_menu_object
te lo puse para que vieses como trabaja y vieses que es usado porwp_get_nav_menu_items
que es la function que devuelve los elementos del menu. Di por hecho que lo comprenderias. Pero el filtro que deberias usar eswp_get_nav_menu_items
.Sobre le Walker basicamente tienes que detectar la categoria y despues puedes añadir los sub items, pero aqui para añadir las classes que añade WordPress deberias pasarle
_wp_menu_item_classes_by_context
y añadir las classes CSS extras.No suelo poner codigos cuando es algo complejo basicamente por no crear problemas, porque si sucede algo como pegarlo, copiarlo o añadirlo mal, sera un problema para la persona que hace la pregunta o incluso romper el WordPress creando un problema mayor.
Pero basicamente te reduzco las opciones.
– Crea un plugin (el codigo es reutilizable si cambias de theme) o añade el codigo en functions.php, la mejor manera para aprender como desarrollar para WordPress.
– Usa el filterwp_get_nav_menu_items
si no te atreves con el primer metodo.
Te he buscado un ejemplo, aunque esta en ingles creo que lo entenderas.
https://gist.github.com/daggerhart/c17bdc51662be5a588c9Muchísimas gracias por la explicación. Ahora me toca estudiar lo que me indicas. Cierro la consulta.
De nada,
Si tienes problemas o te salen errors puedes preguntar en Plugins y Hacks o WordPress Avanzado y veremos si te podemos ayudar.Pongo aquí la solución que he elaborado. No sé si es la mejor, pero funciona. He usado la modificación del walker, detectando si el item de menú es una taxonomía y buscando sus posts correspondientes con
get_posts()
.class ep_submenu extends Walker_Nav_Menu { function end_el(&$output, $item, $depth=0, $args=[]) { if( 'taxonomy' == $item->type ) { $posts_args = [ 'posts_per_page' => -1, 'category_name' => $item->title ]; $cat_posts = get_posts($posts_args); $output .= '<ul>'; foreach ($cat_posts as $cat_post) { $permalink = get_permalink($cat_post->ID); $output .= '<li><a href="' . $permalink . '">' . $cat_post->post_title . '</a></li>'; } $output .= '</ul>'; } $output .= "</li>\n"; } }
Hola,
Te contesto por aqui, #foro-mods es para otro tipo de cosas 😉
Tu solucion es totalmente validad, aunque yo lo hubiese hecho de otra manera.
Si me lo permites te hago un par de cambios que puedes aplicar:class ep_submenu extends Walker_Nav_Menu { public function end_el( &$output, $item, $depth=0, $args=[] ) { if ( 'taxonomy' === $item->type ) { $posts_args = [ 'nopaging' => true, // Muestra todos los posts 'category' => $item->ID // La ID no cambia aunque le cambies el nombre o slug ]; $cat_posts = get_posts( $posts_args ); // Si hay se añade el ul, li, etc... if ( $cat_posts ) { $output .= '<ul>'; foreach ( $cat_posts as $cat_post ) { $link = get_permalink( $cat_post->ID ); // Aplicas los filtros predeterminados para el titulo $title = apply_filters( 'the_title', $cat_post->post_title ); if ( $title ) { $output .= '<li><a href="' . $link . '">' . $title . '</a></li>'; } } $output .= '</ul>'; } } $output .= "</li>\n"; } }
Explicaciones:
Porquenopaging
en vez deposts_per_page
basicamente porque es mas claro y si revistas wp-includes/class-wp-query.php:1719 veras que la define atrue
cuando usas-1
.
Porquecategory
en vez decategory_name
basicamente porque la ID no cambia aunque le cambies el nombre o slug.
La comprobacion si hay post es basicamente porque si aplicas padding o margin al ul, te apareceria el submenu y no tiene sentido añadirlo cuando no hay.
El filtrothe_title
es para asegurarte que se muestra correctamente el titulo ya que escapa caracteres, etc… Elif $title
es para asegurarte que despues de pasar los filtros no esta vacio, no tiene sentido un link sin title y mas en un menu.Opinion de rendimiento:
Pensando en los metodos que te comente me doy cuenta que salvo el primer metodo hay un aumento de consultas en la base de datos.
Te explico:
Por cada categoria del menu haces 1 consulta para recibir todos los posts de esa categoria, y despues se hace 1 consulta para cadaget_permalink
ya que usaget_post
.
En cifras hipoteticas seria:
Menu con 15 categorias
50 posts por cada categoria del menu
Total 51 consultas por cada categoria del menu
Total 765 consultas para mostrar el menu
Hay le sumas las consultas que haga el propio WordPress, en tema de performance puede ser perjudicial, he puesto numeros mas o menos altos para que se vea el aumento mejor. Claro esta que si solo tienes 5 categorias y 10 posts por cada categoria serian 55 consultasSaludos
Edit:
Otra cosa que podrias hacer es añadir las classes CSS que usa WordPress asi podras darle un estilo mas compatible por si cambias de theme, etc…-
Esta respuesta fue modificada hace 5 años por
kallookoo.
Buenísimas sugerencias, @kallookoo. Las aplicaré todas.
Respecto al rendimiento, tienes toda la razón y ya lo había pensado. La opción de aplicar un filtro que modifique el menú a la hora de salvar un post, me parece mucho más efectiva en términos de rendimiento. Lo que pasa es que se me escapa un poco la técnica. Hay que hacer varias cosas que aún no domino:
- Actualizar los submenús cuando se salva un post.
- Actualizar los submenús cuando se modifica el menú desde el interfaz de edición.
- Actualizar los submenús cuando se borra un post.
Esto me parecía bastante complicado para mi nivel actual, aunque reconozco que es mejor.
-
Esta respuesta fue modificada hace 5 años por
Aitor Méndez.
-
Esta respuesta fue modificada hace 5 años por
Aitor Méndez.
@kallookoo, creo que hay un error en las sugerencias:
'category' => $item->ID
Esto debería recoger el ID de la categoría, pero recoge el ID del item de menú, por lo que no funciona.
-
Esta respuesta fue modificada hace 5 años por
Aitor Méndez.
Upss, tienes razon… es
$item->object_id
Dejo aquí el código completo:
https://github.com/aitormendez/menu-acordeon
Y un ejemplo de cómo funciona:
-
Esta respuesta fue modificada hace 5 años por
- El debate ‘Menú por categorías con actualización automática de items’ está cerrado a nuevas respuestas.