Bootstrapに実装されている”Navbar”を使うと、モバイルにも対応したナビゲーションメニューを簡単に作ることが出来ます。
今回は、この”Navbar”をWordPressのカスタムメニューとして出力させる方法について、自身へのメモも兼ねて書き残しておきます。
なお、サブメニューは第一階層までの出力に対応しています。Bootstrapの標準仕様ではありますが、さらに深い階層も表示できる仕様への対応も検討しています。
実装コード
テーマ
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<div class="container">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<?php
/* メニュー項目を配列として取得 */
$menu_name = 'menu-1'; // 定義したメニュー名
$locations = get_nav_menu_locations();
$menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
$item = wp_get_nav_menu_items( $menu->term_id, array( 'order' => 'DESC' ) );
$submenu = false;
$dropdown_id = 0; // ドロップダウン制御用
$item_length = count($item);
for($i = 0; $i < $item_length; $i++){
// タイトルとURLを取得
$title = $item[$i]->title;
$link = $item[$i]->url;
// 親を持たない項目(サブメニューの項目ではない)場合
if ( !$item[$i]->menu_item_parent ){
// 後でサブメニューの項目と比較する為にIDを保存しておく
$parent_id = $item[$i]->ID;
?>
<?php
// 次に現れる項目が、サブメニューの項目であれば、このメニューリンクはトグルリンクにする
if($i < $item_length - 1 && $parent_id == $item[$i + 1]->menu_item_parent){
?>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="<?php echo $link; ?>" id="dropdown<?php echo $dropdown_id ?>" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><?php echo $title; ?></a>
<?php
} else {
?>
<li class="nav-item<?php if($item[$i]->object_id == get_queried_object_id()) echo ' active'; ?>">
<a class="nav-link" href="<?php echo $link; ?>"><?php echo $title; ?></a>
<?php
}
}
?>
<?php
// 参照中項目の親IDが、直前に保存しておいたIDと一致している場合
if ( $parent_id == $item[$i]->menu_item_parent ){
// サブメニューの項目の出力を開始する
if ( !$submenu ){
$submenu = true;
?>
<div class="dropdown-menu" aria-labelledby="dropdown<?php echo $dropdown_id ?>">
<?php
}
//サブメニューを書く
?>
<a class="dropdown-item" href="<?php echo $link; ?>"><?php echo $title; ?></a>
<?php
// 次の項目が同じ親IDを持たず、サブメニューが宣言状態である場合は、サブメニューを閉じる
if ($i < $item_length - 1 && $item[$i + 1]->menu_item_parent != $parent_id && $submenu ){
?>
</div>
<?php
$submenu = false;
$dropdown_id++;
}
}
// 次の項目が同じ親IDを持たない場合は、<li>を閉じます
if ($i < $item_length - 1 && $item[$i + 1]->menu_item_parent != $parent_id ){
?>
</li>
<?php
} else if ($i == $item_length - 1){
?>
</li>
<?php
}
} //END of loop
?>
</ul>
</div>
</div>
</nav>
functions.php
// メニューに標準で出力されるIDを削除する
function removeId( $id ){
return $id = array();
}
add_filter('nav_menu_item_id', 'removeId', 10);
// メニューのaタグにbootstrapのクラスを追加
function add_class_on_link($item_output, $item){
return preg_replace('/(<a.*?)/', '$1' . " class='nav-link'", $item_output);
}
add_filter('walker_nav_menu_start_el', 'add_class_on_link', 10, 4);
// カレントページでは該当するメニューにclassを追加
function remove_to_currentClass( $classes, $item ) {
$classes = array();
$classes[] = 'nav-item';
if( $item -> current == true ) {
$classes[] = 'active';
}
return $classes;
}
add_filter( 'nav_menu_css_class', 'remove_to_currentClass', 10, 2 );
参考文献
php – ワードプレスのwp_get_nav_menu_itemsを使ってカスタムメニューサブメニューシステムを生成するにはどうすればいいですか? – コードログ