メニュー

🏷️wp_nav_menuのHTML出力カスタマイズ方法

複雑な出力はWalker_Nav_Menuを使おう。

<?php

class HogeHoge_Nav_Menu extends Walker_Nav_Menu {
  // ここにコードを記述
}
wp_nav_menu([
  'theme_location' => 'hogemenu',
  'container' => false,
  'menu_class' => 'hoge-menu',
  'before' => '<p>',
  'after' => '</p>',
  'items_wrap' => '<ul class="%2$s">%3$s</ul>',
  'walker' => new HogeHoge_Nav_Menu()
]); 

start_lvl

全体をラップするulではなくliの中に入るulを指定する。
menu_classを入れ忘れないよう注意する。

public function start_lvl( &$output, $depth = 0, $args = [] ) {
  $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' );
  $dom = ( $depth === 0 ? '<ul class="hoge-sub-menu">' : '<ul>' );
  $output .= "\n" . $dom;
}

start_el

親のliと子のliのクラス名を変えてみた。ライブラリを使ったメガメニューの実装があるときに役に立ちそう。

public function start_el( &$output, $item, $depth = 0, $args = [], $id = 0 ) {
  $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' );
  $classes = empty( $item->classes ) ? [] : (array) $item->classes;
  $class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );
  $dom = ( $depth === 0 ? '<li id="menu-item-'. $item->ID . '" class="parent-li ' .  $class_names . '">' : '<li id="menu-item-'. $item->ID . '" class="child-li ' .  $class_names . '">' );

  $attributes  = !empty( $item->attr_title ) ? ' title="' . esc_attr( $item->attr_title ) .'"' : '';
  $attributes .= !empty( $item->target ) ? ' target="' . esc_attr( $item->target ) . '"' : '';
  $attributes .= !empty( $item->xfn ) ? ' rel="' . esc_attr( $item->xfn ) .'"' : '';
  $attributes .= !empty( $item->url ) ? ' href="' . esc_url( $item->url ) . '"' : '';

  $item_output = sprintf( '%1$s<a%2$s>%3$s%4$s%5$s</a>%6$s',
  $args->before,
  $attributes,
  $args->link_before,
  apply_filters( 'the_title', $item->title, $item->ID ),
  $args->link_after,
  $args->after
);
  $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}

親のliはbefore、afterが反映されるようにしたいけれども、子のは除外したい場合には、以下のように作る。

$item_output = sprintf( '%1$s<a%2$s>%3$s%4$s%5$s</a>%6$s',
  ( $depth === 0 ? $args->before : '' ),
  $attributes,
  $args->link_before,
  apply_filters( 'the_title', $item->title, $item->ID ),
  $args->link_after,
  ( $depth === 0 ? $args->after : '' )
);