正如我在评论中所说,这将需要一些工作。简而言之,您将需要以下内容:
获取style
分类学这里我们只需要术语ID
获取当前tax_query
从colour
分类学使用style
分类并创建新的tax_query
从当前页面的术语和从style
分类学
对中的每个术语运行自定义查询style
分类法,从每个术语中获取一个post id数组。您可以在此处添加所有自定义参数。我们将使用此自定义查询中的订单作为后订单
将post ID数组传递给主查询。在这里,您不想添加自定义排序等。我们将使用post id数组中的post id序列进行排序
代码前的几个注意事项:由于使用了短数组语法,代码需要PHP 5.4以上([]
). 您也不应该使用任何早于PHP5的版本。4、如果您这样做了,只需将短数组语法更改为旧数组语法即可(array()
). 例如get_terms( $taxonomy, [\'fields\' => \'ids\'] )
应该成为get_terms( $taxonomy, array( \'fields\' => \'ids\' ) )
我已经建立了一个瞬态系统,以减少我们需要做的所有额外工作带来的额外压力。此瞬态设置为一周后过期,您可以将其调整为更长或更短。当发布、删除、取消删除或更新新帖子时,瞬态将自动删除
我对代码的注释非常好,因此您可以按照我所做的来理解您可以根据需要进行扩展和修改。确保查看我的评论
使用此新代码,您可以放弃我的完整排序思想,如中所述my linked answer on SO. 此答案中给出的代码应负责此排序。您想要进行的任何调整都应该在自定义查询和get_terms
呼叫。只要记住在每次修改后刷新瞬态,或者最好取消对瞬态调用的注释,并在对所有修改满意后恢复正常
代码:一如既往,我们将使用pre_get_posts
根据需要更改主查询
add_action( \'pre_get_posts\', function ( $q )
{
if ( !is_admin() // Targets only front end queries
&& $q->is_main_query() // Targets only main query
&& $q->is_tax( \'colour\' ) // Targets only taxonomy pages
) {
/**
* To save on the extra work that we need to do to get our results,
* lets save everything in a transient. We will save the string of post ids
* in the transient.
*
* We will only delete and recreate this transient when a new post is published,
* deleted, undeleted or updated. This will save us a lot of extra hard work
* on every page load
*
* @link https://codex.wordpress.org/Transients_API
*/
$queried_object = get_queried_object(); // Get the current queried object to build a unique transient name
/**
* Use md5 to build a unique transient name to avoid any conflicts
* The code below will create a unique transient name which will look like this
* "colourtax_1ac37e97ee207e952dfc2b8f7eef110f"
*
* Note, this should NOT be longer that 45 characters else the transient will be regenerated
* on each page load. Transients are expensive to create, so don\'t want to recreate this on every
* page load due to a name being to long. As a quick guide the md5 part generate a 32 character string,
* so the "colourtax_" part should be a maximum of 13 characters
*/
$unique_transient_name = \'colourtax_\' . md5( $queried_object->taxonomy . $queried_object->slug . $queried_object->term_id );
if ( false === ( $post_ids_array = get_transient( $unique_transient_name ) ) ) {
// Gets the current tax_query
$tax_query = $q->tax_query->queries;
// Choose the taxonomy to sort by
$taxonomy = \'style\';
// Set the variable to hold the sorted post ids according to terms
$post_ids_array = [];
/**
* Get all the terms from the selected taxonomy to sort by. Just get term ids
* Add additional arguments here as needed
*
* @link https://codex.wordpress.org/Function_Reference/get_terms
*/
$terms = get_terms( $taxonomy, [\'fields\' => \'ids\'] );
if ( $terms // Check if the array has valid terms, not empty
&& !is_wp_error( $terms ) // Check that we do not have any error
) {
// Define a variable to hold all post ID
$posts_ids = \'\';
foreach ( $terms as $term ) {
/**
* NOTE: You would want to do everything here
*
* Build our query args, add all your relevant arguments here
* You should extend this to include your custom parameter values
* like meta_queries en sorting order.
* Do a var_dump( $wp_query ) and use the relevant arguments from
* there to make this dynamic
*/
$args = [
\'post_type\' => \'any\',
\'posts_per_page\' => 3, // Get only 3 posts per term
\'fields\' => \'ids\', // Only get post ids to make query faster and more lean
// Build a tax_query to add additional terms from selected taxonomy to sort by
\'tax_query\' => [
$tax_query, // Our default tax_query from the taxonomy page
[
\'taxonomy\' => $taxonomy,
\'terms\' => $term,
\'include_children\' => false,
],
],
];
// Return an array of post ids only
$posts_array = get_posts( $args );
// First check if we have posts to avoid bugs in our code
if ( $posts_array ) {
// Break the ids array up into a string for later processing
foreach ( $posts_array as $v )
$posts_ids .= \' \' . $v;
unset( $v );
} //endif $posts_array
} //endforeach $terms
unset( $term );
// ADDITIONAL, CAN DELETE THE FOLLOWING SECTION IF YOU WANT TO. READ COMMENTS BELOW
/**
* You can remove the following section. The idea here is as follow:
* Any post without a term in the style taxonomy will not be displayed on
* a colour taxonomy term page. To avoid this, we will need to get all posts
* that does not have a post in style taxonomy. This posts will be displayed last
* on the page
*
* If you are very sure that all posts are tagged in a colour AND style taxonomy
* term, then you can remove this section, this is really just a fall back
*/
$args_additional = [
\'post_type\' => \'any\',
\'posts_per_page\' => 3, // Get only 3 posts without style taxonomy term, adjust as needed
\'fields\' => \'ids\', // Only get post ids to make query faster and more lean
// Build a tax_query to get posts that is not tagged in style taxonomy
\'tax_query\' => [
$tax_query, // Our default tax_query from the taxonomy page
[
\'taxonomy\' => $taxonomy,
\'terms\' => $terms,
\'include_children\' => false,
\'operator\' => \'NOT IN\', // Posts should not have these terms from style taxonomy
],
],
];
// Return an array of post ids only
$posts_array_2 = get_posts( $args_additional );
// First check if we have posts to avoid bugs in our code
if ( $posts_array_2 ) {
// Break the ids array up into a string for later processing
foreach ( $posts_array_2 as $v )
$posts_ids .= \' \' . $v;
unset( $v );
} //endif $posts_array
// STOP DELETING HERE!!
// Create an array of post ids from the $posts_ids string
$post_ids_array = explode( \' \', ltrim( $posts_ids ) );
} //endif $terms
/**
* Set the transient if it does not exist.
* NOTE: We will choose a week for expiry date, set as needed
*
* @link https://codex.wordpress.org/Transients_API#Using_Time_Constants
*/
set_transient( $unique_transient_name, $post_ids_array, 7 * DAY_IN_SECONDS );
} // endif transient check
/**
* Check if we have an array of post ID\'s before changing anything on the tax page
*
* Here we will alter the main query. You do not want to add or remove anything
* here. Any custom parameters like sorting should be done in the custom queries
* above
*
* DO NOT CHANGE ANYTHING IN THE CODE BELOW EXCEPT posts_per_page
*/
if ( !empty( $post_ids_array ) ) {
$q->set( \'post__in\', $post_ids_array ); // Posts to get as set in our array, max of 3 posts per term
$q->set( \'orderby\', \'post_in\' ); // Sort our posts in the order it is passed in the post__in array
$q->set( \'order\', \'ASC\' );
$q->set( \'posts_per_page\', -1 ); // You can change this, if I remember, you need all posts on one page
}
} //endif conditional checks for query
});
这将处理除发布后刷新、删除等瞬态之外的所有事情以下代码将处理此问题。每当一篇帖子被更新、发布、垃圾或未经处理时transition_post_status
钩子激发,所以我们将使用该逻辑删除所有包含colourtax_
名称
add_action( \'transition_post_status\', function ()
{
global $wpdb;
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient%_colourtax_%\')" );
$wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE (\'_transient_timeout%_colourtax_%\')" );
});