WordPress3.xでメニューをカスタマイズする(wp_nav_menu の出力を変更する方法)


WordPress3.xから作成できるようになったメニューのカスタマイズの覚え書きです。



とりあえず、基本は、
WordPressの管理画面の「外観」→「メニュー」でメニューを作成した後、テンプレート内のメニューを表示したい場所に、

<?php wp_nav_menu( array('menu' => 'xxx' )); ?>
と記述すれば、メニューは表示できます。(xxx は、作成したメニューの名前が入ります)
あとは、書き出されるソースを見ながら、style.cssにスタイルを設定していくというやり方になります。



しかし、標準で書き出されるIDやClass名又は、タグでは対応しきれなくなる場合がでてきたら、以下の方法で、書き出されるHTMLをカスタマイズしましょう。
※万が一の場合の為に、function.phpはバックアップしてた方が良いでしょう。


■カスタマイズの基本(下準備)
使用中のテーマの「functions.php」に、以下を追加記入します。追記箇所は、どこでもよいです。一番最後あたりに付け加えるとよいと思います。
(function.php は、管理画面では「テーマのための関数」と表記されます。管理画面の「テーマ」を編集するページにあります)

class My_Walker_Nav_Menu extends Walker_Nav_Menu {

//ここにカスタマイズを追加していきます。





//カスタマイズ記入箇所はここまで

}



add_filter( 'wp_nav_menu_args', 'my_nav_menu_args' );

function my_nav_menu_args( $args ) {

  $args = (object) $args;

  $args->walker = new My_Walker_Nav_Menu;

  return $args;

}

やっている意味は、WordPressの本来のメニュー表示機能を、自分でカスタマイズしたメニュー表示機能に置き換えますよということです。


■書き出される項目のうち、「a」タグをカスタマイズしたい場合
上記の「ここにカスタマイズを追加して行きます。」の次の行に、


function start_el(&$output, $item, $depth, $args) {

global $wp_query;

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



$class_names = $value = '';



$classes = empty( $item->classes ) ? array() : (array) $item->classes;

$classes[] = 'menu-item-' . $item->ID;



$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );

$class_names = ' class="' . esc_attr( $class_names ) . '"';



$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );

$id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';



$output .= $indent . '<li' . $id . $value . $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_attr( $item->url        ) .'"' : '';



$item_output = $args->before;



//以下をカスタマイズします。

$item_output .= '<a  '. $attributes .'>';

$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;

$item_output .= '</a>';

$item_output .= $args->after;



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

}
と記入します。

「//以下をカスタマイズします」の下の行の「<a」の後に、例えば、「id="xxx"」等と追加していきます。
ちなみに、


$item_output .= '<a id="mmenu' . $item->ID . " " . $attributes .'>';
こんな風にすれば、WordPressの「カテゴリID」を、CSSセレクタのID名に指定できたりするので、重複しないID名をつけたいときには便利です。


■サブメニューの「ul」タグをカスタマイズする場合。
下準備で追加した中の、「ここにカスタマイズを追加して行きます。」の次の行に、


function start_lvl(&$output,  $depth) {

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



//以下をカスタマイズします

$output .= "\n$indent<ul  class=\"sub-menu\">\n";

}
と記入します。

「//以下をカスタマイズします」の下の行の「<ul」の後に、例えば、「id="xxx"」等と追加していきます。
ここにも、カテゴリIDを使用したい場合は、もう少し記入する必要があるので、また別の機会にでも・・・。



PHPもろくに理解していない筆者が、手探りでやっつけ作業でカスタマイズしてみましたので、間違いや突っ込み等ありましたら、ご指摘ください。こういうカスタマイズが出来るプラグインはないのでしょうか・・・・


この方法で、javascriptと連携して、なんとかドロップダウンナビゲーションを実装までこぎ着けました。