如何在WordPress插件中隐藏指定菜单项并实现登录菜单切换?
WordPress插件菜单自定义解决方案
问题背景
我正在用PHP开发一个WordPress插件,已创建多个短代码实现不同功能(如登录页面、未授权页面和仪表盘),并为这些功能创建了对应包含短代码的页面。
现有页面创建代码
目前通过激活钩子成功创建页面的代码如下:
function my_plugin_activation() { $pageData = array( 'post_title' => 'Dashboard', 'post_content' => '[dashboard]', // shortcode 'post_status' => 'publish', 'post_type' => 'page', 'post_name' => 'dashboard', ); // 插入新页面 $pageId = wp_insert_post($pageData); } register_activation_hook(__FILE__, 'my_plugin_activation');
需求目标
- 隐藏“Dashboard”和“Unauthorized”页面的菜单项。
- 未登录时隐藏所有菜单,仅在登录后显示与登录后功能相关的菜单项(如“Dashboard”、“Profile”和“Logout”)。
尝试过的无效方法
方法一:硬编码菜单名称移除菜单项
此方法因硬编码主题菜单名称,无法适配不同主题,导致无法找到目标菜单:
// 若页面不应添加到菜单,从默认头部菜单移除 $menu_name = 'twentytwentytwo'; // 替换为你的菜单名称 $menu = wp_get_nav_menu_object($menu_name); if ($menu) { $menu_id = $menu->term_id; // 查找并移除菜单中的对应页面 $menuItems = wp_get_nav_menu_items($menu_id); foreach ($menuItems as $menuItem) { if ($menuItem->object_id == $pageId) { wp_delete_post($menuItem->ID); } } }
方法二:激活钩子内注册菜单过滤器
此方法中,过滤器仅在激活插件时注册一次,后续页面加载时过滤器不会生效:
function my_plugin_activation() { $pageData = array( 'post_title' => 'Dashboard', 'post_content' => '[dashboard]', // shortcode 'post_status' => 'publish', 'post_type' => 'page', 'post_name' => 'dashboard', ); // 插入新页面 $pageId = wp_insert_post($pageData); // 注册修改菜单项的函数 add_filter('wp_nav_menu_objects', 'my_remove_menu_items'); } register_activation_hook(__FILE__, 'my_plugin_activation'); function my_remove_menu_items($items) { // 需要移除的菜单项别名 $menu_item_slugs = array('dashboard'); // 替换为实际别名 foreach ($items as $key => $item) { if (in_array($item->post_name, $menu_item_slugs)) { unset($items[$key]); } } return $items; }
最终解决方案
以下代码可实现需求,确保所有插件用户自动应用这些更改:
1. 激活钩子:创建页面并移除自动添加的菜单项
function my_plugin_activation() { // 创建Dashboard页面 $dashboard_page = array( 'post_title' => 'Dashboard', 'post_content' => '[dashboard]', 'post_status' => 'publish', 'post_type' => 'page', 'post_name' => 'dashboard', 'post_author' => get_current_user_id(), ); $dashboard_page_id = wp_insert_post($dashboard_page); // 创建Unauthorized页面 $unauthorized_page = array( 'post_title' => 'Unauthorized', 'post_content' => '[unauthorized]', 'post_status' => 'publish', 'post_type' => 'page', 'post_name' => 'unauthorized', 'post_author' => get_current_user_id(), ); $unauthorized_page_id = wp_insert_post($unauthorized_page); // 创建Profile页面 $profile_page = array( 'post_title' => 'Profile', 'post_content' => '[profile]', 'post_status' => 'publish', 'post_type' => 'page', 'post_name' => 'profile', 'post_author' => get_current_user_id(), ); $profile_page_id = wp_insert_post($profile_page); // 创建Logout页面 $logout_page = array( 'post_title' => 'Logout', 'post_content' => '[logout]', 'post_status' => 'publish', 'post_type' => 'page', 'post_name' => 'logout', 'post_author' => get_current_user_id(), ); $logout_page_id = wp_insert_post($logout_page); // 保存页面ID到插件选项,方便后续调用 update_option('my_plugin_pages', array( 'dashboard' => $dashboard_page_id, 'unauthorized' => $unauthorized_page_id, 'profile' => $profile_page_id, 'logout' => $logout_page_id, )); // 自动检测主菜单并移除指定页面的菜单项 $main_menu = wp_get_nav_menu_object('primary'); if (!$main_menu) { // 若找不到primary菜单,取第一个可用菜单 $menus = wp_get_nav_menus(); if (!empty($menus)) { $main_menu = $menus[0]; } } if ($main_menu) { $menu_items = wp_get_nav_menu_items($main_menu->term_id); $pages_to_remove = array($dashboard_page_id, $unauthorized_page_id); foreach ($menu_items as $item) { if (in_array($item->object_id, $pages_to_remove)) { wp_delete_post($item->ID, true); } } } } register_activation_hook(__FILE__, 'my_plugin_activation');
2. 菜单过滤器:根据登录状态动态控制菜单项显示
function my_plugin_filter_menu_items($items) { $my_pages = get_option('my_plugin_pages'); if (!$my_pages) { return $items; } // 定义不同登录状态下允许显示的页面ID $allowed_logged_in = array($my_pages['dashboard'], $my_pages['profile'], $my_pages['logout']); $allowed_logged_out = array(); // 未登录时不显示任何菜单,可根据需求添加登录页面ID $allowed_ids = is_user_logged_in() ? $allowed_logged_in : $allowed_logged_out; // 筛选菜单项 $filtered_items = array(); foreach ($items as $item) { // 处理插件创建的页面 if (in_array($item->object_id, $my_pages)) { if (in_array($item->object_id, $allowed_ids)) { $filtered_items[] = $item; } } else { // 非插件页面:未登录时全部隐藏,登录时可根据需求调整是否保留 if (!is_user_logged_in()) { continue; } // 若登录后需保留其他页面,取消以下注释 // $filtered_items[] = $item; } } return $filtered_items; } add_filter('wp_nav_menu_objects', 'my_plugin_filter_menu_items', 10, 1);
关键说明
- 页面ID存储到插件选项中,避免硬编码,适配后续页面ID变化。
- 自动检测主菜单,无需依赖特定主题的菜单名称,提升兼容性。
- 菜单过滤器全局注册,每次页面加载都会执行,确保动态控制菜单显示。
内容的提问来源于stack exchange,提问作者B.Balamanigandan
相关产品推荐
相关产品推荐

