¿Te gustaría tener un menú exclusivo para usuarios registrados y otro menú para visitantes?, en este artículo aprenderás cómo mostrar un menú diferente para usuarios registrados o para un rol específico, de manera sencilla y sin usar plugins.
Resultado Final

Generalidades
Primero tienes que tener dos menús creados, desde el backend de WordPress, en Apariencia > Menús, puedes crear ambos menús con sus respectivos ítems.

Es importante además asignar algún menú por defecto para la ubicación de menú que tiene tu theme, esta asignación de menú la cambiaremos posteriormente por código.

Seleccionar menú dinámicamente
De acuerdo a si el usuario es un usuario visitante o si es un usuario registrados, mostraremos uno u otro menú, para esto usaremos el siguiente código:
function dcms_menu_dinamico( $args ) {
if ( $args['theme_location'] == 'top'){
if ( is_user_logged_in() ) {
$args['menu'] = 'menu-registrados';
} else {
$args['menu'] = 'menu-visitantes';
}
}
return $args;
}
add_filter( 'wp_nav_menu_args', 'dcms_menu_dinamico' );
En el código anterior:
- Usamos un hook filtro llamado wp_nav_menu_args y hacemos referencia a la función dcms_menu_dinamico
- Dentro de la función, usamos el argumento $args que es un array asociativo, podemos usar los valores que se documentan en el siguiente enlace
- Usamos theme_location para comprobar la ubicación del menú con la que vamos a trabajar, en nuestro ejemplo es ‘top’, para aprender sobre ubicaciones de menús, puedes revisar el siguiente artículo
- Dentro de la condicional, usamos la función is_user_logged_in() para detectar si un usuario esta o no conectado, y de acuerdo a eso cambiamos el menú
- La asignación del menú puedes ser a través del ID, nombre del menú, o del slug, en el ejemplo hemos usado el slug.
Menú por un rol específico de usuario
Siguiendo la misma lógica anterior, podemos mostrar un menú para un determinado rol de algún usuario (autor, editor, etc) con el siguiente código:
function dcms_menu_dinamico_autores( $args ) {
if ( $args['theme_location'] == 'top'){
if ( is_user_logged_in() ) {
$user = wp_get_current_user();
if ( in_array('author', $user->roles) ){
$args['menu'] = 'menu-registrados';
}
}
}
return $args;
}
add_filter( 'wp_nav_menu_args', 'dcms_menu_dinamico_autores' );
En el código anterior:
- En este código he simplificado la condicional de usuario conectado, sin usar “else”, sólo se comprueba con is_user_logged_in() y se asume que tienes el menú de visitantes asignado por defecto.
- La única diferencia es que ahora obtenemos el objeto usuario con wp_get_current_user()
- Con el objeto usuario podemos saber los roles que tiene el usuario y comprobar el rol deseado, en nuestro caso el rol ‘author’
hola muy interesante el artículo, quisiera saber en que archivo, es decir donde pongo la función. y donde agrego el nuevo menu en caso de la opción de hacer dos menú
Hola en el video explico en donde agregar el código, te sugiero revises el video. Otra opción es: https://decodecms.com/agregar-codigo-a-tu-sitio-sin-usar-functions-php/
Muchas Gracias Jhon su material me ha sido de mucha ayuda. Tengo una duda todo me funciona perfectamente pero si me se la url de una pagina de las que no se puede mostrar a un usuario determinado y la pongo el buscador aunque no este en ese user se muestra. Como puedo tratar esas exepciones es decir si una persona quiere acceder a una pagina a la cual su rol no esta autorizada me redireccione para el login Saludos y gracias de antemano .
Hola, el menú que se mostrará para usuarios registrados, los ítems deben hacer referencia a elementos que controlen adicionalmente permisos. Por ejemplo tu menú privado debe tener ítems de menú que hagan referencia a entradas privadas.
Hola jhon me hace falta hacer este trabajo pero no encuentro la solucion espero me ayudes con algun ejemplo o donde encontrarlo. Saludos y muchas gracias
Buenas tardes, quisiera saber como puedo restringir la vista de productos a usuarios según un atributo de éste, por ejemplo yo le puse un atributo marca y deseo que un suscriptor no pueda ver un determinado valor del atributo marca.
Quedo atento y mucha gracias.
Hola creo que es algo muy personalizado y podría ser que se requiera hacer un plugin específico para tu caso. Si deseas puedes contactarme a través del formulario de contacto: https://decodecms.com/contacto/
Hola Jhon!
Primero, muchas gracias por este tutorial. Parece que en mi CMS no termina de funcionar. Como mi tema no había child theme, decidí hacerlo mediante el plugin de snipets que has recomendado en otro artículo. Aun así, no hay manera de que reaccione.
Puede ser que con las últimas actualizaciones haya algo que no se reconozca del código? Puede que esté haciendo mal algo? (Probablemente sea esto último, pero he llamado todo exactamente igual y no hay manera…)
Muchas gracias por leerme y un saludo!
Hola, para hacer un child theme no es necesario un plugin de snippets tienes que colocar el código en el functions.php del theme hijo, revisa : https://decodecms.com/crear-un-child-theme-en-wordpress-de-manera-correcta/
Buen material colega Jhon muy explicito, sin embargo no me está funcionando en una web que estoy configurando, necesito un menú para rol colaborador y otro para visitantes, al colocar el código en el archivo functions.php de mi tema hijo no logro el cambio, al descargar el plugin Snippet y colocar el fragmento de código lo activo pero nada me resulta podrás orientarme en este caso amigo? un saludo gracias por tus aportes igual me sirven de orientación.
Hola, tal vez estas usando un nombre de rol incorrecto, prueba también con otro theme padre directamente, uno de los themes por defecto y verifica. Si sigues con problemas puedes escribirme al formulario de contacto.
Hola. Tengo en mi wordpress el plugin nav menu roles, ya que he puesto un acceso a un área solo para usuarios registrados con el rol de suscriptor, sin embargo siento que usar un plugin solamente para este propósito es un tanto excesivo, no sé si dicho plugin afecta la velocidad de carga de mi web y si pueda hacerlo más ligero cambiando el plugin por un código en mi código que haga exactamente lo mismo, solo mostrar u ocultar un item de menú según el rol de usuario. ¿Me podrías decir si hay diferencia entre una opción y otra?
Hola, dudo que haya una diferencia significativa en la velocidad de respuesta, salvo el plugin este mal programado. Podrías igual evaluar un plugin de cache adicional en caso notes problemas de lentitud.
Evaluaré hacer un artículo sobre cómo mostrar/ocultar opciones de menú específicas a través sólo de código.
Saludos.
Hola..Gracias por tu aporte amigo.
Tengo un problema, primero te comento que estoy trabajando con astra, y al abrir el archivo functions.php, no me visualiza nada del codigo que te aparece a ti del: register_nav_menus…
Por logica que al colocar el codigo que nos brindas, no se visualiza ningun cambio.
Ayuda por favor, te lo agradecere mucho..
Hola, lo primero sería buscar con que nombre tu tema te registra el menú, busca la función register_nav_menus en otros archivos, puedes abrir una carpeta de tu tema en tu máquina local y usar algún editor como Sublime Texto o Visual Studio Code para abrir una carpeta y buscar el texto en todos los archivos, una vez tengas el nombre cambialo por “primary” en el código y agrégalo en el functions.php de tu tema
Hola Jhon, de ante mano te agradezco por este artículo. No entiendo a que te referís con “Primary”. A mi me pasa como a Ronald, ubique la función register_nav_menus en otro archivo llamado “theme-menu.php” pero no logro hacer que funcione colocando el código en el functions.php de mi tema.
Hola, Primary es una posición que usualmente usan los themes, pero, en tu caso es posible que tu theme no la llame así, eso por eso que debes buscar en la función register_nav_menus(), debe aparecer como parámetro el nombre de las posiciones de tu theme.
Buenas Jhon, un placer y muy buenos tutoriales! tengo una duda, si quiero hacer para mas de un rol especifico como lo hago? Tengo que hacer el mismo procedimiento para todos, e ir cambiando el rol?
Te sigo viendo y muchas gracias.
Hola, si, en el mismo código con un elseif puedes agregar roles adicionales, por ejemplo para un rol2
Saludos.
Hola, ya he agregado el código que nos proporcionaste para que se muestre una página más si el usuario está registrado, pero no aparece (utilizo Divi y el código lo agregué con snippets. ¿Tienes alguna idea de qué pudiera estar pasando? Gracias!!
Hola, tal vez los nombres de menú no son correctos en Divi o tal vez estas usando el contructor de temas, en este caso es dificil conocer que nombre le asignará al menú.