Cuando trabajamos con Custom Post Types en WordPress, a veces queremos que ciertos elementos del menú aparezcan o desaparezcan en función de una condición.
En este caso, necesitaba crear una sección de webinars que solo apareciera en el menú principal cuando hubiera al menos un webinar activo.
A continuación te explico cómo lo resolví paso a paso.
1. Crear el CPT “Webinars”
Lo primero es registrar un Custom Post Type llamado webinar.
Puedes hacerlo con un plugin como Custom Post Type UI o directamente con código en el functions.php:
register_post_type('webinar', array(
'labels' => array(
'name' => 'Webinars',
'singular_name' => 'Webinar',
),
'public' => true,
'has_archive' => true,
'menu_icon' => 'dashicons-video-alt3',
'supports' => array('title', 'editor', 'thumbnail'),
));
2. Añadir un campo personalizado “Activo / Inactivo”
Con Advanced Custom Fields (ACF) o manualmente, crea un campo personalizado para marcar si un webinar está activo.
En mi caso lo llamé webinar_activo, con valor 1 cuando está activo y vacío o 0 cuando no lo está.
3. Añadir el elemento al menú solo si hay webinars activos
Aquí viene la parte interesante.
Dentro del functions.php añadimos un filtro al menú principal que comprueba si existe algún webinar activo y, en ese caso, añade el enlace “Webinars”.
add_filter('wp_nav_menu_items', 'agregar_menu_webinars_activos', 10, 2);
function agregar_menu_webinars_activos($items, $args) {
if ($args->theme_location === 'primary') {
$webinars_activos = new WP_Query(array(
'post_type' => 'webinar',
'meta_key' => 'webinar_activo',
'meta_value' => '1',
'posts_per_page' => 1,
));
if ($webinars_activos->have_posts()) {
$items .= '<li><a href="/webinars">Webinars</a></li>';
}
wp_reset_postdata();
}
return $items;
}
Este código comprueba si existe al menos un webinar activo y, si es así, añade un nuevo elemento al menú principal con un enlace a la página de listado de webinars.
4. Mejorar el rendimiento con transients
Como esta consulta se ejecuta cada vez que se carga el menú, es recomendable guardar el resultado temporalmente con los transients de WordPress:
add_filter('wp_nav_menu_items', 'agregar_menu_webinars_activos', 10, 2);
function agregar_menu_webinars_activos($items, $args) {
if ($args->theme_location === 'primary') {
$hay_webinars_activos = get_transient('hay_webinars_activos');
if ($hay_webinars_activos === false) {
$query = new WP_Query(array(
'post_type' => 'webinar',
'meta_key' => 'webinar_activo',
'meta_value' => '1',
'posts_per_page' => 1,
'fields' => 'ids',
));
$hay_webinars_activos = $query->have_posts() ? 'sí' : 'no';
set_transient('hay_webinars_activos', $hay_webinars_activos, 5 * MINUTE_IN_SECONDS);
wp_reset_postdata();
}
if ($hay_webinars_activos === 'sí') {
$items .= '<li><a href="/webinars">Webinars</a></li>';
}
}
return $items;
}
5. Borrar la caché al guardar un webinar
Para que el menú se actualice en el momento en que se crea, edita o desactiva un webinar, podemos eliminar el transient automáticamente al guardar:
add_action('save_post_webinar', function() {
delete_transient('hay_webinars_activos');
});
Resultado final
Con este sistema:
-
Tienes un CPT “Webinars” totalmente funcional.
-
Puedes marcar cada webinar como activo o inactivo.
-
El menú principal mostrará el enlace “Webinars” solo cuando haya alguno activo.
-
Todo con buen rendimiento y sin depender de plugins adicionales.