はじめに
以下の質問に回答します。
「ナビゲーションメニュー」ウィジェットには、ドロップダウン表示機能がありません。
そこで、「タグクラウド」ウィジェットに「ドロップダウンで表示」メニューを追加します。
この記事では、この方法について説明します。
完成イメージ

実装手順
以下のコードをfunctions.phpに追加します。
// ウィジェットに設定メニューを追加
add_action('in_widget_form', function ($widget, $return, $instance) {
if ($widget->id_base !== 'nav_menu') {
return;
}
$dropdown = !empty($instance['dropdown']);
?>
<p>
<input type="checkbox" id="<?= $widget->get_field_id('dropdown'); ?>" class="widefat" name="<?= $widget->get_field_name('dropdown'); ?>" value="1" <?php checked($dropdown); ?>>
<label for="<?= $widget->get_field_id('dropdown'); ?>">ドロップダウン形式で表示</label>
</p>
<?php
}, 10, 3);
// ウィジェットの入力データを更新
add_filter('widget_update_callback', function ($instance, $new_instance) {
if (isset($new_instance['dropdown'])) {
$instance['dropdown'] = !empty($new_instance['dropdown']) ? 1 : 0;
}
return $instance;
}, 10, 2);
// フロントエンド表示に反映
add_filter('widget_display_callback', function ($instance) {
if (empty($instance['dropdown'])) {
return $instance;
}
$nav_menu = !empty($instance['nav_menu']) ? wp_get_nav_menu_object($instance['nav_menu']) : false;
if (!$nav_menu) {
return $instance;
}
$menu_items = wp_get_nav_menu_items($nav_menu->term_id);
if (!$menu_items) {
return $instance;
}
$current_url = trailingslashit(home_url(add_query_arg([], $_SERVER['REQUEST_URI'])));
// 現在の表示オブジェクトを取得
$current_object = get_queried_object();
/**
* ナビゲーションメニュー項目を再帰的に<option>タグとして出力
*
* @param array $items wp_get_nav_menu_items() で取得したメニュー項目の配列
* @param int $parent_id 親メニュー項目のID(デフォルト: 0)
* @param int $depth 現在の階層の深さ(インデント用、デフォルト: 0)
* @return void
*/
$render_options = function ($items, $parent_id = 0, $depth = 0) use (&$render_options, $current_url, $current_object) {
$indent_unit = ' ';
foreach ($items as $item) {
if ((int) $item->menu_item_parent !== (int) $parent_id) {
continue;
}
$indent = str_repeat($indent_unit, $depth);
// selectedを判定
$is_taxonomy = $item->type === 'taxonomy' && isset($current_object->term_id) && (int) $item->object_id === (int) $current_object->term_id;
$is_post_type = $item->type === 'post_type' && isset($current_object->ID) && (int) $item->object_id === (int) $current_object->ID;
$is_custom = $item->type === 'custom' && trailingslashit($item->url) === $current_url;
$selected = $is_taxonomy || $is_post_type || $is_custom;
?>
<option value="<?= esc_url($item->url); ?>" <?php selected($selected); ?>>
<?= $indent . esc_html($item->title); ?>
</option>
<?php
// 子メニューを再帰的に出力
$render_options($items, $item->ID, $depth + 1);
}
};
ob_start();
?>
<select onchange="if (this.value) window.location.href=this.value;">
<option value="">メニューを選択</option>
<?php $render_options($menu_items); ?>
</select>
<?php
// ウィジェット出力を置き換え
echo ob_get_clean();
return false;
});
さいごに
今回紹介した方法を使えば、「ナビゲーションメニュー」を簡単に簡単にドロップダウン表示できます。
メニュー項目を動的に表示できるため、柔軟にカスタマイズすることも可能です。

