Cómo ocultar un elemento de un menú a los usuarios que han cerrado sesión (sin un complemento)

2

Quiero ocultar un elemento de un menú si un usuario está desconectado.

Actualmente estoy usando el siguiente código que logra esto usando dos menús separados, pero para guardar la duplicación, me gustaría tener que administrar solo un menú de navegación.

function my_wp_nav_menu_args( $args = '' ) {

    if ( is_user_logged_in() ) { 
        $args['menu'] = 'logged-in';
    } else { 
        $args['menu'] = 'logged-out';
    }

    return $args;
}
add_filter( 'wp_nav_menu_args', 'my_wp_nav_menu_args' );

¿Es posible ocultar un solo elemento para un usuario que ha cerrado sesión, en lugar de hacerlo de la forma en que estoy actualmente?

    
pregunta Iqbal Mahmud 31.07.2016 - 11:01

3 respuestas

3

Como @chrisguitarguy ya agregó una respuesta más que válida mientras escribía esta respuesta, aquí hay una simple adición a las otras dos respuestas.

El valor return de la función wp_setup_nav_menu() tiene , que tiene $menu_item como único valor proporcionado, exactamente antes de que se devuelva, y es del tipo object y \stdClass con las siguientes propiedades public que puede verificar:

  • ID : el term_id si el elemento del menú representa un término de taxonomía.
  • attr_title : el atributo de título del elemento de enlace para este elemento de menú.
  • classes : la matriz de valores de atributo de clase para el elemento de enlace de este elemento del menú.
  • db_id : el ID de DB de este elemento como un objeto nav_menu_item, si existe (0 si no existe).
  • description : la descripción de este elemento de menú.
  • menu_item_parent : el ID de la base de datos de nav_menu_item que es el elemento primario del menú de este elemento, si corresponde. 0 de lo contrario.
  • object : el tipo de objeto originalmente representado, como "categoría", "publicación" o "adjunto".
  • object_id : el ID de DB del objeto original que representa este elemento de menú, por ejemplo, ID para publicaciones y term_id para categorías.
  • post_parent : el ID de la base de datos del objeto principal del objeto original, si existe (0 en caso contrario).
  • post_title : una etiqueta de "sin título" si el elemento del menú representa una publicación que carece de un título.
  • target : el atributo de destino del elemento de enlace para este elemento de menú.
  • title : el título de este elemento del menú.
  • type : la familia de objetos originalmente representados, como "post_type" o "taxonomy".
  • type_label : la etiqueta singular utilizada para describir este tipo de elemento de menú.
  • url : la URL a la que apunta este elemento del menú.
  • xfn : la relación XFN expresada en el enlace de este elemento del menú.
  • _invalid : si el elemento del menú representa un objeto que ya no existe.

Por lo tanto, una simple devolución de llamada te permitirá usar un poco de lógica condicional y tal vez excluir un elemento:

add_filter( 'wp_setup_nav_menu', function( \stdClass $item ) {
    # Check conditionals, and invalidate an item in case
    $item->_invalid = is_user_logged_in() 
        && 'post' === $item->object
        && 'post_type' === $item->type
        # && … whatever you need to check for your invalidation of an item
    ;

    return $item;
} );

La lógica de exclusión se encuentra dentro de la propiedad _invalid y se ejecuta mediante _is_valid_nav_menu_item( $item ) es una devolución de llamada que se usa cuando los elementos del menú de navegación se recuperan . Lo usa dentro de array_filter() para reducir el número de elementos dependiendo de esta bandera .

Como extensión de la solución @MD Sultan Nasir Uddin: si bien una solución solo para CSS funcionará, el objetivo debe ser ni siquiera tener los datos en esta solicitud, en la consulta de la base de datos y en la canalización de procesamiento. Para obtener una respuesta completa, aquí está el cómo : ejemplo utilizando wp_add_inline_style() para incluir el estilos y sintaxis heredoc de PHP para facilitar la lectura:

<?php
/** Plugin Name: Hide menu items for logged in users */

# Add class:
add_filter( 'wp_nav_menu_args', function( Array $args ) {
    if ( is_user_logged_in() )
        $args['menu_class'] .= '  logged-in';
    return $args;
} );

# Add inline styles
add_action( 'wp_enqueue_scripts', function() {

    $styles = <<<STYLES
.logged-in .special-item {
    display: none;
}
STYLES;

    wp_add_inline_style( 'custom-style', $styles );
} );

Probablemente podría usar las clases body para encontrar una clase logged-in o similar para un objetivo más específico también, en lugar de agregar una clase adicional como la anterior.

    
respondido por el kaiser 31.07.2016 - 14:49
2

Después de eso, lo hago con css nth child, el procedimiento es

add_action('wp_head','hide_menu');

function hide_menu() { 
    if ( is_user_logged_in() ) {
        //
    } else {
        $output="<style> .menu li:nth-child(3) { display: none; } </style>";
    }
    echo $output;
}

Gracias a todos por su esfuerzo :)

    
respondido por el Iqbal Mahmud 08.08.2016 - 08:05
2

Filtre wp_nav_menu_objects . Contendrá la lista ordenada de elementos del menú de navegación para renderizar. Echa un vistazo a wp_setup_nav_menu_item utilizar.

Aquí hay un ejemplo rápido (no probado).

add_filter( 'wp_nav_menu_objects', function( array $items, array $args ) {

    if ( 'someThemeLocation' !== $args->theme_location ) {
        return $items;
    }

    return array_filter( $items, function( $item ) {
        return '/user-specific-thingy' === $item->url 
            && ! is_user_logged_in();
    } );

}, 10, 2 );
    
respondido por el chrisguitarguy 31.07.2016 - 14:10

Lea otras preguntas en las etiquetas