我们知道,当我们访问一个 WordPress URL 时,WordPress 会自动给导航菜单项目中的这个 URL 加上“current-menu-item”类,以帮助前端开发者进行高亮处理。当我们有多个文章类型的时候,访问文章类型的文章详情页面的时候,我们有时候需要给该文章类型的存档页也加上“current-menu”类。比如访问 http://abc.com/box/small-box 的时候,我们想给该文章类型的存档页 http://abc.com/box/ 加上 “current-menu-item” 类,WordPress 默认是不支持这个特性的。在严格意义上来讲,文章类型的详情页和文章类型的存档页不是同一个页面,但是从用户体验的角度来讲,这种操作是讲的通的。
通过 nav_menu_css_class Action 钩子为文章类型详情页添加当前菜单类
我们可以通过比对文章类型 Slug 和 URL 字符串的方式来实现这个需求,下面是实现的代码,这种方法并不是很严谨,在特殊情况下,会有 bug 出现。
add_action('nav_menu_css_class', function ($classes, $item)
{
// 获取当前文章
global $post;
// 获取当前文章的文章类型
$current_post_type = get_post_type_object(get_post_type($post->ID));
$current_post_type_slug = $current_post_type->rewrite[ 'slug' ];
// 获取导航菜单项的 URL
$menu_slug = strtolower(trim($item->url));
// 如果菜单项包含当前文章类型的 Slug,添加当前菜单 CSS 类
if (strpos($menu_slug, $current_post_type_slug) !== false) {
$classes[] = 'current-menu-item';
}
// 返回添加后的 CSS 类数据
return $classes;
}, 10, 2);
注意,以上代码只在固定链接结构设置为 “文章名” 的情况下有效,其他情况可以参考上面的代码自行测试。
可能会遇到的 Bug 及解决思路
我们设想一下这种情况,一个文章类型的名称为 “box”, 而网站的地址为 www.express-box.com,这种情况下,网站的 Url 总是包含 “box”,当我们打开 box 文章类型的详情页时,所有的菜单项目都会被添加一个当前菜单类。
比对 URL 的时候,把网址的域名部分排除掉可以减少这个 Bug 发生的概率。根据 WordPress URL 的结构特性,文章类型 Slug 是紧跟域名显示的,我们可以使用正则表达式把网址中的 这个文章类型 Slug 匹配出来,再跟通过文章对象获取到的文章类型 Slug 比对就可以了。
除了给当前文章的文章类型存档 URL 添加当前菜单类,我们还可以通过类似的方法给当前文章所属的分类或者自定义分类法项目添加当前菜单类,时间所限,就不一一测试对应的代码了,有空测试了再补上。如果您写出了对应的代码,可以在评论中贴出,供大家参考。