使用Transient缓存为后台自定义文章类型导航项添加通知气泡
给WordPress自定义文章类型后台菜单加高性能通知气泡
嘿,这个需求我太熟了——既要给自定义文章类型的后台菜单加美观的通知气泡,又不想因为频繁查询拖慢后台速度,用WordPress自带的Transient缓存绝对是最优解,我给你梳理一套完整的可落地方案:
核心思路
直接用WP_Query每次加载后台都查数据库,肯定会拖慢速度。Transient是WP原生的缓存机制,能把我们需要的计数存起来,定期自动更新,完美平衡数据实时性和后台性能。
1. 写一个带缓存的计数函数
先搞一个函数,它会优先从缓存里取计数,只有缓存过期或者不存在的时候才去查数据库,这样能极大减少数据库请求:
function get_custom_post_type_notification_count() { // 先尝试从Transient缓存拿数据 $count = get_transient('custom_post_type_notification_count'); if (false === $count) { // 缓存没命中,执行轻量查询 $args = array( 'post_type' => 'your_custom_post_type', // 替换成你的自定义文章类型slug 'post_status' => 'pending', // 改成你要统计的状态,比如draft、自定义状态都可以 'posts_per_page' => -1, 'fields' => 'ids', // 只查ID,减少查询开销,提升速度 ); $query = new WP_Query($args); $count = $query->found_posts; // 把结果存进缓存,这里设15分钟(900秒),可根据需求调整 set_transient('custom_post_type_notification_count', $count, 900); } return $count; }
这里重点说下:用fields => 'ids'是因为我们只需要计数,不需要完整的文章对象,这样查询会更轻量;缓存时间可以根据你的实时性需求改,比如要更实时就设5分钟(300秒),反之可以设30分钟甚至更久。
2. 给后台菜单添加上气泡
接下来用admin_menu钩子找到你的自定义文章类型菜单,把气泡HTML加进去。我用了WP后台原生的气泡样式,这样不用自己写太多CSS,和系统风格统一:
function add_custom_post_type_menu_notification() { global $menu; $notification_count = get_custom_post_type_notification_count(); if ($notification_count <= 0) { return; // 计数为0就不显示气泡,避免空占位 } // 遍历后台菜单,找到我们的自定义文章类型项 foreach ($menu as $key => $menu_item) { // 替换成你的自定义文章类型对应的菜单slug if ($menu_item[2] === 'edit.php?post_type=your_custom_post_type') { // 拼接原生风格的气泡HTML $menu[$key][0] .= sprintf( '<span class="update-plugins count-%d"><span class="plugin-count">%d</span></span>', $notification_count, number_format_i18n($notification_count) ); break; } } } // 用高优先级(999)确保最后修改菜单,避免被其他代码覆盖 add_action('admin_menu', 'add_custom_post_type_menu_notification', 999);
3. 缓存自动刷新(可选但推荐)
默认缓存是定期过期的,但如果我们想在内容变化时立即更新缓存(比如用户提交了一篇待审核的自定义文章),可以加个钩子监听文章状态变化,自动清除旧缓存:
function refresh_custom_post_type_notification_cache($new_status, $old_status, $post) { // 只处理我们的自定义文章类型 if ($post->post_type !== 'your_custom_post_type') { return; } // 只在目标状态变化时清除缓存(和计数函数里的post_status保持一致) $target_status = 'pending'; if ($new_status === $target_status || $old_status === $target_status) { delete_transient('custom_post_type_notification_count'); } } add_action('transition_post_status', 'refresh_custom_post_type_notification_cache', 10, 3);
这样只要自定义文章的状态涉及到我们统计的类型,缓存就会被删除,下次加载后台时会自动重新查询并缓存,保证数据不会太滞后。
4. 自定义气泡样式(可选)
如果觉得WP原生气泡不符合你的插件风格,也可以自己写CSS定制:
function custom_menu_notification_style() { ?> <style> .update-plugins.count-custom { background-color: #2196F3; /* 自定义蓝色背景 */ color: #fff; font-size: 10px; padding: 1px 6px; border-radius: 12px; margin-left: 6px; font-weight: 600; } </style> <?php } add_action('admin_head', 'custom_menu_notification_style');
然后把之前气泡HTML里的count-%d改成count-custom,就能用上你自己的样式了。
最后要注意的点
- 把所有
your_custom_post_type替换成你实际的自定义文章类型slug; - 调整
post_status为你需要统计的具体状态(比如草稿、私密、自定义状态都可以); - 如果你的计数逻辑更复杂(比如按用户角色统计、带自定义字段条件),直接修改
$args数组里的参数就行,比如加meta_query或者author条件。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

