1

I've got my Custom Nav Walker set up and it works fine with the main menu items, and displays them how I want.

However the same HTML is being applied to the sub-menu elements which isn't what I want.

I'm aiming to get the sub-menu to have the following styling:

<ul>
    <li>
        <h2 class="dropdown-text">Blog 1</h2>
    </li>
    <li>
        <h2 class="dropdown-text">Blog 2</h2>
    </li>
    <li>
        <h2 class="dropdown-text">Blog 3</h2>
    </li>
    <li>
        <h2 class="dropdown-text">Blog 4</h2>
    </li>
</ul>

Here is the HTML Structure for the full navigation

<div class="postit-surround">
<a href="#">
    <div class="postit">
        <div class="pin">
            <img src="<?php echo get_template_directory_uri(); ?>/assets/drawing-pin.png">
        </div>
        <div class="postit-title">
            <h1 class="nav-title-text">Products</h1>
        </div>
        <div class="corner-peel">
            <img src="<?php echo get_template_directory_uri(); ?>/assets/corner-flick-cyan.png">
        </div>
    </div>
</a>
<div class="navigation-dropdown">
    <ul>
        <li>
            <h2 class="dropdown-text">Products 1</h2>
        </li>
        <li>
            <h2 class="dropdown-text">Products 2</h2>
        </li>
        <li>
            <h2 class="dropdown-text">Products 3</h2>
        </li>
        <li>
            <h2 class="dropdown-text">Products 4</h2>
        </li>
        <li>
            <h2 class="dropdown-text">Products 5</h2>
        </li>
    </ul>
</div>
</div>

Here is the HTML call for the wp_nav_menu:

<div class="navigation-container">
<?php 

$walker = new my_nav_walker;
wp_nav_menu( array( 'theme_location' => 'header-menu', 'menu' => 'ul', 'menu_class' => 'navigation', 'menu_id' => '', 'walker' => $walker ) ); 


?>
</div>

Here is the construct for my Custom Walker HTML: (NOTE: I'm really new to this, so this is going to be messy...)

class my_nav_walker extends Walker {
       function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

            $direct = get_template_directory_uri();

            $item_output = $args->before;
            $item_output .= '<div class="postit-surround">';
            $item_output .= '<a'. $attributes .'>';
            /** This filter is documented in wp-includes/post-template.php */

            $item_output .= '<div class="postit">
                                    <div class="pin">';
            $item_output .= '<img src="' . $direct . '/assets/drawing-pin.png">
                                    </div>
                                    <div class="postit-title">
                                            <h1 class="nav-title-text">';
            $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;

            $item_output .= '</h1>
                            </div>
                                    <div class="corner-peel">
                                            <img src="' . $direct . '/assets/corner-flick-green.png">
                                    </div>
                            </div>';
            $item_output .= '</a>';
            $item_output .= '</div>';
            $item_output .= $args->after;

        }    

} // Walker_Nav_Menu

Here's the CSS if needed:

PasteBin Link

I'm not sure if I'm doing the construct right to get the separate styling that I want.

What would you advise?

Are there any alternatives?

Constructive Criticism on the code? (Don't be too harsh! :P)

EDIT -----:

I've done some more research into understanding the php code, and I now realise where the defining of the start and end of the sub-menu starts (With start_lvl and end_lvl), but I still don't understand how to separate what code goes to the Parent navigation panes, and which goes to their respective sub-menus.

This is what I'm after with the display of the naviagtion: http://jsfiddle.net/TPD5L/

15
  • "Constructive Criticism on the code?". Well stated. ;) May 19, 2014 at 10:10
  • @PieterGoosen Thanks :) Even I cringe at the code, god knows what most people seeing it are thinking!
    – Mallander
    May 19, 2014 at 10:13
  • 1
    which method are you overridding? and i don't think you need to have a custom walker, you can get it done using wp_nav_menu function with proper arguments, plz post the full code including the method names of your custom walker May 19, 2014 at 11:47
  • @MortalViews Question Edited to include FULL Custom Walker Code, and HTML wp_nav_menu call.
    – Mallander
    May 19, 2014 at 11:55
  • 1
    Hi, when you are extending the parent class, you don't need to include any method that you are not overriding. check: the general example codex.wordpress.org/Class_Reference/Walker May 19, 2014 at 12:00

1 Answer 1

2

Solution: Copy paste the below code into your function. and then in template use

my_nav_menu($menu_location);

//put this in your functions

class MY_Menu_Walker_Ext extends Walker {

