问题描述

我的问题很简单,我使用 WP_Query 来检索一些使用 tax_query 的分类法过滤自定义类型的帖子。

现在我的问题是我想按照分类法排序,但是从文档和在网络中搜索我找不到解决方案。

WP_Query 中的顺序让我们通过一堆字段甚至自定义元字段进行排序,但它似乎不支持分类法。

任何指针在正确的方向?

谢谢你们。

最佳解决方案

不,不可能通过分类法进行排序,因为从某种类型的观点来看,实际上并没有什么意义。

分类法是将事情分组在一起的方式。所以在职位上有一个分类标准的那一点真的是要在职位之间分享这个分类学的术语。如果一个分类学的术语只用于一个职位,那么这样就会使分类学无意义。而且如果这些条款被分享就像它们应该是这样,那么它的命令就不会产生任何特别有用的东西。

在这种情况下你应该使用的是后期元。您可以通过 post meta 命令,并且每个帖子都是唯一的。

编辑:也就是说,您可以通过使用过滤器进行自定义 SQL 查询,通过分类法进行排序,您不能从未修改的 WP_Query:http://scribu.net/wordpress/sortable-taxonomy-columns.html

但是,如果您不得不诉诸于此类事情,那么您的数据设计结构首先是错误的。 “Terms” 在分类中不是实际的”data” 。这些术语本身没有固有的含义,它们只是他们描述的特定分组的标签。如果你把它们视为有意义的数据,那么你有一个潜在的设计缺陷。

分类法通过为其分配条款来分组事物。该分组是分类法的整体,术语只是分组中的漂亮脸。如果您有有意义的元数据分配给一个帖子,那么您应该使用后期元数据。而且您可以订购,因为后期元数据使用键和值来存储信息。使用分类法,您实际上只存储密钥,其值为该术语分组在一起的帖子。

如果您使用正确的方法,长远来说,事情会更容易。虽然我不是说你不能用分类法做一些奇怪的事情,但是从长远来看,只要使用错误就能使事情变得更加困难。

次佳解决方案

这个问题的接受答案是不能接受的。假设税收排序 「没有意义」 是不合逻辑的。他给的答案没有意义。

考虑有一个菜单帖子类型。那么你有一个”FoodCategories” 的定制税。 FoodCategories 税有”Breakfast”,”Lunch” 和”Dinner” 条款。如果您使用 tax_query 参数提交查询,则您现在将具有所有条款的结果集,但是按发布日期排序。

为了得到正确的订单,相对于他们的条款,然后通过将帖子分隔成各自的类别,正确地显示在前端,您必须循环遍历结果集,然后查询每个单独的帖子结果集找到它的术语并与当前术语进行比较,过滤到数组中并继续进行。那么你必须再次循环显示新的数组。这没有生产力。

如果 WP 有一个”tax__in” orderby 选项,那么它会很好,因为它是一个”post__in”,但是由于没有,你要么做上述可笑的过程; 通过’posts_orderby’ 过滤器和’posts_join’ 过滤器自定义查询,以便通过方法调整顺序并将术语分别添加到结果集中; 或者您必须针对相对于这些术语在 HTML 部分中筛选的每个术语进行新的查询。

最有效的方法是通过过滤器更改查询字符串。最简单的是做三个单独的查询。 WP API 应该按照税收排序或任何限制性查询参数进行处理。如果您是基于某些条件限制查询,那么许多人将很可能需要通过相同条件进行排序。

第三种解决方案

是的,但它是相当涉及…

添加到您的主题中的 functions.php:

function orderby_tax_clauses( $clauses, $wp_query ) {
    global $wpdb;
    $taxonomies = get_taxonomies();
    foreach ($taxonomies as $taxonomy) {
        if ( isset( $wp_query->query['orderby'] ) && $taxonomy == $wp_query->query['orderby'] ) {
            $clauses['join'] .=<<<SQL
LEFT OUTER JOIN {$wpdb->term_relationships} ON {$wpdb->posts}.ID={$wpdb->term_relationships}.object_id
LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id)
LEFT OUTER JOIN {$wpdb->terms} USING (term_id)
SQL;
            $clauses['where'] .= " AND (taxonomy = '{$taxonomy}' OR taxonomy IS NULL)";
            $clauses['groupby'] = "object_id";
            $clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) ";
            $clauses['orderby'] .= ( 'ASC' == strtoupper( $wp_query->get('order') ) ) ? 'ASC' : 'DESC';
        }
    }
    return $clauses;
}

    add_filter('posts_clauses', 'orderby_tax_clauses', 10, 2 );

这是从一些发现的东西和一些我自己做的东西。解释是非常艰难的,但是底线是这样运行的,你可以放置?orderby =(分类法查询 var)& order = ASC(或 DESC),她会直接关闭!

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。