Skip to content

Instantly share code, notes, and snippets.

@hitautodestruct
Forked from anonymous/gist:4344870
Last active September 26, 2022 11:25
Show Gist options
  • Select an option

  • Save hitautodestruct/4345363 to your computer and use it in GitHub Desktop.

Select an option

Save hitautodestruct/4345363 to your computer and use it in GitHub Desktop.
Generate a custom structure for Wordpress menus.

This gist is for showing an example of a custom wordpress menu.

If you want to get more from the menu item simply have a look at the $item object. i.e:

// Will return a large object with lots of props like title, url, description, id etc.
var_dump( $item );

This code works on Wordpress 4.1.1 as of 31st of March 2015

<?php
$menu_name = 'main_nav';
$locations = get_nav_menu_locations();
$menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
$menuitems = wp_get_nav_menu_items( $menu->term_id, array( 'order' => 'DESC' ) );
?>
<nav>
<ul class="main-nav">
<?php
$count = 0;
$submenu = false;
foreach( $menuitems as $item ):
$link = $item->url;
$title = $item->title;
// item does not have a parent so menu_item_parent equals 0 (false)
if ( !$item->menu_item_parent ):
// save this id for later comparison with sub-menu items
$parent_id = $item->ID;
?>
<li class="item">
<a href="<?php echo $link; ?>" class="title">
<?php echo $title; ?>
</a>
<?php endif; ?>
<?php if ( $parent_id == $item->menu_item_parent ): ?>
<?php if ( !$submenu ): $submenu = true; ?>
<ul class="sub-menu">
<?php endif; ?>
<li class="item">
<a href="<?php echo $link; ?>" class="title"><?php echo $title; ?></a>
</li>
<?php if ( $menuitems[ $count + 1 ]->menu_item_parent != $parent_id && $submenu ): ?>
</ul>
<?php $submenu = false; endif; ?>
<?php endif; ?>
<?php if ( $menuitems[ $count + 1 ]->menu_item_parent != $parent_id ): ?>
</li>
<?php $submenu = false; endif; ?>
<?php $count++; endforeach; ?>
</ul>
</nav>
@mehmetsarr
Copy link
Copy Markdown

mehmetsarr commented Oct 13, 2021

Hi, has anyone found a solution for the third level menu? The third level menu does not appear on my website.
In addition, the name of the main menu appears in the submenus. I have shared the sample picture.

menu

@josh-tt
Copy link
Copy Markdown

josh-tt commented Oct 22, 2021

That code just doesn't work properly, I ended up just adding the menu items into a PHP array so I could output easily.

Add the following into your functions.php then call in your theme passing the menu of choice.

function wp_get_menu_array($current_menu) {
    $array_menu = wp_get_nav_menu_items($current_menu);
    $menu = array();
    foreach ($array_menu as $m) {
        if (empty($m->menu_item_parent)) {
            $menu[$m->ID] = array();
            $menu[$m->ID]['ID']          =   $m->ID;
            $menu[$m->ID]['title']       =   $m->title;
            $menu[$m->ID]['url']         =   $m->url;
            $menu[$m->ID]['children']    =   array();
        }
    }
    $submenu = array();
    foreach ($array_menu as $m) {
        if ($m->menu_item_parent) {
            $submenu[$m->ID] = array();
            $submenu[$m->ID]['ID']       =   $m->ID;
            $submenu[$m->ID]['title']    =   $m->title;
            $submenu[$m->ID]['url']      =   $m->url;
            $menu[$m->menu_item_parent]['children'][$m->ID] = $submenu[$m->ID];
        }
    }
    return $menu;
}

Then call in your theme $menu_items = wp_get_menu_array('main-menu');

  <nav>
      <ul>
        <?php foreach ($menu_items as $item) : ?>
          <li>
            <a href="<?= $item['url'] ?>" title="<?= $item['title'] ?>"><?= $item['title'] ?></a>
            <?php if( !empty($item['children']) ):?>
            <ul class="sub-menu">
              <?php foreach($item['children'] as $child): ?>
                <li class="b-main-header__sub-menu__nav-item">
                  <a href="<?= $child['url'] ?>" title="<?= $child['title'] ?>"><?= $child['title'] ?></a>
                </li>
              <?php endforeach; ?>
            </ul>
            <?php endif; ?>
          </li>
        <?php endforeach; ?>
     <ul>
