前几天维护一个客户的网站碰到一个需求:网站有一个自定义文章类型Brand,下属有30多篇文章,客户希望这些文章能够自动更新到主菜单名为“Brand”的菜单项下作为子菜单项。因为更新Brand文章的编辑人员在添加文章后容易忘记去更新网站菜单,所以要求这个网站菜单可以自动读取文章列表,这样就不需要手动维护主菜单了。
网站菜单大致就是这样的:

查了一下文档,WordPress输出完整菜单的钩子是 wp_nav_menu_objects ,通过改写输出内容,我们就可以在指定的位置插入自己的菜单项,完整代码如下,注释含可参考信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /* * Customize menu items, add custom post type posts under specific parent item * https://blog.brain1981.com */ function brain1981_add_posts_to_menu($items, $args) { //只对特定的菜单进行处理,根据菜单名或位置调整,‘menu-top’是我对主菜单的命名 if ($args->theme_location != 'primary' && $args->menu != 'menu-top' && $args->menu_slug != 'menu-top') { return $items; } //查找目标父菜单项,我的父菜单是Brands,菜单ID是21,根据需要修改 $parent_item = null; $parent_item_index = null; foreach ($items as $index => $item) { if ($item->title == 'Brands' || $item->post_name == 'Brands' || $item->object_id == '21') { $parent_item = $item; $parent_item_index = $index; break; } } //没有找到目标菜单就直接返回 if (!$parent_item) { return $items; } //获取所有brand文章,如果没有文章,直接返回 $brand_posts = get_posts(array( 'post_type' => 'brand', 'numberposts' => -1, 'orderby' => 'menu_order title', 'order' => 'ASC', 'post_status' => 'publish', 'suppress_filters' => 0 )); //没有brand文章直接返回 if (empty($brand_posts)) { return $items; } //为父菜单项添加‘has-children’类,有时候我们需要给父菜单以以样式区别 if (!in_array('menu-item-has-children', $parent_item->classes)) { $parent_item->classes[] = 'menu-item-has-children'; $items[$parent_item_index] = $parent_item; } //获取当前最大菜单项ID,并且加上一个大数字,这样新生成的菜单项的id不会和已有的重复 $max_db_id = 0; foreach ($items as $item) { if ($item->db_id > $max_db_id) { $max_db_id = $item->db_id; } } $max_db_id+=100000; //开始为输出的对象添加内容,我们可以通过参数列表的classes参数定义特殊样式,也可以自定义target、description等输出内容作为特殊使用,以下列表应该已经列出了所有可能用得到的菜单输出项 $new_items = array(); $current_order = count($items) + 1; foreach ($brand_posts as $post) { $max_db_id++;//确保ID唯一 //创建新的菜单项对象 $new_item = new stdClass(); $new_item->ID = $max_db_id; $new_item->db_id = $max_db_id; $new_item->title = $post->post_title; $new_item->url = get_permalink($post->ID); $new_item->menu_order = $current_order++; $new_item->menu_item_parent = $parent_item->ID; $new_item->type = 'post_type'; $new_item->object = 'brand'; $new_item->object_id = $post->ID; $new_item->classes = array('menu-brand-'.$post->ID, 'menu-brand-item'); $new_item->target = ''; $new_item->attr_title = ''; $new_item->description = ''; $new_item->xfn = ''; $new_item->status = 'publish'; $new_item->post_type = 'nav_menu_item'; $new_item->post_status = 'publish'; $new_item->post_name = 'brand-' . $post->post_name; $new_item->current = false; $new_item->current_item_ancestor = false; $new_item->current_item_parent = false; $new_items[] = $new_item; } //将新增加的菜单项插入到已指定的父菜单项之后 $final_items = array(); foreach ($items as $item) { $final_items[] = $item; if ($item->ID == $parent_item->ID) { //在父菜单项后插入所有子菜单项 foreach ($new_items as $new_item) { $final_items[] = $new_item; } } } return $final_items; } add_filter('wp_nav_menu_objects', 'brain1981_add_posts_to_menu', 10, 2); |
全文完。
本站所有文章均为原创,欢迎转载,请注明文章出处:https://blog.brain1981.com/3456.html。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。
本站记录了近几年的工作中遇到的一些技术问题和解决过程,“作品集”还收录了本人的大部分作品展示。除了本博客外,我们的工作室网站 – JennyStudio,内有更多作品回顾和展示。您也可以扫描左边的二维码,关注我们的微信公众号,在微信上查看我们的案例。
