wp_nav_menu()が出力するメニューの<li>にはやたらとクラスが設定されていて、検索するとこれに対応するための記事が幾つも発見できます。
対応法としては、nav_menu_css_classフィルターを使うのですが、この中に「カスタムクラス」なるものを退避して再設定するという記事があり、なぜかフィルターに渡された配列の先頭要素のみを退避しているものがありました。
要点だけ抜き出すと↓な感じ。
add_filter('nav_menu_css_class', function ($classes, $menu_item, $args, $depth) {
$save = (!empty($classes[0])) ? $classes[0] : null;
$classes = [];
if ($save) {
$classes[] = $save;
}
return $classes;
}, 10, 4);
なんで[0]だけ?
と思ってvar_dumpしてみたら、[0]が空でないのは、たしかにカスタムクラス使用時のみのようです。
// カスタムクラス設定なし
array(8) {
[1]=>
string(9) "menu-item"
[2]=>
string(24) "menu-item-type-post_type"
// カスタムクラス設定あり
array(9) {
[0]=>
string(12) "custom_class"
[1]=>
string(9) "menu-item"
[2]=>
string(24) "menu-item-type-post_type"
しかし、カスタムクラスに空白を含む値を入力してみると、空白で区切られた分だけ配列要素が増え、[0]だけではダメだということが分かってしまいます。
// あらら
array(11) {
[0]=>
string(13) "custom_class1"
[1]=>
string(13) "custom_class2"
[2]=>
string(13) "custom_class3"
[3]=>
string(9) "menu-item"
[4]=>
string(24) "menu-item-type-post_type"
たぶん参考にした記事の投稿時点では[0]だけで良かったのでしょうが、そもそもカスタムクラス機能が使われてなくて問題になってないのか、僕の検索技術ではたどり着けないのか、対処方法が...。
とにかく、カスタムクラスなんて僕は使いませんが、見てしまった以上は対応も見つけておかないと、ということで調べると、wp_setup_nav_menu_itemフィルターで受け取れる$menu_itemのclassesはカスタムクラスのみの状態で、nav_menu_css_classまでの間に加工されてしまう、と。
なので、少々強引ですが、wp_setup_nav_menu_itemで$menu_itemに退避して、nav_menu_css_classで戻してやれば良いのでは、という結論。
add_filter('wp_setup_nav_menu_item', function ($menu_item) {
// カスタムクラスを退避
if (!empty($menu_item->classes) && $menu_item->classes[0]) {
$menu_item->custom_classes = $menu_item->classes;
}
return $menu_item;
}
add_filter('nav_menu_css_class', function ($classes, $menu_item, $args, $depth) {
// IDくらいは残しておきたい
$classes = ['menu-item-' . $menu_item->ID];
// カレントか知りたいこともある
if ($menu_item->current) {
$classes[] = 'current-menu-item';
}
// 退避したカスタムクラスを再設定
if (isset($menu_item->custom_classes)) {
$classes = array_merge($classes, $menu_item->custom_classes);
}
return $classes;
}, 10, 4);
...気にしなければよかった。