wordpress登陆前登陆后显示不同的顶部菜单

在WordPress中让"未登录"和"已登录"用户看到不同的顶部菜单,最干净、最安全、最可维护的做法是:

在同一个菜单位置(themelocation)里,根据is_user_logged_in()动态切换菜单。

下面给出三种常见实现方式,按推荐程度排序。任选其一即可,不要混用。

方案一:在主题或子主题里用filter切换(推荐)

为你的顶部菜单在主题里注册一个菜单位置(如果还没注册):

复制代码
// functions.php
add_action( 'after_setup_theme', function () {
    register_nav_menus( [
        'primary' => __( '顶部菜单', 'your-textdomain' ),
    ] );
} );

用wp_nav_menu_args过滤器在渲染前判断是否登录,并替换菜单:

复制代码
// functions.php
add_filter( 'wp_nav_menu_args', function ( $args ) {

    // 只针对前端、只针对我们关心的菜单位置
    if ( ! is_admin() && 'primary' === $args['theme_location'] ) {
        // 未登录时显示哪个菜单
        $guest_menu = get_term_by( 'slug', 'guest-menu', 'nav_menu' ); // 也可以用 id
        // 已登录时显示哪个菜单
        $user_menu  = get_term_by( 'slug', 'user-menu',  'nav_menu' );

        if ( ! is_user_logged_in() && $guest_menu ) {
            $args['menu'] = $guest_menu->term_id;
        } elseif ( is_user_logged_in() && $user_menu ) {
            $args['menu'] = $user_menu->term_id;
        }
    }

    return $args;
} );

在后台"外观→菜单"里分别建好两个菜单,并记录它们的别名(slug)或ID,对应到上面的guest_menu、user_menu即可。

注意:这两个菜单都不要勾选任何菜单位置,完全由代码接管。

模板里照常调用:

复制代码
wp_nav_menu( [ 'theme_location' => 'primary' ] );

优点

不依赖插件,逻辑集中,可版本控制。

菜单本身仍由WordPress管理,客户日后改菜单不用改代码。

方案二:用同一个菜单+条件标签隐藏/显示条目

如果你两个菜单80%都一样,只是个别条目不同,可以只建一个菜单,然后:

在"外观→菜单"给需要隐藏的条目加CSS类:

未登录条目加hide-logged-in,已登录条目加hide-logged-out。

在主题额外输出一段CSS:

复制代码
add_action( 'wp_head', function () {
    if ( is_user_logged_in() ) {
        echo '<style>.hide-logged-in{display:none!important}</style>';
    } else {
        echo '<style>.hide-logged-out{display:none!important}</style>';
    }
} );

优点:只有一个菜单,维护简单。

缺点:条目其实仍在HTML里,只是display:none,安全性/SEO略差。

方案三:用插件(不想写代码时)

"ConditionalMenus"

"UserMenus"

安装后可在菜单位置里给不同角色/登录状态指派不同菜单。

缺点:多一个插件,代码控制权低。

常见坑

缓存插件/全页缓存

如果站点启用了全页缓存(WPSuperCache、WPRocket、CloudflareAPO等),需要把登录cookie设为不缓存或者缓存分用户组,否则访客会相互看到对方的菜单。

WPRocket:开启"为登录用户单独缓存"。

Cloudflare:用BypassCacheonCookie规则匹配wordpress_logged_in_*。

使用了页面构建器(Elementor、Bricks等)

这些构建器往往用自己的Nav组件,需要在其设置里找"Visibility"或"DisplayCondition",把上述条件标签is_user_logged_in()填进去即可。

一句话总结

最推荐方案一:注册一个菜单位置,用wp_nav_menu_args过滤器根据is_user_logged_in()把$args'menu'换成不同的菜单ID。

原文

http://www.dulizhan.bj.cn/wordpress/239.html

相关推荐
李纲明8 小时前
WordPress 媒体库上传图片失败:先核 PHP 体积与目录权限,再查安全插件与对象存储
php·上传·wordpress·媒体库·devdiy
李纲明2 天前
WordPress 报 Allowed memory size exhausted:先抓堆栈找吃内存的插件,再改 memory_limit
性能优化·php·内存·插件·wordpress·devdiy
李纲明3 天前
WordPress 前台改完还是旧页:浏览器、CDN、页面缓存、对象缓存怎么分层清
缓存·cdn·wordpress·devdiy
李纲明5 天前
WordPress 结账页一直转圈不跳支付:AJAX、缓存排除、支付回调和 REST 怎么逐层核
运维·ajax·缓存·wordpress·woocommerce·devdiy·结账
李纲明6 天前
WordPress 安装或更新插件提示「无法创建目录」:权限、磁盘空间与 FS_METHOD 排查
wordpress·插件安装·devdiy·无法创建目录·fs_method
李纲明6 天前
WordPress 后台登录马上被踢回登录页:Cookie 域、HTTPS、盐值和页面缓存怎么查
运维·缓存·https·php·wordpress·cookie
用户60968624266086 天前
页面构建器做的页面翻译:短代码、区块、动态内容各自会踩什么坑
php·wordpress
李纲明7 天前
WordPress 挂上 Cloudflare 后询盘和后台异常:缓存规则、SSL 模式和真实 IP 怎么核
运维·缓存·https·cdn·wordpress·cloudflare
DEVDIY7 天前
WordPress TTFB 高怎么排查:7 步定位服务端瓶颈
wordpress
李纲明8 天前
WordPress 媒体库上传图片报「HTTP 错误」:php.ini、临时目录、安全插件和 CDN 怎么逐层查
运维·php·上传·cdn·wordpress·媒体库