    var $tree_type = array('post_type', 'taxonomy', 'custom');
    var $db_fields = array('parent' => 'menu_item_parent', 'id' => 'db_id');

    function start_el(&$output, $object, $depth = 0, $args = array(), $current_object_id = 0) {
        $output .="<li><h2 class='dropdown-text'>{$object->title}</h2>";
    }

    function end_el(&$output, $object, $depth = 0, $args = array()) {
        $output.='</li>';
    }

}

class my_custom_menu {

    public $menu;
    public $menuItems;
    public $parents;
    public $walker;

    public function __construct($menu_location) {
        $this->setMenu($menu_location);
        $this->getMenuItems();
        $this->getParents();

        $this->walker = new MY_Menu_Walker_Ext();
    }

    public function drawMenu() {

    }

    public function setMenu($menu_location) {

        $this->menu = $this->getMenuByLocation($menu_location);
    }

    protected function getMenuByLocation($menu_location) {
        $locations = get_nav_menu_locations();

        $menu = null;
        if ($locations && isset($locations[$menu_location])) {
            $menu = wp_get_nav_menu_object($locations[$menu_location]);
        }

        return $menu;
    }

    public function get() {

    }

    public function getMenuItems() {
        if ($this->menuItems)
            return $this->menuItems;
        $this->menuItems = wp_get_nav_menu_items($this->menu);

        return $this->menuItems;
    }

    public function getParents() {
        if ($this->parents)
            return $this->parents;
        $parents = array();

        foreach ($this->menuItems as $item) {
            if ($item->menu_item_parent == 0) {
                array_push($parents, $item);
            }
        }

        $this->parents = $parents;
        return $this->parents;
    }

    public function getChild($parent_id) {

        $childs = array();


        foreach ($this->menuItems as $item) {
            if ($parent_id == $item->menu_item_parent) {
                $item->menu_item_parent = 0;

                array_push($childs, $item);
                foreach ($this->menuItems as $item1) {
                    if ($item->ID == $item1->menu_item_parent) {
                        array_push($childs, $item1);
                    }
                }
            }
        }



        return $childs;
    }

    public function draw() {
        echo "<div class='postit-surround'>";

        foreach ($this->parents as $item) {
            $this->displayParentHTML($item->title);
            $this->drawChildren($this->getChild($item->ID));
        }
        echo "</div>";
    }

    public function displayParentHTML($title) {
        ?>
        <a href="#">
            <div class="postit">
                <div class="pin">
                    <img src="<?php echo get_template_directory_uri(); ?>/assets/drawing-pin.png">
                </div>
                <div class="postit-title">
                    <h1 class="nav-title-text"><?php echo $title ?></h1>
                </div>
                <div class="corner-peel">
                    <img src="<?php echo get_template_directory_uri(); ?>/assets/corner-flick-cyan.png">
                </div>
            </div>
        </a>


        <?php
    }

    public function drawChildren($children) {
        $defaults = array('menu' => '', 'container' => 'div', 'container_class' => '', 'container_id' => '', 'menu_class' => 'menu', 'menu_id' => '',
            'echo' => true, 'fallback_cb' => 'wp_page_menu', 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => '', 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
            'depth' => 0, 'walker' => '', 'theme_location' => '');
        $args = array(
            'theme_location' => 'header-menu',
            'container' => 'div',
            'container_class' => 'navigation-dropdown',
            'items_wrap' => '<ul >%3$s</ul>',
            'depth' => 0,
        );
        $args = wp_parse_args($args, $defaults);

        echo "<div class='navigation-dropdown'><ul>";
        echo $this->walker->walk($children, 2, $args);
        echo "</ul></div>";
    }

}

function my_nav_menu($name = null) {
    $myMenu = new my_custom_menu($name);
    $myMenu->draw();
}
8
  • Thanks, that works fine on it's own, however i'm struggling to see how to integrate that with my top-level Walker to get the overall structure stated in the question?
    – Mallander
    May 19, 2014 at 13:20
  • i didn't get you. you don't need another top-level Walker. May 19, 2014 at 13:22
  • replace your my_nav_walker class with this one. and in the template where you want to display the nave menu. copy paste the code in the second section. note: the output will include the container div also May 19, 2014 at 13:23
  • I'm not sure you're understanding what I'm after with the navigation (I've been really unclear in my question, sorry for that) See this fiddle: jsfiddle.net/TPD5L
    – Mallander
    May 19, 2014 at 13:25
  • okay, the html for the 'postit' part should be includeed in the template. <post it div>< the post it code></> Here call the nav menu </div> May 19, 2014 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.