2

I researched in google, yandex but had no success.

With this code I can set a div to sub-menu but this code add to all sub-menus, I just need to add div to specific sub-menu.

class Megratron_div extends Walker_Nav_Menu
{
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<div id='megatron'><ul class='sub-menu'>\n";
    }
    function end_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat("\t", $depth);
        $output .= "$indent</ul></div>\n";
    }
}

¿How can I do that?

I really appreciate your support.

0

The WordPress native Walker class doesn't pass the arguments you need to the start_lvl() method. So to do this, you will need to add a custom display_element() method to your custom walker. You can use most of the original, with something similar to the commented section below:

public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
    if ( ! $element ) {
        return;
    }

    $id_field = $this->db_fields['id'];
    $id       = $element->$id_field;

    //display this element
    $this->has_children = ! empty( $children_elements[ $id ] );
    if ( isset( $args[0] ) && is_array( $args[0] ) ) {
        $args[0]['has_children'] = $this->has_children; // Backwards compatibility.
    }

    $cb_args = array_merge( array( &$output, $element, $depth ), $args );
    call_user_func_array( array( $this, 'start_el' ), $cb_args );

    // descend only when the depth is right and there are childrens for this element
    if ( ( $max_depth == 0 || $max_depth > $depth + 1 ) && isset( $children_elements[ $id ] ) ) {

        foreach ( $children_elements[ $id ] as $child ) {

            if ( ! isset( $newlevel ) ) {
                $newlevel = true;
                //start the child delimiter
                $cb_args = array_merge( array( &$output, $depth ), $args );

                /** Additional check for custom addition of id to sub-level */
                if ( $element->post_name = 'Megatron' ) {
                    $cb_args['sub_menu_id'] = 'megatron';
                }
                /** End custom check */

                call_user_func_array( array( $this, 'start_lvl' ), $cb_args );
            }
            $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
        }
        unset( $children_elements[ $id ] );
    }

    if ( isset( $newlevel ) && $newlevel ) {
        //end the child delimiter
        $cb_args = array_merge( array( &$output, $depth ), $args );
        call_user_func_array( array( $this, 'end_lvl' ), $cb_args );
    }

    //end this element
    $cb_args = array_merge( array( &$output, $element, $depth ), $args );
    call_user_func_array( array( $this, 'end_el' ), $cb_args );
}

The added code here checks for your main element name and then appends id information to the args that will be sent to start_lvl().

Now you can output the correct markup in your start_lvl() method with something like:

public function start_lvl( &$output, $depth = 0, $args = array(), $sub_menu_div = null ) {
    $indent = str_repeat("\t", $depth);
    if ( $sub_menu_div ) {
        $output .= "\n$indent<div id=\"$sub_menu_div\"><ul class=\"sub-menu\">\n";
    } else {
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }
}

Hope that helps. Good luck!

  • First I thank you for the support, I get error when I paste the code public function start_lvl also with the code public function display_element, the error is Parse error: syntax error, unexpected 'public' (T_PUBLIC). Thanks. – user3185638 Apr 14 '16 at 16:05
  • This usually indicates a missing ; somewhere or you have dropped a closing bracket. I can't debug for you. – Caspar Apr 14 '16 at 18:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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