Answers:
不,不可能按分类法进行排序,因为从某种类型的角度来看,这实际上没有多大意义。
分类法是将事物组合在一起的方法。因此,对职位进行分类的要点实际上是让该分类中的术语在职位之间共享。如果一个分类法中每个术语仅在一个帖子上使用,那么这将使分类法变得毫无意义。而且,如果按应有的方式共享术语,那么按其排序不会产生任何特别有用的信息。
在这种情况下,您应该使用的是post meta。您可以按帖子元命令进行订购,并且每个帖子都具有唯一性。
编辑:也就是说,您可以通过使用过滤器进行自定义SQL查询来按分类进行排序,而不能通过未修改的WP_Query进行分类:http ://scribu.net/wordpress/sortable-taxonomy-columns.html
但是,如果您不得不采取这种方式,那么您的数据设计结构首先是错误的。分类中的“术语”不是实际的“数据”。这些术语本身没有内在的含义,它们只是它们所描述的特定组的标签。如果将它们视为有意义的数据,则存在潜在的设计缺陷。
分类法通过为事物分配术语来对事物进行分组。分组是分类法的重点,术语只是分组中的漂亮面孔。如果您有有意义的元数据可分配给帖子,则应改为使用帖子元。而且您可以订购,因为post meta同时使用键和值来存储信息。使用分类法,您实际上只存储键,键的值是按该术语分组的帖子。
如果您使用正确的方法,从长远来看,事情会变得容易。我并不是说您不能对分类法做一些奇怪的事情,但从长远来看,您只是在错误地使用它来使事情变得更艰难。
这个问题的可接受答案是不可接受的。假定按税款“毫无意义”是不合逻辑的。他给出的答案没有任何意义。
考虑使用菜单项类型。然后,您有一个“ FoodCategories”的自定义税。FoodCategories税具有“早餐”,“午餐”和“晚餐”术语。现在,如果您使用tax_query参数提交查询,那么您现在将获得一个包含所有条款的结果集,但是这些条款是按发布日期排序的。
为了从这些条款中获得正确的顺序,然后通过将帖子分为不同的类别来适当地显示在前端,您必须遍历结果集,然后查询列表中的每个帖子结果集以查找其术语并与当前术语进行比较,过滤成数组并继续进行。然后,您必须再次遍历新数组以进行显示。这没有生产力。
如果WP具有“ post__in”选项,那么如果WP具有“ tax__in” orderby选项会很好,但是由于没有,因此您要么必须执行上述荒谬的过程,要么必须执行上述操作。通过“ posts_orderby”过滤器和“ posts_join”过滤器自己定制查询,以调整orderby方法并将其分别添加到结果集中;或您必须针对与这些字词相关的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 =(taxonomy query var)&order = ASC(或DESC),她马上就出发!
add_filter('posts_clauses', 'orderby_tax_clauses', 10, 2 );
为“ add_filter('posts_clauses', 'todo_tax_clauses', 10, 2 );
谢谢” :)
我在这里玩游戏迟到了,但是有一种更简单的WordPressy方法可以做到这一点。
$tax_query = array();
$tax_query['relation']="OR";
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $cat_terms,
);
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array(
'post_type'=>'post',
'posts_per_page'=>12,
'paged'=>$paged,
'tax_query' => $tax_query,
);
add_filter('posts_orderby', 'edit_posts_orderby');
function edit_posts_orderby($orderby_statement) {
$orderby_statement = " term_taxonomy_id ASC ";
return $orderby_statement;
}
query_posts($args);
remove_filter('posts_orderby', 'edit_posts_orderby');
不要忘了之后删除过滤器...
这对b / c有效,tax_query为您创建联接等,您只需要按联接中的字段之一进行排序。
好吧,我想展示一下我按类别/分类对自定义帖子类型进行排序的经验。
网络
案子
在存档类别列表页面中,客户希望帖子按以下类别排序
步骤
首先,我从未修改的存档页面查询中捕获了请求,该请求恰好是这样的:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
WHERE 1=1
AND ( wp_term_relationships.term_taxonomy_id IN (5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23,25,26,28,29,31,32,33,35,38,95,101,102,193) )
AND wp_posts.post_type IN ('ruta', 'nav_menu_item')
AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 45
AND wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC LIMIT 0, 20
其次,我根据数据库在Sequel Pro中编辑了sql代码。我得出这个结论(是的,可能可以改进:我对MySQL的了解并不突出):
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID, tt1.parent AS pare,
(
SELECT COUNT(*)
FROM wp_posts
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id )
INNER JOIN wp_term_taxonomy AS tt2 ON ( tt2.term_taxonomy_id = tt1.term_taxonomy_id )
WHERE 1=1
AND tt1.parent = pare
) AS Total
FROM wp_posts
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id )
INNER JOIN wp_terms ON ( tt1.term_id = wp_terms.term_id )
WHERE 1=1
AND ( wp_term_relationships.term_taxonomy_id IN (5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23,25,26,28,29,31,32,33,35,38,95,101,102,193) )
AND wp_posts.post_type IN ('ruta', 'nav_menu_item')
AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 45
AND wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY
total DESC,
wp_terms.name
第三,我使用三个过滤器将查询挂接到functions.php文件上:posts_fields,posts_join和posts_orderby
functions.php中的代码:
function xc_query_fields( $fields ) {
$fields = "wp_posts.ID, wp_posts.post_title, wp_terms.name, tt1.parent AS pare,
(
SELECT COUNT(*)
FROM wp_posts
INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id )
INNER JOIN wp_term_taxonomy AS tt2 ON ( tt2.term_taxonomy_id = tt1.term_taxonomy_id )
WHERE 1=1
AND tt1.parent = pare
)
AS Total";
return $fields;
}
function xc_query_joins( $join ) {
$join .= "INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id )
INNER JOIN wp_terms ON ( tt1.term_id = wp_terms.term_id )";
return $join;
}
function xc_query_orderby( $join ) {
$join = "total DESC, wp_terms.name ";
return $join;
}
最后,我根据一些条件从pre_get_post钩子触发了过滤器
function filtra_queries( $query )
{
if ( is_archive() && $query->is_main_query() && !is_admin() ) {
$rutes = array('viajes-privados', 'asia', 'africa', 'oceania', 'america', 'oriente-proximo');
if ( in_array( $query->get('category_name'), $rutes ) )
{
add_filter( 'posts_fields', 'xc_query_fields' );
add_filter( 'posts_join', 'xc_query_joins' );
add_filter( 'posts_orderby', 'xc_query_orderby' );
}// end if in_array
}// end if is_archive
}
add_filter('pre_get_posts', 'filtra_queries');
希望这可以帮助某人
我遇到了一个非常相似的问题:我想通过自定义分类法(问题)订购自定义的后置存档(杂志文章)。我从不在我的网站上进行直接SQL查询-通常,如果您像其他答案一样,则需要重新考虑您的方法。
问题:
1)Wordpress不允许您以任何智能方式排序分类法。
2)Wordpress只是不允许orderby
在帖子类型WP_Query上使用分类法(由Otto阐明)。
解决方案:
1)分类分类法目前最好由“ 定制分类法顺序” NE插件完成。它允许您通过所见即所得来订购分类法,wp-admin
这不是我会做的,但是我没有发现更好的方法。
设置插件后,您将获得与我在这里所做的类似的操作。记下该选项Auto-sort Queries of this Taxonomy
-将其设置为Custom Order as Defined Above
; 这可以为您提供所需的订购。屏幕截图:
2)有了分类的分类法,您现在可以创建贯穿每个术语的一系列WP_Query调用,有效地创建分类法排序的档案。使用get_terms()
创建所有的税收条件的数组,然后运行foreach
在每个学期。这WP_Query
将为每个术语项创建一个,它将返回给定术语的所有帖子,从而有效地创建按分类术语排序的档案。实现此目的的代码:
// Get your terms and put them into an array
$issue_terms = get_terms([
'taxonomy' => 'issues',
'hide_empty' => false,
]);
// Run foreach over each term to setup query and display for posts
foreach ($issue_terms as $issue_term) {
$the_query = new WP_Query( array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'issues',
'field' => 'slug',
'terms' => array( $issue_term->slug ),
'operator' => 'IN'
)
)
) );
// Run loop over each query
while($the_query->have_posts()) :
$the_query->the_post();
// YOUR TEMPLATE OUTPUT FOR EACH POST
endwhile;
}
本网站上的相关阅读: 以自定义帖子类型显示所有帖子,按自定义分类法分组
我不确定为什么这里的所有解决方案都过分夸大了。好的,已经有五年了,但是我现在正在运行以下代码,它可以正常工作:
<?php // Default
$wheels_args = array(
'post_type' => 'wheels',
'posts_per_page' => '96',
'orderby' => 'taxonomy, name', // Just enter 2 parameters here, seprated by comma
'order'=>'ASC'
);
$loop = new WP_Query($wheels_args);
?>
这将首先按照CPT的分类法(按字母顺序)对这些CPT的分类法进行排序,然后在这些分类法组中按字母顺序对其进行分类。
这是我用于此特定问题的解决方案。此解决方案适用于无法使用pre_get_posts
过滤器并且查询中存在现有分页的极端情况(例如:WooCommerce):
global $wpdb;
$taxonomies = array('my-tax-1', 'my-tax-2', 'my-tax-3');
$orderby = "'".implode("', '", array_keys($taxonomies))."'";
$id_sql = $GLOBALS['wp_query']->request;
$id_sql = preg_replace('/LIMIT\s+\d+\s?,?\s\d*/', '', $id_sql);
$id_sql = str_replace('SQL_CALC_FOUND_ROWS', '', $id_sql);
$term_sql = "SELECT
tt.taxonomy AS `taxonomy`,
t.name AS `term_name`,
t.slug AS `term_slug`,
count(*) AS `term_count`
FROM ({$id_sql}) p
JOIN wp_term_relationships tr
ON p.ID = tr.object_id
JOIN wp_term_taxonomy tt
ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms t
ON tt.term_id = t.term_id
WHERE tt.taxonomy IN ({$orderby})
GROUP BY t.slug
ORDER BY
FIELD(tt.taxonomy, {$orderby})"; // Add further specific ordering here
$results = $wpdb->get_results($term_sql, ARRAY_A);
我已经使用它来创建按分类,术语和每期发布次数排序的导航菜单。
如果您只想要帖子,则将查询更改为SELECT p.*
和GROUP BY p.ID
就像查询之前的查询一样,但是如果我们不查询太多帖子,也不会打扰...想法是修改主查询,因此我们甚至不需要去模板并生成新查询,循环...
function grouped_by_taxonomy_main_query( $query ) {
if ( $query->is_home() && $query->is_main_query() ) { // Run only on the homepage
$post_ids = array();
$terms = get_terms('my_custom_taxonomy');
foreach ( $terms as $term ) {
$post_ids = array_merge( $post_ids, get_posts( array(
'posts_per_page' => 4, // as you wish...
'post_type' => 'my_custom_post_type', // If needed... Default is posts
'fields' => 'ids', // we only want the ids to use later in 'post__in'
'tax_query' => array( array( 'taxonomy' => $term->taxonomy, 'field' => 'term_id', 'terms' => $term->term_id, )))) // getting posts in the current term
);
}
$query->query_vars['post_type'] = 'my_custom_post_type'; // Again, if needed... Default is posts
$query->query_vars['posts_per_page'] = 16; // If needed...
$query->query_vars['post__in'] = $post_ids; // Filtering with the post ids we've obtained above
$query->query_vars['orderby'] = 'post__in'; // Here we keep the order we generated in the terms loop
$query->query_vars['ignore_sticky_posts'] = 1; // If you dont want your sticky posts to change the order
}
}
// Hook my above function to the pre_get_posts action
add_action( 'pre_get_posts', 'grouped_by_taxonomy_main_query' );