</nav>

This works nicely, thanks. Any tips on how to approach getting the current menu item styled?

@mehmetsarr
Copy link
Copy Markdown

Bu kod düzgün çalışmıyor, kolayca çıktı alabilmek için menü öğelerini bir PHP dizisine ekledim.

Aşağıdakileri function.php dosyanıza ekleyin ve ardından seçtiğiniz menüden temanızı çağırın.

function wp_get_menu_array($current_menu) {
    $array_menu = wp_get_nav_menu_items($current_menu);
    $menu = array();
    foreach ($array_menu as $m) {
        if (empty($m->menu_item_parent)) {
            $menu[$m->ID] = array();
            $menu[$m->ID]['ID']          =   $m->ID;
            $menu[$m->ID]['title']       =   $m->title;
            $menu[$m->ID]['url']         =   $m->url;
            $menu[$m->ID]['children']    =   array();
        }
    }
    $submenu = array();
    foreach ($array_menu as $m) {
        if ($m->menu_item_parent) {
            $submenu[$m->ID] = array();
            $submenu[$m->ID]['ID']       =   $m->ID;
            $submenu[$m->ID]['title']    =   $m->title;
            $submenu[$m->ID]['url']      =   $m->url;
            $menu[$m->menu_item_parent]['children'][$m->ID] = $submenu[$m->ID];
        }
    }
    return $menu;
}

Ardından temanızı arayın $menu_items = wp_get_menu_array('main-menu');

  <nav>
      <ul>
        <?php foreach ($menu_items as $item) : ?>
          <li>
            <a href="<?= $item['url'] ?>" title="<?= $item['title'] ?>"><?= $item['title'] ?></a>
            <?php if( !empty($item['children']) ):?>
            <ul class="sub-menu">
              <?php foreach($item['children'] as $child): ?>
                <li class="b-main-header__sub-menu__nav-item">
                  <a href="<?= $child['url'] ?>" title="<?= $child['title'] ?>"><?= $child['title'] ?></a>
                </li>
              <?php endforeach; ?>
            </ul>
            <?php endif; ?>
          </li>
        <?php endforeach; ?>
     <ul>
</nav>

This code works fine but when I add 3rd level menu it gives the following warning. How can I fix this?

NOTICE: UNDEFINED INDEX: TITLE IN /HOME/ZIRKON/PUBLIC_HTML/DEMO/CLEANMAX/WP-CONTENT/THEMES/CLEANMAX-MAIN/HEADER.PHP ON LINE 70

@OmarHossamEldin
Copy link
Copy Markdown

<nav class='navbar navbar-expand-lg navbar-dark bg-dark'>
            <div class="container-fluid">
                <a class="navbar-brand" href="<?= home_url() ?>"><?= bloginfo() ?></a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                        <li class="nav-item">
                            <a class="nav-link active" aria-current="page" href="<?= home_url() ?>">Home</a>
                        </li>
                        <?php foreach (get_pages() as $page) : ?>
                            <li class="nav-item">
                                <a class="nav-link active" aria-current="page" href="<?= home_url() . '/' . $page->post_name ?>"><?= $page->post_title ?></a>
                            </li>
                        <?php endforeach; ?>
                    </ul>
                </div>
            </div>
        </nav>

@OmarHossamEldin
Copy link
Copy Markdown

<nav class='navbar navbar-expand-lg navbar-dark bg-dark'>
            <div class="container-fluid">
                <a class="navbar-brand" href="<?= home_url() ?>"><?= bloginfo() ?></a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                        <li class="nav-item">
                            <a class="nav-link active" aria-current="page" href="<?= home_url() ?>">Home</a>
                        </li>
                        <?php foreach (get_pages() as $page) : ?>
                            <li class="nav-item">
                                <a class="nav-link active" aria-current="page" href="<?= home_url() . '/' . $page->post_name ?>"><?= $page->post_title ?></a>
                            </li>
                        <?php endforeach; ?>
                    </ul>
                </div>
            </div>
        </nav>

better code readability

@mehmetsarr
Copy link
Copy Markdown

<?= $page->post_title ?>

this is not happening. main code becomes but dropdown icon disappears

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment