Вопрос

I'm attempting to add my logo to the middle of my navbar, and while looking at the nav walker class I couldn't figure what the best way to do this would be.

So my question is essentially how do I do that. the Walker_Nav_Menu() method start_el() seems to build only one li so where is it iterating over all of them and writing them to file.

Это было полезно?

Решение

You need to make your own walker menu (i am guessing you already know that), and the best way i think is overriding the function that ends each menu item which is end_el :

class logo_in_middle_Menu_Walker extends Walker_Nav_Menu {

    public $menu_location = 'primary';

    function __construct($menu_location_var) {
        // parent class doesnt have a constructor so no parent::__construct();
        $this->menu_location = $menu_location_var;
    }

    public function end_el(&$output, $item, $depth = 0, $args = array()) {
        $locations = get_nav_menu_locations(); //get all menu locations
        $menu = wp_get_nav_menu_object($locations[$this->menu_location]); //one menu for one location so lets get the menu of this location
        $menu_items = wp_get_nav_menu_items($menu->term_id);

        $top_lvl_menu_items_count = 0; //we need this to work with a menu with children too so we dont use simply $menu->count here
        foreach ($menu_items as $menu_item) {
            if ($menu_item->menu_item_parent == "0") {
                $top_lvl_menu_items_count++;
            }
        }

        $total_menu_items = $top_lvl_menu_items_count;

        $item_position = $item->menu_order;

        $position_to_have_the_logo = ceil($total_menu_items / 2);

        if ($item_position == $position_to_have_the_logo && $item->menu_item_parent == "0") { //make sure we output for top level only
            $output .= "</li>\n<img src='PATH_TO_YOUR_LOGO' alt='' />"; //here we add the logo
        } else {
            $output .= "</li>\n";
        }
    }
}

i am assuming that if its a menu with an uneven number of item say 5 the logo will be after the third element, also that this is only for top elements only.

you have to use it like this in the menu location:

<?php
    wp_nav_menu(array(
            'theme_location' => 'footer',
            "walker" => new logo_in_middle_Menu_Walker('footer'),
    ));
?>

you have to supply the name of the theme location.

Here with 4 items:

enter image description here

Here with 5:

enter image description here

Другие советы

Modified David Lees nav walker class as for some reason it wouldn't quite work for me with submenu links. Unverified, but believe this was due to the menu items not having tidy/sequential menu_order values.

<?php 

class logo_in_middle_Menu_Walker extends Walker_Nav_Menu {

    public $menu_location = 'primary';

    function __construct($menu_location_var) {
        $this->menu_location = $menu_location_var;
    }

    public function end_el(&$output, $item, $depth = 0, $args = array()) 
    {
        $locations = get_nav_menu_locations();
        $menu = wp_get_nav_menu_object($locations[$this->menu_location]);
        $menu_items = wp_get_nav_menu_items($menu->term_id);

        $top_level_items = [];
        foreach ( $menu_items as $menu_item ) {
            if ( $menu_item->menu_item_parent == 0 ) {
                $top_level_items[] = $menu_item;
            }
        }

        $logo_position = ceil(count($top_level_items) / 2);

        if ( $item->menu_item_parent == 0 ) {
            $current_position = 0;
            foreach ( $top_level_items as $index => $top_level_item ) {
                if ( $top_level_item->ID == $item->ID ) {
                    $current_position = $index + 1;
                }
            }
    
            if ( $current_position == $logo_position ) {
                $output .= '</li>' . "\n";
                $output .= '<li class="logo">' . "\n";
                    $output .= '<img src="PATH_TO_YOUR_LOGO" alt="LOGO ALT" />' . "\n";
            }
        }
        
        $output .= "</li>\n";
    }
}

The best way to achieve the desired functionality, is to add a new menu item for the logo, by going to the Appearance > Menus, and set the class of the menu item to logo.

To enable custom CSS class in the menu, click the Screen Options then check the CSS Classes checkbox.

Let's assume you have a predetermined number of li items of 5.

<ul>
  <li class="logo">LOGO</li>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 4</li>
  <li>Item 5</li>
</ul>

Then set the main ul element css display attribute to flex:

ul {
  display: flex
}

And the li order number as follows:

ul li { order: 4; } 
ul li:nth-of-type(2) { order: 1; } /* For Item 1 */
ul li:nth-of-type(3) { order: 2; } /* For Item 2 */

Then for the logo class:

ul li.logo {
  order: 3;
}

You can learn for about the order property of the Flexible Box Layout

Лицензировано под: CC-BY-SA с атрибуция
Не связан с wordpress.stackexchange
scroll top