✅ Nowości, motywy, wtyczki WEB i WordPress. Tutaj dzielimy się wskazówkami i najlepszymi rozwiązaniami dla stron internetowych.

Samouczek WordPress: Niestandardowe menu dla postów lub stron na pasku bocznym

30

Ten post jest dla Ciebie, który zarządza witryną WordPress, która ma dużo treści, prawdopodobnie wiele stron uporządkowanych hierarchicznie i chcesz mieć lepszą nawigację poza menu głównym. Aby ułatwić poruszanie się po witrynie, ogromnie pomoże niestandardowe menu związane z aktualnym postem. Problem z umieszczeniem widżetu menu na pasku bocznym (lub gdziekolwiek chcesz) polega na tym, że pasek boczny jest powszechny. W tym poście dowiemy się, jak wyświetlić dodatkowe niestandardowe menu na pasku bocznym, umożliwiając postom, stronom lub niestandardowym typom postów wybór menu.

Dodaj poniższy kod w motywie functions.phplub w kodzie wtyczki.

Zezwalaj postom lub stronom na wybór menu

Tworzenie menu w WordPressie jest łatwe i możesz użyć widżetu Menu, aby wyświetlić menu na pasku bocznym. Problem polega na tym, że pasek boczny jest globalny i wszędzie będzie wyświetlane to samo menu. Co zrobić, jeśli chcesz, aby określone menu były wyświetlane na określonych stronach? Dowiesz się również, jak upewnić się, że wybrane menu jest dziedziczone przez strony podrzędne. W ten sposób wystarczy wybrać menu na stronie nadrzędnej. Wszelkie podstrony również pokażą to samo menu bez konieczności ich edycji.

Dodanie metabox do wyboru menu

Pierwszym krokiem jest stworzenie metaboxu na posty lub strony, gdzie mamy możliwość wyboru menu. Używamy funkcji add_meta_box()i decydujemy, dla jakich typów postów chcemy ją pokazać.

add_action('add_meta_boxes', function() {
    add_meta_box('metabox-sidebar-menu', __('Sidebar Menu', 'txtdomain'), 'awp_sidebar_menu_metabox_callback', ['post', 'page']);
});

Dostosuj powyższy kod do tytułu i typów postów, które chcesz. Powyższy przykład doda metabox zarówno do postów, jak i stron. Trzecim parametrem, który nazwałem awp_sidebar_menu_metabox_callback, jest funkcja odpowiedzialna za renderowanie zawartości metaboksu. Zdefiniujmy to dalej. Oto, co musimy zrobić w naszym metaboksie:

function awp_sidebar_menu_metabox_callback($post) {
    // Get all menus
 
    // Get the current saved menu, if set
 
    // Output HTML with a select showing all menus, and mark the currently saved one as selected
}

Tablicę ze wszystkimi zapisanymi menu w WordPressie możemy uzyskać za pomocą wp_get_nav_menus(). Jeśli chodzi o pobieranie aktualnie wybranego menu, przechowujemy wybrane menu jako meta postu awp_sidebar_menu(nazywaj je, jak chcesz), a my po prostu pobieramy wartość na podstawie prądu $postdostarczonego nam w funkcji metabox. Zapiszemy identyfikatory menu, ponieważ to wszystko, czego potrzebujemy, aby wyświetlić menu. A potem wypisujemy HTML dla zaznaczenia, które przechodzi przez menu. Wynik HTML metaboksu zależy od Ciebie, poniżej jest przykład. Dołączyłem również funkcjonalność nonce dla bezpieczeństwa.

