WordPresのwp_nav_menuのwalkerパラメータを設定してクラスを継承してオーバーライドする
こんにちは、今回はグローバルメニューのwp_nav_menuのパラメータの一つ、
walkerパラメータを設定することで、グローバルメニューを自由にカスタマイズすることをしてみたいと思います。
そもそもwp_nav_menuを設置する前準備をする
// ナビメニューの登録
function register_my_menus() {
register_nav_menus( array(
//'「メニューの位置」の識別子' => 'メニューの説明の文字列',
'header-menu' => 'Header Menu',
'footer-menu' => 'Footer Menu',
'sidebar-menu' => 'Sidebar Menu',
) );
}
add_action( 'after_setup_theme', 'register_my_menus' );
上記のコードをfunctions.phpに記述します。
register_nav_menusは複数のナビメニューを配列で登録します。
「メニューの位置の識別子」はナビメニューのIDになります。
「’メニューの説明の文字列’」は管理画面上に表示される項目になります。
次に表示する場所に以下のコードを追加します。
wp_nav_menuでメニューを表示する
<?php if ( has_nav_menu( 'header-menu' ) ) : ?>
<?php wp_nav_menu(
array(
'menu' => 'ojako_main_menu',
'theme_location' => 'header-menu',
'container' => 'nav',
'container_id' => 'main_nav',
'menu_class' => 'pc_only',
'walker' => new custom_walker_nav_menu
)
); ?>
<?php endif; ?>
まず大事なのが‘theme_location’ =>ここの値は上で設定したIDになる
ということです。
他のパラメータはナビメニューを他のタグでラップするか?またはそのクラスを指定したり、リンクの前後に文字列を入れたりすることも可能です。
さぁここからやや難しいですが、パラメータの中にある
‘walker’ => new custom_walker_nav_menu
こちらのパラメータでクラスのインスタンスを生成してWordPressが用意したナビメニューの雛形を一時的に上書きすることが可能です。
具体的なコードを一気に見ていきます
ナビメニューのHTMLと階層構造の登録
理解できた部分を丁寧に順番に解説していきます。
class custom_walker_nav_menu extends Walker_Nav_Menu
最初の冒頭でWordPressのクラスを継承します
extendsキーワードが継承するという意味です。
custom_walker_nav_menuの部分は何でもいいです
ここの名前は先にwp_nav_menu()で引数に指定していたwalkerパラメータの引数として
newをつけてインスタンス化する際の名前と同じになるようにします。
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
続いてこちらの部分は三項演算にしてありますが
$depthにはメニュー項目の深さ。 としての値が格納されています。
その値が存在した場合str_repeat(繰り返す文字列 , 回数)での関数で“\t”(タブ)を繰り返し変数にします。
$depthが存在しない場合は空文字列を代入しています。
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
$class_names = ' class="' . esc_attr( $class_names ) . '"';
$output .= $indent . '<li id="menu-item-' . $item->ID . '"' . $value . $class_names . '>';
ここからはHTMLの<li>タグを出力する部分の解説です。
$class_names = $value = ”; まずは空の配列を用意します。
$itemはWP_POSTのメニューの様々な値を格納するオブジェクトで、ここから様々な情報を取得して自身でナビメニューを構築することも出来るようです。
$item->classesとすることでそれに付与されるべきクラスの値を取得して
$class_namesへ連結する関数join()で文字列として並べているようです
そして$output 変数に代入してやることでこちらの変数から実際にHTMLのタグとして生成するというわけです
$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 ) . '"' : '';
ここからは<a>タグの属性値を設定するところです
$attributes変数に先程から登場した$itemの値をドットでつないで連結していきます。
ちなみに$item->xfnはリンクの親子関係を示す値のようです。
さてここからはオリジナルの部分になります
$prepend = '<strong class="gMenu_name">';
$append = '</strong>';
$description = ! empty( $item->description ) ? '<div class="active_headwrap"><span class="gMenu_description">' . esc_attr( $item->description ) . '</span></div>' : '';
$prepend $append 変数を用意してオリジナルのタグでリンクを囲う様に準備します
$description変数は管理画面のリンクの説明の項目を出したいので
$item->descriptionで取得することが出来ます
毎度おなじみ三項演算でこれを存在しているか判定後変数に代入します
次はいよいよ中身のタグの出力です
if ( $depth != 0 ) {
$description = $append = $prepend = '';
}
$item_output = $args->before;
$item_output .= '<a' . $attributes . '>';
$item_output .= $args->link_before . $prepend . apply_filters( 'the_title', $item->title, $item->ID ) . $append;
$item_output .= $description . $args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
最初の条件分岐はもし階層構造を持っていた場合に対象の変数をリセットしておきます
そのままでは文書構造的に変になってしまうためです
$argsは先のwp_nav_menuの引数のパラメータが渡ってきています
よってbefore,afterはそれぞれの前後に追加する文字列です
これらもそれぞれドットで連結していき<a>タグを作っていきます
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
最後にこちらの$output変数にアクションフックwalker_nav_menu_start_elに紐づけて追加代入します
この様にこのクラス変数の中の
start_elは主にメインとなる<li>タグを生成します
他の主要メソッドの関数も列挙すると、
- function start_lvl ()
- function end_lvl ()
- function start_el ()
- function end_el ()
の種類があり
start_lvl では <ul> を出力するが一般的です。
end_lvl では </ul> を出力するが一般的です。
end_elはタグの最後 </li>を出力するようです
ということで最後のブロックで
function start_lvl(&$output, $depth = 0, $args = array()) {
$output .= '<div class="header-nav-child"><ul class="sub-menu">';
}
function end_lvl(&$output, $depth = 0, $args = array()) {
$output .= '</ul></div>';
}
こちらの関数もこのクラスの中で書き換える事が可能です
これら2つの関数は階層構造があった場合にその<ul>タグを生成するのですが
ここはシンプルにタグをそのまま追加で代入してやることで
自分の好きなタグで生成することが可能です
メニューの表示を画像にする場合は?
最後にこちらも簡単に紹介しておきます
これの方法はとても簡単で手順は
- メニューに入れたい文字の画像を作成・アップロード
- 管理画面のメニューの設定から、各メニューのナビゲーションラベルというメニューの名前をいれるところにimgタグをそのまま書く
ということで簡単に表示できます
また当然ながらFont Awesomeのアイコンタグでも問題ありません
まあ背景ならCSSで簡単に出来ますしね
今回は長かったしやや難しい内容でしたね
では
コメントをお待ちしております