Cum să ascunzi un element din meniu pentru utilizatorii neautentificați (fără plugin)

31 iul. 2016, 12:01:06
Vizualizări: 30.5K
Voturi: 4

Vreau să ascund un element din meniu dacă un utilizator nu este autentificat.

În prezent folosesc codul de mai jos care realizează acest lucru folosind două meniuri separate, dar pentru a evita duplicarea, aș dori să gestionez un singur meniu de navigare.

function my_wp_nav_menu_args( $args = '' ) {

    if ( is_user_logged_in() ) { 
        $args['menu'] = 'autentificat';
    } else { 
        $args['menu'] = 'neautentificat';
    }

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

Este posibil să ascund doar un singur element pentru un utilizator neautentificat, în loc să procedez în modul în care o fac în prezent?

3
Comentarii

ce vrei să ascunzi dintr-un meniu?

mmm mmm
31 iul. 2016 12:33:00

Un link care nu este vizibil pentru utilizatorii neînregistrați.

Iqbal Mahmud Iqbal Mahmud
31 iul. 2016 13:02:30

Lucrul "fără un plugin" nu este niciodată necesar. O astfel de logică este independentă de designul și stilizarea ta și ar trebui să supraviețuiască unei reproiectări a site-ului tău. Pune-o într-un plugin sau un mu-plugin. A avea sute de mini-plugin-uri în loc de un functions.php mare sau un plugin extrem de mare nu încetinește site-ul tău.

kaiser kaiser
31 iul. 2016 15:51:15
Toate răspunsurile la întrebare 7
1

Filtrează wp_nav_menu_objects. Va conține lista sortată de elemente din meniul de navigare pentru randare. Consultă wp_setup_nav_menu_item pentru unele proprietăți pe care le poți folosi.

Iată un exemplu rapid (netestat).

add_filter( 'wp_nav_menu_objects', function( array $items, object $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 );
31 iul. 2016 15:10:36
Comentarii

Acest cod este invalid, deoarece wp_nav_menu_objects primește array $sorted_menu_items, stdClass $args, nu array $items, array $args

User User
9 mar. 2023 02:28:56
2

În timp ce @chrisguitarguy a adăugat deja un răspuns mai mult decât valid în timp ce scriam acest răspuns, iată o simplă adăugare la celelalte două răspunsuri.

Valoarea de return a funcției wp_setup_nav_menu() are un filtru, care are $menu_item ca singură valoare furnizată – exact înainte de a fi returnată – și este de tip object și un \stdClass cu următoarele proprietăți public pe care le puteți verifica:

  • ID: term_id dacă elementul de meniu reprezintă un termen de taxonomie.
  • attr_title: Atributul title al elementului de link pentru acest element de meniu.
  • classes: Matricea de valori ale atributului class pentru elementul de link al acestui element de meniu.
  • db_id: ID-ul din baza de date al acestui element ca obiect nav_menu_item, dacă există (0 dacă nu există).
  • description: Descrierea acestui element de meniu.
  • menu_item_parent: ID-ul din baza de date al nav_menu_item care este părintele acestui element de meniu, dacă există. 0 în caz contrar.
  • object: Tipul de obiect reprezentat inițial, cum ar fi "category", "post" sau "attachment".
  • object_id: ID-ul din baza de date al obiectului original pe care îl reprezintă acest element de meniu, de exemplu ID pentru postări și term_id pentru categorii.
  • post_parent: ID-ul din baza de date al obiectului părinte al obiectului original, dacă există (0 în caz contrar).
  • post_title: O etichetă "fără titlu" dacă elementul de meniu reprezintă o postare care nu are titlu.
  • target: Atributul target al elementului de link pentru acest element de meniu.
  • title: Titlul acestui element de meniu.
  • type: Familia de obiecte reprezentate inițial, cum ar fi "post_type" sau "taxonomy".
  • type_label: Eticheta singulară folosită pentru a descrie acest tip de element de meniu.
  • url: URL-ul către care indică acest element de meniu.
  • xfn: Relația XFN exprimată în link-ul acestui element de meniu.
  • _invalid: Dacă elementul de meniu reprezintă un obiect care nu mai există.

Deci, un simplu callback vă va permite să folosiți o logică condițională și apoi poate să excludeți un element:

add_filter( 'wp_setup_nav_menu', function( \stdClass $item ) {
    # Verificați condițiile și invalidați un element în caz
    $item->_invalid = is_user_logged_in() 
        && 'post' === $item->object
        && 'post_type' === $item->type
        # && … orice altceva trebuie să verificați pentru invalidarea unui element
    ;

    return $item;
} );

Logica de excludere se află în interiorul proprietății _invalid și este executată de funcția _is_valid_nav_menu_item( $item ) care este un callback folosit când elementele de meniu sunt preluate. Aceasta o folosește în interiorul unui array_filter() pentru a reduce numărul de elemente în funcție de acest flag.


Ca extensie la soluția lui @MD Sultan Nasir Uddin: În timp ce o soluție doar cu CSS va funcționa, scopul ar trebui să fie să nu aveți date în această cerere, în interogarea bazei de date și în pipeline-ul de randare. Pentru un răspuns complet, iată în continuare cum: Exemplu folosind wp_add_inline_style() pentru a include stilurile inline și sintaxa heredoc PHP pentru lizibilitate:

<?php
/** Plugin Name: Ascunde elementele de meniu pentru utilizatorii autentificați */

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

# Adaugă stiluri inline
add_action( 'wp_enqueue_scripts', function() {

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

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

Ați putea probabil să folosiți doar clasele body pentru a găsi o clasă logged-in sau similară pentru o țintă mai specifică – în loc să adăugați o clasă suplimentară ca mai sus.

31 iul. 2016 15:49:42
Comentarii

Acel lucru _invalid este destul de ingenios.

chrisguitarguy chrisguitarguy
31 iul. 2016 16:11:31

@chrisguitarguy Este! Și nu știam despre el până nu ai postat răspunsul și am citit prin cod. Singurul lucru la care nu sunt sigur acum este dacă nu ar trebui să fie pur și simplu false atunci când vrei să renunți la ceva.

kaiser kaiser
31 iul. 2016 17:41:12
1

După aceea, am reușit să o fac folosind CSS nth-child, procedura este următoarea:

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;
}

Vă mulțumesc tuturor pentru efortul depus :)

8 aug. 2016 09:05:29
Comentarii

Aceasta nu va funcționa dacă elementul de meniu își schimbă poziția.

Alexander Holsgrove Alexander Holsgrove
4 mar. 2021 13:13:24
0

Nu-mi place ideea de a ascunde elementele de meniu doar cu CSS, deoarece acestea ar rămâne vizibile folosind inspectorul de cod de pe pagină. Pentru cei care caută o metodă mai sigură de a elimina elementele de meniu, acest cod ar trebui să facă treaba:

În acest exemplu, doresc să elimin elementul de meniu "Descărcări" pentru orice utilizator care nu este autentificat.

add_filter( 'wp_nav_menu_objects', 'remove_menu_items' ), 10, 2 );
function remove_menu_items( $items, $args ) {

    // Dacă trebuie să elimini mai multe elemente de meniu, este o practică bună să setezi o variabilă pentru verificare în prealabil, astfel încât să nu rulezi aceeași funcție de verificare în mod repetat.
    $logged_in = is_user_logged_in();

    foreach ( $items as $item_index => $item ) {
        // Elimină elementul de meniu "Descărcări" când utilizatorul nu este autentificat
        if ( $item->title == 'Descărcări' ) {
            if ( !$logged_in ) {
                unset($items[$item_index]);
            }
        }
    }
    return $items;
}
28 iun. 2022 00:29:30
0

Bazat pe răspunsul lui @jamio, sunt de acord că dacă doar folosești display:none pentru meniu, acesta rămâne accesibil prin inspect element. Prin urmare, am venit cu o soluție prin care poți ascunde elementele din meniu bazându-te pe clasa lor, folosind classes[0] în loc de title. Astfel, poți adăuga pur și simplu o clasă pe elementul de meniu în loc să-l setezi individual prin cod.

 add_filter( 'wp_nav_menu_objects', 'remove_menu_items', 10, 2 );
function remove_menu_items( $items, $args ) {

    $logged_in = is_user_logged_in();

    foreach ( $items as $item_index => $item ) {
        // Elimină elementul de meniu cu clasa "hide_when_logout" când utilizatorul nu este autentificat
        if ( $item->classes[0] == 'hide_when_logout' ) {
            if ( !$logged_in ) {
                unset($items[$item_index]);
            }
        }
    }
    return $items;
}
23 oct. 2022 14:25:12
2
<?php
//Apoi în fișierul header.php al temei tale, înainte de închiderea tag-ului head, folosește următorul cod
//https://wordpress.stackexchange.com/questions/233667/how-to-hide-an-item-from-a-menu-to-logged-out-users-without-a-plugin
    <?php
 if ( is_user_logged_in() ) {
       $output="<style>.menu-item-8685 {display: none !important;}</style>";
echo $output;
    } else {  
         echo '<script>alert("Bun venit vizitator")</script>';
    }
     ?>
4 mar. 2021 01:16:59
Comentarii

Aceasta este o combinație între răspunsul acceptat și răspunsul lui Iqbal?

Rup Rup
4 mar. 2021 02:26:13

da, acesta este un răspuns | și a funcționat perfect la mine...

Mohannad Najjar Mohannad Najjar
14 mar. 2021 19:36:07
3
-3

Găsește clasa sau ID-ul elementului de meniu pe care dorești să-l ascunzi. presupunem că clasa acelui meniu este logged-in-menu

Apoi, în fișierul header.php al temei tale, înainte de închiderea tag-ului head, folosește următorul cod

<style>
<?php if(! is_user_logged_in() ) : ?>
    .logged-in-menu{
        display: none;
    }
<?php endif; ?>
</style>
31 iul. 2016 14:07:08
Comentarii

Aceasta înseamnă că (a) interogați date inutile și (b) este ireversibil pentru temele copil sau plugin-uri. Ați putea dori să folosiți cel puțin un callback atașat la wp_head sau să înregistrați și să încărcați corect stilurile. Chiar dacă atunci ar fi o soluție întrucâtva acceptabilă, ar fi totuși de preferat să dezactivați condiționat acele elemente înainte de a le interoga din baza de date.

kaiser kaiser
31 iul. 2016 15:03:24

Pentru oricine se gândește să folosească acest lucru, vă rog să nu o faceți. Folosiți hook-urile corecte pentru meniu conform răspunsului lui @chrisguitarguy.

Alexander Holsgrove Alexander Holsgrove
4 mar. 2021 13:16:18

Aceasta este o prostie. Orice script kiddie poate totuși să vadă meniul tău.

User User
9 mar. 2023 02:22:19