function awp_sidebar_menu_metabox_callback($post) {
    // Get all menus
    $menus = wp_get_nav_menus();
 
    // Get the current saved menu, if set
    $current_selected = get_post_meta($post->ID, 'awp_sidebar_menu', true);
 
    // Output HTML with a select showing all menus, and mark the currently saved one as selected
    wp_nonce_field('awp_sidebar_menu_metabox_nonce', 'awp_sidebar_menu_nonce');
    ?><div class="awp-metabox-item">
        <div class="awp-metabox-label"><label><?php _e('Choose menu', 'txtdomain'); ?></label></div>
        <div class="awp-metabox-input"><?php
        if (empty($menus)) {
            echo '<p>'. __('No menus created.', 'txtdomain'). '</p>';
        } else { ?>
            <select name="awp-sidebar-menu" id="awp-sidebar-menu">
                <?php 
                echo '<option value="">'. __('Choose menu', 'txtdomain'). '</option>';
                foreach ($menus as $menu) { 
                    echo '<option value="'. $menu->term_id. '" '.selected($current_selected, $menu->term_id).'>'.$menu->name.'</option>';
                } ?>
            </select>
        <?php } ?>
        </div>
    </div><?php
}

W wyniku HTML drukuję etykietę. Jeśli w WordPressie nie ma żadnych zapisanych menu, po prostu wyświetli akapit. W przeciwnym razie generowany jest wybór z identyfikatorami menu jako wartościami i nazwami menu jako etykietą. Dodaję również pusty wybór, aby posty nie wyświetlały menu. Korzystam z funkcji pomocniczej WordPressa [selected](https://developer.wordpress.org/reference/functions/selected/)()do zaznaczania aktualnie zapisanej opcji jako wybranej.

Jeśli edytujesz post lub stronę, na dole powinno pojawić się metabox z zaznaczeniem. Wspaniały! Jednak w tym momencie nie zapisze wyboru menu podczas zapisywania posta. To kolejny krok.

Zapisywanie wyboru menu

Używamy haka save_postdo tworzenia funkcji, która zapisuje każdy wybór, który dodaliśmy w naszym metaboksie. Podpięcie save_postjest uruchamiane za każdym razem, gdy post jest zapisywany lub aktualizowany. Najpierw sprawdzimy wartość jednorazową (jeśli nie masz pewności, co to są, sprawdź ten przewodnik WordPressa o wartościach jednorazowych ). Następnie dwukrotnie sprawdzamy, czy użytkownik może aktualizować posty, i aktualizujemy naszą meta postu o wybór.

add_action('save_post', function($post_id) {
    if (!isset($_POST['awp_sidebar_menu_nonce']) || !wp_verify_nonce($_POST['awp_sidebar_menu_nonce'], 'awp_sidebar_menu_metabox_nonce')) {
        return;
    }
 
    if (!current_user_can('edit_post', $post_id)) {
        return;
    }
 
    update_post_meta($post_id, 'awp_sidebar_menu', $_POST['awp-sidebar-menu']);
});

Teraz, gdy aktualizujesz posty, zapisze również Twój wybór menu.

I to tyle, jeśli chodzi o część dotyczącą wyboru postów. Następnym krokiem jest w rzeczywistości wyświetlenie menu, jeśli zostało wybrane menu.

Wybór pozycji dla niestandardowego menu

Dodaję dane wyjściowe na pasku bocznym, ale możesz je wyprowadzić w dowolnym miejscu w szablonach motywu. Potrzebujemy tylko predefiniowanego haka lub zdefiniowania własnego. Jako przykład dodaję niestandardowy zaczep na górze paska bocznego, abym mógł utworzyć podłączoną do niego funkcję.

Możesz po prostu zadzwonić wp_nav_menu()bezpośrednio w szablonie, ale zamiast tego zalecam utworzenie niestandardowego hooka, ponieważ dodamy sporo kodu i może się to wydawać nieuporządkowane.

W moim motywie, który edytuję sidebar.phpi tuż przed dynamic_sidebar()wywołaniem paska bocznego (gdzie dodawane są widżety), dodaję mój niestandardowy hak z do_action()podaną nazwą. Możesz go nazwać, jak chcesz, ale musi być unikalny w WordPressie. Więc przynajmniej poprzedź to czymś wyjątkowym dla Ciebie.

<aside class="sidebar">
    <?php 
    do_action('awp_before_sidebar');
    dynamic_sidebar('left-sidebar'); 
    ?>
</aside>

Renderowanie menu

Teraz możemy wrócić do functions.php, zdefiniować podłączoną funkcję, awp_before_sidebara jej wynik zostanie wyświetlony na pasku bocznym przed widżetami. Funkcja użyje tagów warunkowych WordPress, aby sprawdzić, czy aktualnie wyświetlamy pojedynczy post lub stronę. A jeśli tak, pobiorę naszą meta postu. Jeśli ustawiono meta posta, wyprowadzamy menu, wywołując [wp_nav_menu](https://developer.wordpress.org/reference/functions/wp_nav_menu/)()i podając identyfikator zapisanego menu jako jego menuparametr.

add_action('awp_before_sidebar', function() {
    if (is_singular()) {
        global $post;
 
        $sidebar_menu = get_post_meta($post->ID, 'awp_sidebar_menu', true);
    }
 
    if (!empty($sidebar_menu)) {
        ?><section class="widget awp-sidebar-menu">
            <?php wp_nav_menu(['menu' => $sidebar_menu]); ?>
        </section><?php
    }
});

Powinieneś dostosować kod HTML wokół menu, aby pasował do reszty treści. W powyższym kodzie zawijam menu w ten sam kod HTML, w którym są zawinięte wszystkie widżety na pasku bocznym, dzięki czemu styl widżetu motywu ma zastosowanie do naszego niestandardowego menu.

Otóż ​​to! Za każdym razem, gdy wybierzesz menu w poście lub na stronie, menu zostanie wyświetlone nad paskiem bocznym podczas przeglądania tego posta lub strony.

Możemy jednak pójść o krok dalej. Jeśli chcesz, aby strony dla dzieci pokazywały to samo menu paska bocznego ustawione u któregokolwiek z rodziców, czytaj dalej.

Zezwalaj stronom podrzędnym na dziedziczenie menu rodzica

Ta dodatkowa funkcja ma sens, jeśli masz wiele stron w hierarchii lub niestandardowy typ posta z włączoną hierarchią. Edytowanie każdej strony podrzędnej i wybieranie tego samego menu byłoby zbyt kłopotliwe. W takim przypadku lepiej byłoby wybrać menu na stronie nadrzędnej i automatycznie pozwolić wszystkim podstronom „dziedziczyć" ten wybór menu. Jeśli jakakolwiek podstrona wybierze inne menu, to menu zostanie wyświetlone raz zamiast „odziedziczonego”.

Wewnątrz naszej funkcji podpiętej do awp_before_sidebar, dodamy fragment kodu, wewnątrz sprawdzania, czy oglądamy pojedynczy post lub stronę:

        ...
        $sidebar_menu = get_post_meta($post->ID, 'awp_sidebar_menu', true);
        if (!empty($sidebar_menu)) {
            $parents = get_post_ancestors($post->ID);
            if (!empty($parents)) {
                // go step by step up the parents tree
                for ($i = 0; $i < count($parents); $i++) {
                    $sidebar_menu = get_post_meta($post->ID, 'awp_sidebar_menu', true);
                    if (!empty($sidebar_menu)) {
                        break;
                    }
                }
            }
        }
    }
 
    if (!empty($sidebar_menu)) {
        ...

Co robi powyższy kod, jeśli nie znaleziono menu na bieżącej stronie, pobiera wszystkich rodziców za pomocą [get_post_ancestors](https://developer.wordpress.org/reference/functions/get_post_ancestors/)(). Ta funkcja zwraca tablicę nadrzędnych identyfikatorów postów posortowanych najpierw według najbliższego rodzica. Jeśli strona nie ma rodziców (na przykład jeśli jest to post), zwracana jest pusta tablica. A jeśli są jacyś rodzice, przechodzimy przez każdego rodzica po kolei i sprawdzamy, czy ustawili naszą meta postu. Jeśli taki zostanie znaleziony, wyrwiemy się z przechodzenia przez rodziców i $sidebar_menuzostanie ustawiony, a menu zostanie wyświetlone później za pomocą wp_nav_menu().

I to tyle, jeśli chodzi o funkcjonalność „dziedziczenia”!

Źródło nagrywania: awhitepixel.com

Ta strona korzysta z plików cookie, aby poprawić Twoje wrażenia. Zakładamy, że nie masz nic przeciwko, ale możesz zrezygnować, jeśli chcesz. Akceptuję Więcej szczegółów