回答:
いいえ、特定のタイプの観点からは実際にはあまり意味がないので、分類法で注文することはできません。
分類法は、物事をグループ化する方法です。そのため、投稿にタクソノミーを設定するポイントは、投稿間で共有されるタクソノミーに用語を設定することです。分類法にそれぞれ1つの投稿でのみ使用される用語がある場合、分類法は無意味になります。また、用語が本来あるべきように共有されている場合、それによる順序付けは特に有用なものを生成しません。
このような状況で使用する必要があるのは、ポストメタです。投稿メタで注文することができ、それは各投稿に固有です。
編集:つまり、フィルターを使用してカスタムSQLクエリを作成することで、分類法で並べ替えることができます。変更されていないWP_Queryからはできません:http ://scribu.net/wordpress/sortable-taxonomy-columns.html
ただし、この種のことを行う必要がある場合は、そもそもデータ設計構造が間違っています。分類法の「用語」は、実際の「データ」ではありません。用語自体には固有の意味はありません。それらは説明している特定のグループの単なるラベルです。それらを意味のあるデータとして扱っている場合、根本的な設計上の欠陥があります。
分類法は、用語を割り当てて分類します。そのグループ化は分類法の全体的なポイントであり、用語はグループ化のほんの一面にすぎません。投稿に割り当てる意味のあるメタデータがある場合は、代わりに投稿メタを使用する必要があります。また、ポストメタは情報を保存するためにキーと値の両方を使用するため、注文することができます。分類法では、キーのみを保存し、その値はその用語でグループ化された投稿になります。
正しいアプローチを使用すれば、長い目で見れば簡単になります。タクソノミーでは奇妙なことはできないと言っているわけではありませんが、間違った使い方をすることで、長い目で見れば自分を難しくしているだけです。
この質問に対する受け入れられた答えは受け入れられません。税による注文は「意味をなさない」と仮定するのは非論理的です。彼が与えた答えは意味をなさない。
メニュー投稿タイプを持つことを検討してください。次に、「FoodCategories」のカスタム税があります。FoodCategories税には、「朝食」、「昼食」、および「夕食」という用語があります。tax_queryパラメータを使用してクエリを送信すると、すべての用語を含む結果セットが得られますが、それらは投稿日順に並べられます。
これらの用語に関連して正しい順序を取得し、投稿をさまざまなカテゴリに分けてフロントエンドに適切に表示するには、結果セットをループしてから、各投稿をクエリする必要があります結果セットを検索して現在の用語と比較し、配列にフィルターをかけて全体を通して続行します。次に、表示のために新しい配列を再度ループする必要があります。これは生産的ではありません。
WPに "post__in"オプションと同様に "tax__in" orderbyオプションがあればいいのですが、ないので、上記のとんでもないプロセスを実行する必要があります。orderbyメソッドを調整し、用語を結果セットに追加するために、「posts_orderby」フィルターと「posts_join」フィルターを使用して自分でクエリをカスタマイズします。または、それらの用語に関連するhtmlセクション内でフィルタリングする各用語に対して新しいクエリを作成する必要があります。
最も効率的なのは、フィルターを使用してクエリ文字列を変更することです。最も簡単な方法は、3つの個別のクエリを実行することです。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 );
これはいくつかの発見されたものと私が自分でやったものからフランケンシュタインです。説明するのは非常に難しいですが、一番下の行はこれを実行することです。
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が結合などを作成するために機能します。結合のフィールドの1つで並べ替えるだけです。
さて、カスタム投稿タイプをカテゴリ/分類法でソートした経験を公開したいと思います。
ウェブ
ケース
アーカイブカテゴリリストページでは、クライアントは投稿を次のようにソートすることを望んでいました。
手順
最初に、変更されていないアーカイブページクエリからのリクエストをキャッチします。
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
3番目に、posts_fields、posts_join、posts_orderbyの3つのフィルターを使用して、functions.phpファイルにクエリをフックしました。
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
、post-type WP_Queryでの分類法の使用を許可していません(Ottoによって記述されています)。
解決策:
1)分類法のソートは、現時点ではCustom Taxonomy Order NEプラグインによって最適に実行されます。WYSIWYGを介して分類法を注文することができます。wp-admin
これは、私がそれを行う方法ではありませんが、より良いものは見つかりませんでした。
プラグインをセットアップすると、ここで行ったことに似たものが得られます。オプションに注意してくださいAuto-sort Queries of this Taxonomy
-これをに設定してくださいCustom Order as Defined Above
。これにより、必要な順序を取得できます。スクリーンショット:
2)分類された分類法を使用して、各用語を実行する一連のWP_Query呼び出しを作成し、分類法によって順序付けられたアーカイブを効果的に作成できます。を使用get_terms()
して、すべての税条件の配列を作成し、foreach
各条件に対してa を実行します。これにより、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;
}
このサイトの関連資料: すべての投稿をカスタム分類でグループ化されたカスタム投稿タイプで表示します
ここでのすべてのソリューションがそれをほとんどやりすぎている理由はわかりません。OK、それは半十年前ですが、私は現在次のコードを実行しているだけで、動作します:
<?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の分類法がアルファベット順に分類され、これらの分類グループ内でアルファベット順に分類されます。
この特定の問題に使用した解決策を次に示します。このソリューションは、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.*
andに変更します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' );