WordPress中拖放更新菜单子项与菜单结合及编程挂载列表为菜单项咨询
实现方案
通用实现思路
- 先拿到你已经生成好的自定义排序结果数组,里面至少要包含每个项目的标题、访问链接、ID标识三个核心字段,私有内容要提前做权限校验,没有访问权限的用户不要返回对应项
- 注册自定义菜单位置(如果你的系统还没有预留主菜单的扩展钩子的话),或者直接挂载到现有主菜单的钩子上
- 遍历排序好的内容列表,按你需要的层级(父菜单/子菜单)生成对应的菜单项配置
- 把生成的配置注入到主菜单的输出逻辑里,覆盖原有默认的菜单输出
常用场景代码示例
如果你用的是WordPress
WordPress原生提供了wp_nav_menu_objects钩子可以直接修改菜单输出,不用动主题代码:
你可以选择先加一个自定义的父菜单项当容器,再把排序好的内容当子项插入,也可以直接把排序内容作为一级菜单项添加:
// 把自定义排序内容注入主菜单 add_filter('wp_nav_menu_objects', 'add_custom_sorted_content_to_menu', 10, 2); function add_custom_sorted_content_to_menu($items, $args) { // 只针对主菜单生效,把theme_location的值换成你自己主题主菜单的注册名 if ($args->theme_location != 'primary') { return $items; } // 这里调用你自己已经写好的自定义排序方法,拿到排序后的内容数组 $sorted_contents = your_custom_get_sorted_posts_pages_function(); if (empty($sorted_contents)) { return $items; } // 先添加父级菜单,不需要父容器的话可以删除这部分代码 $parent_item = (object) [ 'ID' => 999999, // 填写一个不会和现有菜单ID重复的数值即可 'title' => '自定义排序内容', 'url' => '#', // 父菜单如果不需要跳转就填# 'menu_item_parent' => 0, 'type' => 'custom', 'object' => 'custom', 'object_id' => 999999, 'classes' => ['custom-sorted-parent'] ]; array_push($items, $parent_item); // 遍历排序内容加子菜单,不需要父容器的话把menu_item_parent的值改为0即可 foreach ($sorted_contents as $content) { // 私有内容权限校验,没权限的直接跳过 if ($content->post_status == 'private' && !current_user_can('read_private_posts')) { continue; } $child_item = (object) [ 'ID' => $content->ID . '999', 'title' => $content->post_title, 'url' => get_permalink($content->ID), 'menu_item_parent' => $parent_item->ID, // 关联到上面的父菜单ID 'type' => 'custom', 'object' => 'custom', 'object_id' => $content->ID, 'classes' => ['custom-sorted-child'] ]; array_push($items, $child_item); } return $items; }
如果你用的是自定义开发的系统
直接在渲染主菜单的模板逻辑里插入排序后的内容即可:
- 渲染原有菜单项目的循环结束后,调用你自定义的排序方法拿到内容数组
- 权限校验后循环输出菜单项的HTML结构即可,示例结构如下:
<ul class="main-menu"> <!-- 原有默认菜单项 --> <li><a href="/">首页</a></li> <li><a href="/about">关于</a></li> <!-- 插入自定义排序的内容 --> <li class="has-child"> <a href="#">自定义排序内容</a> <ul class="sub-menu"> <?php foreach ($sorted_contents as $item): ?> <?php if ($item['is_private'] && !$current_user_has_permission) continue; ?> <li><a href="<?php echo $item['url']; ?>"><?php echo $item['title']; ?></a></li> <?php endforeach; ?> </ul> </li> </ul>
注意私有内容一定要在服务端做权限校验,不要只在前端隐藏,避免未授权用户通过直接输入链接访问到私有内容。
内容的提问来源于stack exchange,提问作者Karan Naimish Trivedi
相关产品推荐
相关产品推荐

