1

In my navigation, items which have children should only be clickable to open / close the sub-menu. Because of this I'm searching for a way to append this item as first item in sub-menu so the page is accessible.

Here is a short example:

# structure in backend # needed in frontend                  #
# -------------------- # ----------------------------------- #
# item 1               # item 1                              #
# item 2               # item 2 (opens / closes submenu)     #
# - subitem 1          # - item 2 copy (normal link to page) #
# - subitem 2          # - subitem 1                         #
# - subitem 3          # - subitem 2                         #
# item 3               # - subitem 3                         #
#                      # item 3                              #
# -------------------- # ----------------------------------- #

I've tried it in the following way, with a count var, I know if I'm in a sub-menu and when it is the first item. So with the $item->object_id I could get all values from the parent menu-item. But I don't know how to create a new menu-item in the class method:

class flexnav_walker extends Walker_Nav_Menu {

    static $count=0;

    public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

      $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

      $classes = empty( $item->classes ) ? array() : (array) $item->classes;
      $classes[] = 'menu-item-' . $item->ID;

      $args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );

      $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) );
      $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

      $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args, $depth );
      $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';

      $output .= $indent . '<li' . $id . $class_names .'>';

      $atts = array();
      $atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
      $atts['target'] = ! empty( $item->target )     ? $item->target     : '';
      $atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';

      $navActive = get_post_meta( $item->object_id, '_wecOverviewNavState', true );

      // remove link from pages with children
      if (in_array('menu-item-has-children', $classes, true)) {
          $atts['href'] = '#';
      }else{
          $atts['href'] = ! empty( $item->url ) ? $item->url : '';
      }

      $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );

      $attributes = '';
      foreach ( $atts as $attr => $value ) {
        if ( ! empty( $value ) ) {
          $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
          $attributes .= ' ' . $attr . '="' . $value . '"';
        }
      }

      if ($depth==0) self::$count=0;  // reset var when we are in first level

        if ($depth==1 && self::$count==1) {  // if we are in submenu and items count is 1...

            // create a link from the actual parent
            // $hasChildren = count(get_pages(array( 'child_of' => $item->object_id )));

        }

      $title = apply_filters( 'the_title', $item->title, $item->ID );
      $title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );

      $item_output = $args->before;
      $item_output .= '<a'. $attributes .'>';
      $item_output .= $args->link_before . $title . $args->link_after;
      $item_output .= '</a>';
      $item_output .= $args->after;

      $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );

      self::$count++;
    }

  }

Thanks for your help!

Your Answer

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

Browse other questions tagged or ask your own question.