Skip to content
Atrás

Mostrar un item del menú solo cuando haya algun post activo dentro de un CPT.

Actualizado:
Editar página

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() ? '' : 'no';
            set_transient('hay_webinars_activos', $hay_webinars_activos, 5 * MINUTE_IN_SECONDS);

            wp_reset_postdata();
        }

        if ($hay_webinars_activos === '') {
            $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:


Editar página
Comparte:

Siguiente
Planteamos un sistema de donaciones con Gravity Forms y pagos recurrentes