WordPressのメニューを表示する際、wp_nav_menuメソッドを使って表示することがあると思います。
その際の例
wp_nav_menu( array( 'menu' => 'GlobalMenu', 'menu_id' => 'global_navi', 'container_class' => 'global_navigation' ) );
wp_nav_menu
ではidやクラス等、ある程度はパラメータを与えることでカスタマイズ出来るようになっています。
しかし、例えばメニューアイテムの最後に任意のアイテムを追加で表示させたいなど、柔軟なカスタマイズをすることが出来ません。
そんな柔軟なカスタマイズを行いたいときの手法をご紹介します。
順に解説していきますが、実際には一連の処理をfunctions.php
にカスタムメソッドとして作成し、メニューを表示したい任意の箇所で実行してください。
解説
メニュー名を指定し、wp_get_nav_menu_object
メソッドでメニュー情報を取得します。
※メニュー名は[外観]->[メニュー]->[メニュー構造]で設定しているメニュー名を指定してください。
// メニュー名
$menu_name = 'GlobalMenu';
// メニュー情報取得
$menu = wp_get_nav_menu_object($menu_name);
取得したメニュー情報を基にメニューアイテムを取得します。
// メニューアイテム取得
$menu_items = wp_get_nav_menu_items($menu->term_id);
取得したメニューアイテムの情報にCSSクラスの情報がありますが、この段階では[外観]->[メニュー]->[メニュー構造]の各項目で設定したCSS class(オプション)で指定したクラスしか設定されていません。
wp_nav_menu
でメニューを表示したときはWordPressが自動的に設定してくれているクラスが含まれています。
そのクラスも含めて設定して欲しいときは_wp_menu_item_classes_by_context
メソッドを実行し、本来wp_nav_menu
でなら適用されるクラスを反映させます。
但し、このメソッドは公式ガイドにはプライベートだと書かれておりテーマ開発者の実行を想定していないそうなので、今後使えなくなったりする可能性はあります。
// 自動で割り当てられるWP独自クラスを反映させる
_wp_menu_item_classes_by_context($menu_items);
続いてdiv
等でラッピングしつつ、リストを作成していきます。
echo '<div class="global_navigation">';
echo '<ul id="global_navi" class="menu">';
又、先ほど実行した_wp_menu_item_classes_by_context
だけではmenu-item-メニューID
クラスが追加されていないので、こちらは手動で追加します。
// クラス用配列
$current_classes = [];
ループでメニューアイテムを取り出していきます。
foreach ( (array) $menu_items as $key => $menu_item ) {
// クラス用配列にmenu-item-メニューIDを追加
$current_classes = array_merge($menu_item->classes, ['menu-item-'.$menu_item->ID]);
echo '<li class="' . implode(' ', $current_classes) . '">';
echo '<a href="' . $menu_item->url . '"' . (($menu_item->current) ? ' aria-current="page"' : '') . '>' . $menu_item->title . '</a>';
echo '</li>';
}
ループでメニューアイテムの取り出しが一通り終わったところで、追加アイテムを書き出します。
echo '<li>追加メニューアイテム</li>';
最後にHTMLタグを閉じます。
echo '</ul>';
echo '</div>';
以上でカスタマイズしたメニューを表示することが出来ます。
wp_get_nav_menu_object() – Function | Developer.WordPress.org
_wp_menu_item_classes_by_context() – Function | Developer.WordPress.org