Wordpress wp_query:按 meta_query 键排序,然后按日期排序(固定/置顶)
Wordpress wp_query: Order by meta_query key & then everything else by date (pinned / sticky)
我已经为此绞尽脑汁好几个小时了,现在是时候把它带到 Stack overflow 了。
我知道没有简单的方法可以做到这一点,而且可能根本没有办法做到这一点。
使用 Wordpress,我正在尝试查询 posts,但在保持分页的同时以特定方式对它们进行排序(因为它是通过 AJAX 完成的,所以两个查询解决方案在我的情况 - 据我所知)。
我正在尝试获取 按日期排序 的 post 列表,其中如果 元键 set_as_pinned
设置为 true
return 这总是 post 1,然后其余的可以按日期排序。因此给了我一个"Sticky"壮举。
在尝试了许多不同的解决方案之后,我遇到了以下查询,
$args = array(
'post_type' => $post_type,
'posts_per_page' => $post_type,
'post_status' => 'publish',
'search_prod_title' => $s_query,
'orderby' => array(
'pinned', 'not_pinned'
),
'paged' => $paged,
'tax_query' => $tax_query,
'meta_query' => array(
'relation' => 'or',
'pinned' => array(
'key' => 'set_as_pinned',
'value' => true,
'compare' => '=',
'orderby' => 'date',
'order' => 'DESC'
),
'not_pinned' => array(
'key' => 'set_as_pinned',
'value' => true,
'compare' => '!=',
'orderby' => 'date',
'order' => 'DESC'
),
)
);
目前,所有这些 return 都是我拥有的 1 个固定 post。它缺少 DATE 顺序中的所有其他内容。
我不是通过使用元查询方法而是通过使用 2 个查询设法实现了这一点,我认为这是不可能的。我会尽力为可能遇到相同问题的其他人解释。
此解决方案将帮助人们尝试解决
- AJAX 固定或粘性分页 posts
- 具有自定义 post 类型的置顶帖子
可以在此处找到无评论版本https://github.com/Sandy-Garrido/wordpress-ajax-pagination-sticky-pinned
先决条件 - 设置固定/置顶的元数据
我假设您已经(使用 ACF 或其他方式)设置元数据以检索固定的 posts。在我的示例中,我有一个名为 set_as_pinned
的键的字段类型 Boolean
第 1 步 - 获取您的 pinned/stick posts
$paged = $_POST['pageRequested'];
// declare an empty array for your pinned posts
// (this helps us exclude it from our query when we need to get all the other posts)
$pinned_post_arr = array();
// Define your args for pinned or sticky posts
$pinned_args = array(
'post_type' => 'insight',
'posts_per_page' => -1,
'meta_key' => 'set_as_pinned',
'meta_value' => true
);
// Query list of pinned posts using wp_query or get_posts()
$pinned_posts = new \WP_Query($pinned_args);
while ($pinned_posts->have_posts()){
$pinned_posts->the_post();
//Send this post ID to array so we don't duplicate this in our list
array_push( $pinned_post_arr, get_the_ID());
$Posts = new Posts;
//add each post to the query response data
if($paged == 1){
// DO STUFF WITH YOUR PINNED POSTS HERE.
// Generate HTML or cards, whatever you need
// My use case was to generate HTML and pass it back via AJAX
// this is relative to my project, so copying won't work
query_response['data'] .= $Posts->render_posts();
}
}
wp_reset_postdata(); // ensure you include this line
第 2 步 - 为第二个查询设置变量
(并计算第 2 页及以上页的偏移量)
什么是偏移量?
get_posts()
& wp_query
的论点
offset (int) – number of post to displace or pass over. Warning:
Setting the offset parameter overrides/ignores the paged parameter and
breaks pagination. The 'offset' parameter is ignored when
'posts_per_page'=>-1 (show all posts) is used.
注意 Wordpress 给我们的关于分页和分页问题的警告。
if($paged == 1){
// if the request from the browser ajax request wants page 1,
// we need the second query to return the right amount of posts.
// This is done by deducting the count of our pinned post array
$post_per_page = 10 - count($pinned_post_arr);
$offset = false; // this is not req but I like to add for sanity
} else {
// If the browser did not request page 1 but requested another page.
// We need to counter the pinned posts using an offset.
// This stops page 2 missing items which page 2 thinks is on page 1.
$post_per_page = 10;
// here, we calculate, based on the page we're on and how many pinned posts there were
// the number 10 is my defined posts per page that I personally wanted.
$offset = ((10-count($pinned_post_arr) ) + (10 * ($paged - 2)));
}
第 3 步 - 第二个查询
$args = array(
'post__not_in' => $pinned_post_arr, // required -exclude already pinned posts
'post_type' => $post_type,
'posts_per_page' => $post_per_page, // required
'post_status' => 'publish',
'orderby' => $orderby,
'order' => $order,
'offset' => $offset, // required
'paged' => $paged, // required
'tax_query' => $tax_query,
);
$wp_query = new \WP_Query($args);
// I used a library called SimplePagination
// https://github.com/flaviusmatis/simplePagination.js
// This required me to send back the number of items.
// I can query found posts as an int but I MUST add the count from pinned posts too
$query_response['numOfItems'] = $wp_query->found_posts + count($pinned_post_arr);
$query_response['postsPerPage'] = 10;
// Get all found posts (not including pinned) and add it to the data query
while ($wp_query->have_posts()) {
$wp_query->the_post();
$Posts = new Posts;
// Here I'm appending more to the AJAX response. Which will follow seamlessly from the pinned posts (if any)
$query_response['data'] .= $Posts->render_posts();
}
wp_reset_postdata(); // reset for safe measures
我希望这对你有所帮助,就像对我一样..
我已经为此绞尽脑汁好几个小时了,现在是时候把它带到 Stack overflow 了。
我知道没有简单的方法可以做到这一点,而且可能根本没有办法做到这一点。
使用 Wordpress,我正在尝试查询 posts,但在保持分页的同时以特定方式对它们进行排序(因为它是通过 AJAX 完成的,所以两个查询解决方案在我的情况 - 据我所知)。
我正在尝试获取 按日期排序 的 post 列表,其中如果 元键 set_as_pinned
设置为 true
return 这总是 post 1,然后其余的可以按日期排序。因此给了我一个"Sticky"壮举。
在尝试了许多不同的解决方案之后,我遇到了以下查询,
$args = array(
'post_type' => $post_type,
'posts_per_page' => $post_type,
'post_status' => 'publish',
'search_prod_title' => $s_query,
'orderby' => array(
'pinned', 'not_pinned'
),
'paged' => $paged,
'tax_query' => $tax_query,
'meta_query' => array(
'relation' => 'or',
'pinned' => array(
'key' => 'set_as_pinned',
'value' => true,
'compare' => '=',
'orderby' => 'date',
'order' => 'DESC'
),
'not_pinned' => array(
'key' => 'set_as_pinned',
'value' => true,
'compare' => '!=',
'orderby' => 'date',
'order' => 'DESC'
),
)
);
目前,所有这些 return 都是我拥有的 1 个固定 post。它缺少 DATE 顺序中的所有其他内容。
我不是通过使用元查询方法而是通过使用 2 个查询设法实现了这一点,我认为这是不可能的。我会尽力为可能遇到相同问题的其他人解释。
此解决方案将帮助人们尝试解决
- AJAX 固定或粘性分页 posts
- 具有自定义 post 类型的置顶帖子
可以在此处找到无评论版本https://github.com/Sandy-Garrido/wordpress-ajax-pagination-sticky-pinned
先决条件 - 设置固定/置顶的元数据
我假设您已经(使用 ACF 或其他方式)设置元数据以检索固定的 posts。在我的示例中,我有一个名为 set_as_pinned
第 1 步 - 获取您的 pinned/stick posts
$paged = $_POST['pageRequested'];
// declare an empty array for your pinned posts
// (this helps us exclude it from our query when we need to get all the other posts)
$pinned_post_arr = array();
// Define your args for pinned or sticky posts
$pinned_args = array(
'post_type' => 'insight',
'posts_per_page' => -1,
'meta_key' => 'set_as_pinned',
'meta_value' => true
);
// Query list of pinned posts using wp_query or get_posts()
$pinned_posts = new \WP_Query($pinned_args);
while ($pinned_posts->have_posts()){
$pinned_posts->the_post();
//Send this post ID to array so we don't duplicate this in our list
array_push( $pinned_post_arr, get_the_ID());
$Posts = new Posts;
//add each post to the query response data
if($paged == 1){
// DO STUFF WITH YOUR PINNED POSTS HERE.
// Generate HTML or cards, whatever you need
// My use case was to generate HTML and pass it back via AJAX
// this is relative to my project, so copying won't work
query_response['data'] .= $Posts->render_posts();
}
}
wp_reset_postdata(); // ensure you include this line
第 2 步 - 为第二个查询设置变量
(并计算第 2 页及以上页的偏移量)
什么是偏移量?
get_posts()
& wp_query
offset (int) – number of post to displace or pass over. Warning: Setting the offset parameter overrides/ignores the paged parameter and breaks pagination. The 'offset' parameter is ignored when 'posts_per_page'=>-1 (show all posts) is used.
注意 Wordpress 给我们的关于分页和分页问题的警告。
if($paged == 1){
// if the request from the browser ajax request wants page 1,
// we need the second query to return the right amount of posts.
// This is done by deducting the count of our pinned post array
$post_per_page = 10 - count($pinned_post_arr);
$offset = false; // this is not req but I like to add for sanity
} else {
// If the browser did not request page 1 but requested another page.
// We need to counter the pinned posts using an offset.
// This stops page 2 missing items which page 2 thinks is on page 1.
$post_per_page = 10;
// here, we calculate, based on the page we're on and how many pinned posts there were
// the number 10 is my defined posts per page that I personally wanted.
$offset = ((10-count($pinned_post_arr) ) + (10 * ($paged - 2)));
}
第 3 步 - 第二个查询
$args = array(
'post__not_in' => $pinned_post_arr, // required -exclude already pinned posts
'post_type' => $post_type,
'posts_per_page' => $post_per_page, // required
'post_status' => 'publish',
'orderby' => $orderby,
'order' => $order,
'offset' => $offset, // required
'paged' => $paged, // required
'tax_query' => $tax_query,
);
$wp_query = new \WP_Query($args);
// I used a library called SimplePagination
// https://github.com/flaviusmatis/simplePagination.js
// This required me to send back the number of items.
// I can query found posts as an int but I MUST add the count from pinned posts too
$query_response['numOfItems'] = $wp_query->found_posts + count($pinned_post_arr);
$query_response['postsPerPage'] = 10;
// Get all found posts (not including pinned) and add it to the data query
while ($wp_query->have_posts()) {
$wp_query->the_post();
$Posts = new Posts;
// Here I'm appending more to the AJAX response. Which will follow seamlessly from the pinned posts (if any)
$query_response['data'] .= $Posts->render_posts();
}
wp_reset_postdata(); // reset for safe measures
我希望这对你有所帮助,就像对我一样..