php - wp_query中的随机顺序与分页
问题描述
我有一个查询一些自定义帖子的简码,还添加了分页。一切正常,但我想随机化顺序。但是,当我在 args 中将 order 设置为“rand”时,我的分页中的每一页都是完全随机的——这意味着,同一个帖子可以在不同的页面上出现多次。我怎样才能随机化我所有帖子的顺序,而不是在每页级别?这是我的代码:
function slaProductsArchive( $atts ){
global $paged;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$numposts = intval($atts['num']);
$cat = $atts['cat'];
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => $numposts,
'orderby' => 'rand',
'product-category' => $cat,
'paged' => $paged,
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
// Display my posts
endwhile;
$output .= '</div>';
$output .= '<div class="slaPagination"><span class="prev-posts-links">' . get_previous_posts_link('<i class="fas fa-arrow-left"></i> Previous') . '</span> ';
$output .= '<span class="next-posts-links">' . get_next_posts_link('Next <i class="fas fa-arrow-right"></i>', $loop->max_num_pages) . '</span></div>';
wp_reset_postdata();
return $output;
}
add_shortcode('slaProductsArchive', 'slaProductsArchive');
解决方案
为此,我使用了 WC-Session,因为您使用的是产品,我假设您使用的是 WooCommerce。每个页面都存储在一个会话变量中,所以如果你回到上一个页面,它和以前一样。它还编写了一个单独的帖子数组,以便您可以使用post__not_in
.
因此,虽然这会生成随机顺序,但一旦创建了页面,它就是刷新时的顺序。
我还更新了您的使用情况,shortcode_atts
并提出了一个条件,以防没有设置产品类别。
function slaProductsArchive( $atts ){
$atts = shortcode_atts(
array(
'num' => 10,
'cat' => ''
),
$atts, 'slaProductsArchive' );
// Retrieve Previous WC Session Vars
$done = WC()->session->get('viewed_randoms', array());
$my_page = WC()->session->get('my_page', array());
global $paged;
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
if (!array_key_exists($paged, $my_page)) {
if ( !empty( $atts['cat'] ) ) {
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => absint( $atts['num'] ),
'orderby' => 'rand',
'paged' => $paged,
'product_cat' => $atts['cat'],
'post__not_in' => $done
);
} else {
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => absint( $atts['num'] ),
'orderby' => 'rand',
'paged' => $paged,
'post__not_in' => $done
);
}
} else {
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'post__in' => $my_page[$paged]
);
}
// Initialize $output ** This wasn't here before **
$output = '<div>';
// A variable to store the POST ID's of this loop
$this_loop = array();
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
// just to show something from the loop
// You can remove this and put your own loop here
$output .= '<p>' . get_the_title() . ' ' . get_the_ID(). '</p>';
// Set two array of the POST ID's
$done[] = get_the_ID();
$this_loop[] = get_the_ID();
endwhile;
$output .= '</div>';
$output .= '<div class="slaPagination"><span class="prev-posts-links">' . get_previous_posts_link( '<i class="fas fa-arrow-left"></i> Previous' ) . '</span> ';
$output .= '<span class="next-posts-links">' . get_next_posts_link( 'Next <i class="fas fa-arrow-right"></i>', $loop->max_num_pages ) . '</span></div>';
// Set My Page Key = Page Number - Value = each post ID
$my_page[$paged] = $this_loop;
// Store WC Session Var
WC()->session->set('viewed_randoms', $done);
WC()->session->set('my_page', $my_page);
wp_reset_postdata();
return $output;
}
add_shortcode( 'slaProductsArchive', 'slaProductsArchive' );
没有 WooCommerce 的替代方法
在这个方法中,我初始化了一个 PHP 会话,并使用会话 ID 的 cookie 来存储一个瞬态,因为所有其余的都是在发送标头之后完成的。因此会话仅用于会话 ID。您也可以简单地设置一个具有您想要的任何名称的 cookie,并将其用于组成的会话,纯粹用于将瞬态用作此会话。
function dd_register_session(){
if(!session_id() && !headers_sent()) {
session_start();
session_write_close();
}
}
add_action('init','dd_register_session', 1);
add_action('wp_logout', 'end_session');
add_action('wp_login', 'end_session');
add_action('end_session_action', 'end_session');
function end_session() {
session_destroy ();
}
function slaProductsArchive( $atts ){
$atts = shortcode_atts(
array(
'num' => 10,
'cat' => ''
),
$atts, 'slaProductsArchive' );
// Retrieve Previous Session Data
$done = $my_page = array();
if (isset($_COOKIE['PHPSESSID'])) {
if ( false !== ( $session_data = get_transient( $_COOKIE['PHPSESSID'] ) ) ) {
$done = $session_data['done'];
$my_page = $session_data['my_page'];
}
}
global $paged;
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
if (!array_key_exists($paged, $my_page)) {
if ( !empty( $atts['cat'] ) ) {
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => absint( $atts['num'] ),
'orderby' => 'rand',
'paged' => $paged,
'product_cat' => $atts['cat'],
'post__not_in' => $done
);
} else {
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => absint( $atts['num'] ),
'orderby' => 'rand',
'paged' => $paged,
'post__not_in' => $done
);
}
} else {
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'post__in' => $my_page[$paged],
'orderby' => 'post__in'
);
}
// Initialize $output ** This wasn't here before **
$output = '<div>';
// A variable to store the POST ID's of this loop
$this_loop = array();
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
// just to show something from the loop
// You can remove this and put your own loop here
$output .= '<p>' . get_the_title() . ' ' . get_the_ID(). '</p>';
// Set two array of the POST ID's
$done[] = get_the_ID();
$this_loop[] = get_the_ID();
endwhile;
$output .= '</div>';
$output .= '<div class="slaPagination"><span class="prev-posts-links">' . get_previous_posts_link( '<i class="fas fa-arrow-left"></i> Previous' ) . '</span> ';
$output .= '<span class="next-posts-links">' . get_next_posts_link( 'Next <i class="fas fa-arrow-right"></i>', $loop->max_num_pages ) . '</span></div>';
// Set My Page Key = Page Number - Value = each post ID
$my_page[$paged] = $this_loop;
if (isset($_COOKIE['PHPSESSID'])) {
set_transient( $_COOKIE['PHPSESSID'] , array('done' => $done, 'my_page' => $my_page), 10 * MINUTE_IN_SECONDS );
}
wp_reset_postdata();
return $output;
}
add_shortcode( 'slaProductsArchive', 'slaProductsArchive' );
推荐阅读
- python - 从 Python 中的目录转换所有文件(.jpg 到 .png)
- firebase - 为什么“无法再从 http 页面调用方法 FB.login。” 是否出现在我的 Ionic4 应用程序中?
- java - 我们可以动态添加带有 setter 和 getter 的类属性吗
- haskell - Haskell:理解绑定和 >> 函数
- python - 编解码器无法解码字节 0x81
- python-3.x - 在一列上使用 groupby 并从具有相同属性的两个不同列中获取唯一值或计数
- reactjs - React-native:向所有通过 react-navigation 和 redux 创建的屏幕添加一个组件
- jquery - 在悬停时制作一个 Bootstrap 4 卡片翻转
- java - Maven 依赖项升级后 Jenkins 构建失败
- python - 如何通过熊猫中给定的填充值更新小数点前后的字符串格式