
本文介绍如何在使用 get_terms() 获取自定义分类法(如 work-category)术语时,将带有自定义字段 stick_to_end 的特定术语强制排在排序结果的最后,同时保持其余术语按文章数量(count)降序排列。
本文介绍如何在使用 `get_terms()` 获取自定义分类法(如 work-category)术语时,将带有自定义字段 `stick_to_end` 的特定术语强制排在排序结果的最后,同时保持其余术语按文章数量(count)降序排列。
在 WordPress 开发中,get_terms()(底层为 WP_Term_Query)不支持多字段复合排序(例如 'orderby' => ['count' => 'DESC', 'stick_to_end' => 'ASC']),也不原生支持基于 term_meta 的排序条件(如 meta_query 在 get_terms 中无效)。因此,无法通过参数直接实现“按 count 排序,但带 stick_to_end=1 的项始终置底”的效果。
正确做法是:先获取全部术语,再用 PHP 手动重排序。核心思路是——将 stick_to_end 值为 1(即需置底)的术语统一视为“高权重”,使其在比较中始终大于其他项,从而被 usort() 排至数组末尾;其余术语则按 count 降序排列。
以下是完整、可直接集成的优化方案:
✅ 步骤一:获取并预排序术语
在调用 get_terms() 后、遍历前插入自定义排序逻辑:
$terms = get_terms([
'taxonomy' => 'work-category',
'hide_empty' => true,
'orderby' => 'count',
'order' => 'DESC',
]);
// ✅ 关键:手动重排序 —— stick_to_end=1 的项排到最后,其余保持 count 降序
if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) {
usort( $terms, function( $a, $b ) {
// 获取 stick_to_end 元数据(转为整数便于比较)
$a_ste = (int) get_term_meta( $a->term_id, 'stick_to_end', true );
$b_ste = (int) get_term_meta( $b->term_id, 'stick_to_end', true );
// 若两者 sticky 状态相同,则按原始 count 降序(保持 get_terms 的默认排序逻辑)
if ( $a_ste === $b_ste ) {
return $b->count - $a->count; // 注意:DESC → b 在前
}
// stick_to_end=1 的项排在后面(即返回 1 表示 $a 应在 $b 之后)
return $a_ste > $b_ste ? 1 : -1;
});
}
⚠️ 注意事项:
- 必须确保
stick_to_end自定义字段已为对应术语正确设置(后台或代码中保存为1或0);get_term_meta()返回空字符串时(int)会转为0,安全可靠;usort()会修改原$terms数组,无需重新赋值。
✅ 步骤二:保留原有循环结构(无需改动)
后续的 foreach ($terms as $category) 及文章查询逻辑完全保持不变,此时 $terms 已按「非置底项按 count 降序 + 置底项统一排末尾」完成重组。
? 补充:若需多个“置底项”且保持内部顺序?
当前逻辑中所有 stick_to_end=1 的项彼此之间无次序保证。如需它们也按 count 降序排列(仅整体在末尾),可升级比较函数:
usort( $terms, function( $a, $b ) {
$a_ste = (int) get_term_meta( $a->term_id, 'stick_to_end', true );
$b_ste = (int) get_term_meta( $b->term_id, 'stick_to_end', true );
if ( $a_ste && $b_ste ) {
// 二者均需置底 → 按 count 降序
return $b->count - $a->count;
}
if ( $a_ste ) return 1; // $a 置底 → 排 $b 后
if ( $b_ste ) return -1; // $b 置底 → $a 排 $b 前
// 二者均不置底 → 按 count 降序
return $b->count - $a->count;
});
✅ 总结
WordPress 的 get_terms() 不支持元字段参与排序,但借助 usort() + get_term_meta() 可灵活实现复杂排序需求。该方案轻量、兼容性强(适配 WP 5.0+),且不依赖 SQL 查询改造,是处理“伪 sticky term”场景的最佳实践。记住:排序逻辑必须置于 get_terms() 之后、循环之前,即可无缝集成到现有模板中。











