You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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');

需求目标

  1. 隐藏“Dashboard”和“Unauthorized”页面的菜单项。
  2. 未登录时隐藏所有菜单,仅在登录后显示与登录后功能相关的菜单项(如“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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:44:56