Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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/

share|improve this question
    
"Constructive Criticism on the code?". Well stated. ;) –  Pieter Goosen May 19 at 10:10
    
@PieterGoosen Thanks :) Even I cringe at the code, god knows what most people seeing it are thinking! –  Mallander May 19 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 –  MortalViews May 19 at 11:47
    
@MortalViews Question Edited to include FULL Custom Walker Code, and HTML wp_nav_menu call. –  Mallander May 19 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 –  MortalViews May 19 at 12:00

1 Answer 1

up vote 1 down vote accepted

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();
}
share|improve this answer
    
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 at 13:20
    
i didn't get you. you don't need another top-level Walker. –  MortalViews May 19 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 –  MortalViews May 19 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 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> –  MortalViews May 19 at 13:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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