WordPress por defecto no tiene una funcionalidad para establecer ítems de menú privados, tal como lo hace con las páginas o entradas, en este artículo veremos como agregar esta funcionalidad a través de código.
Resultado Final
Al final queremos obtener algo similar a lo que se muestra en la siguiente imagen para cada ítem de menú.
Código para mostrar un campo adicional en la administración de ítems de menú
Para facilitar la tarea de establecer cuales ítems de menú serán sólo visibles a usuarios registrados usaremos este código que nos creará un nuevo campo en la configuración de los ítems de menú.
El valor lo almacenamos como parte de los metadatos del ítem de menú.
// Hook para agregar un nuevo campo a la configuración de un ítem de menú
add_action( 'wp_nav_menu_item_custom_fields', 'agregar_checkbox_item_menu', 10, 5 );
function agregar_checkbox_item_menu( $item_id, $item, $depth, $args, $id ): void {
?>
<p class="description description-wide">
<label for="edit-menu-item-registered-<?php echo $item_id; ?>">
<input type="checkbox" id="edit-menu-item-registered-<?php echo $item_id; ?>"
name="menu-item-registered[<?php echo $item_id; ?>]"
<?php checked( get_post_meta( $item_id, '_menu_item_registered', true ), '1' ); ?> />
<span>Sólo mostrar para usuarios registrados</span>
</label>
</p>
<br>
<?php
}
// Guardar el valor del campo personalizado
add_action( 'wp_update_nav_menu_item', 'guardar_checkbox_item_menu', 10, 3 );
function guardar_checkbox_item_menu( $menu_id, $menu_item_db_id, $args ): void {
$value = isset( $_POST['menu-item-registered'][ $menu_item_db_id ] ) ? '1' : '0';
if ( $value === '0' ) {
delete_post_meta( $menu_item_db_id, '_menu_item_registered' );
} else {
update_post_meta( $menu_item_db_id, '_menu_item_registered', $value );
}
}
En el código anterior:
- La primera porción de código simplemente crea el nuevo campo HTML, que será un checkbox
- Para esto usamos el hook wp_nav_menu_item_custom_fields y usamos código HTML adicional para envolver el nuevo campo
- La otra porción de código la usamos para guardar el valor del campo si esta marcado o no, usamos el Hook wp_update_nav_menu_item
- Los ítems de menú, son un tipo de contenido en WordPress por lo que usamos las tablas de posts y para guardar metadata la tabla postmeta
Ocultar el ítem de menú en el front-end del sitio
Los ítems que están marcados sólo deberían ser visibles por usuarios registrados, es por eso que agregaremos una clase CSS a los ítems marcados cuando lo visualice un visitante. La clase CSS se llamará ‘hide’.
// Agregar una clase CSS a los items que no deberían aparecer en el front-end
add_filter( 'wp_get_nav_menu_items', 'ocultar_items_menu_usuarios_no_registrados', 10, 3 );
function ocultar_items_menu_usuarios_no_registrados( $items, $menu, $args ) {
if ( ! is_user_logged_in() ) {
foreach ( $items as $item ) {
$only_registered = get_post_meta( $item->ID, '_menu_item_registered', true );
if ( $only_registered ) {
$item->classes[] = 'hide';
}
}
}
return $items;
}
En el código anterior:
- Simplemente usamos el Hook wp_get_nav_menu_items en la función a la que hace referencia comprobamos si el usuario esta o no conectado
- Si es un usuario visitante entonces recorremos los ítems de menú y si tiene el metadato _menu_item_registered, entonces agregamos una clase CSS llamada hide
En el archivo style.css de tu tema hijo puedes agregar el siguiente código CSS que define la clase hide.
.hide {
display: none!important;
}
Seguridad si se trata de acceder directamente a la URL
Como paso final, en caso no hayas establecido el contenido como privado y todo lo quieras controlar desde los ítems de menú, se puede agregar condiciones adicionales para redireccionar en caso la URL se encuentre como privada.
// Redirigir si un usuario no registrado intenta acceder a la URL directamente
add_action( 'template_redirect', 'redirigir_usuarios_no_registrados' );
function redirigir_usuarios_no_registrados(): void {
if ( ! is_user_logged_in() ) {
// ===> Reemplaza 'Main Menu' con el nombre de tu menú
$menu_items = wp_get_nav_menu_items( 'Main Menu' );
$current_url = home_url( add_query_arg() );
foreach ( $menu_items as $item ) {
if ( $current_url === $item->url ) {
if ( get_post_meta( $item->ID, '_menu_item_registered', true ) ) {
wp_redirect( home_url() );
exit;
} else {
break;
}
}
}
}
}
En el código anterior:
- En el código anterior usamos el Hook template_redirect
- El código sólo se ejecutará cuando el usuario es visitante
- Hay que obtener los items del menú que nos interesa, hay que cambiar el nombre del menú
- Obtenemos la URL actual que se esta visitando
- Recorremos los ítems de menú y verificamos si la URL actual coincide con alguna del menú
- Si coincide entonces comprobamos la metadata para ver si es una URL privada
- Si es privada entonces hacemos una redirección
- Si no es privada simplemente terminamos el bucle
Conclusión
Como has podido comprobar es posible restringir los ítems de menú de tu sitio web para que sólo sean visibles y accesibles por usuarios registrados, en este artículo hemos visto como realizarlo a través de código.
La entrada Establecer ítems de menú sólo para usuarios registrados es un artículo reciente del sitio DecodeCMS.
0 Commentaires