如何在短码中按日期过滤查询?

时间:2017-05-08 作者:Johansson

我已经写了一个在过去一周中获取浏览量最大的帖子的短代码。我在shortcode函数中使用了如下过滤器:

function weeks_popular(){
    //Filter the date
    function filter_where($where = \'\') {
        $where .= " AND post_date > \'" . date(\'Y-m-d\', strtotime(\'-7 days\')) . "\'";
        return $where;
    }
    add_filter(\'posts_where\', \'filter_where\');
    $pops = new WP_Query( 
                array( 
                    \'posts_per_page\' => 4,
                    \'meta_key\' => \'views\',
                    \'orderby\' => \'meta_value_num\',
                    \'order\' => \'DESC\' 
                ) 
            );
    //If there is a post, start the loops
    if ($pops->have_posts()) {
        $pops_content=\'<div class="shortcode">\';
        while ($pops->have_posts()){ 
            $pops->the_post(); 
            $pops_content .= \'<a href="\'.get_the_permalink().\'">\'.get_the_title().\'</a>\';
        }
        $pops_content .= \'</div>\';
        return $pops_content;
    } 
    //Remove the date filter
    remove_filter(\'posts_where\', \'filter_where\'); 
    wp_reset_postdata();        
}
add_shortcode( \'recent-posts\', \'weeks_popular\' );
我以前在PHP小部件中使用过它,它工作得很好。现在,它有一个问题:它会影响页面上的所有其他查询,包括其他短代码。

我在查询完成后重置post数据,所以我不知道出了什么问题,因为它过去在PHP小部件中工作(现在仍然工作)。只是在短代码中不起作用。

我错过什么了吗?

3 个回复
最合适的回答,由SO网友:birgire 整理而成

请注意,您从短代码的回调返回时使用的是:

return $pops_content;
在删除筛选器的回调之前,请执行以下操作:

remove_filter(\'posts_where\', \'filter_where\'); 
所以从来没有人打过电话。

那意味着你以后都会受到影响WP_Query 筛选器的实例。

请注意,您可以使用date_query 在里面WP_Query 相反,您不需要posts_where 过滤。

SO网友:Tom J Nowell

订购是这里的问题:

//If there is a post, start the loops
if ($pops->have_posts()) {
    $pops_content=\'<div class="shortcode">\';
    while ($pops->have_posts()){ 
        $pops->the_post(); 
        $pops_content .= \'<a href="\'.get_the_permalink().\'">\'.get_the_title().\'</a>\';
    }
    $pops_content .= \'</div>\';
    return $pops_content;
} 
//Remove the date filter
remove_filter(\'posts_where\', \'filter_where\'); 
wp_reset_postdata();   
你的代码永远不会调用wp_reset_postdata 或移除过滤器,因为它在while

相反,您应该在移除过滤器并重置postdata后,在函数结束时返回。

最后一个音符总是在呼唤wp_reset_postdata 是不明智的。它的目的是清理,但如果您从未设置任何postdata,那么您要重置什么?这可能会导致嵌套循环出现问题,因此始终将调用放在while循环之后的if语句中。

SO网友:Johansson

我通过忘记过滤器并使用日期查询解决了此问题:

$pops = new WP_Query( 
        array( 
            \'posts_per_page\' => 4,
            \'meta_key\' => \'views\',
            \'orderby\' => \'meta_value_num\',
            \'order\' => \'DESC\',
            \'date_query\' => array(
                array(
                    \'year\'  => date(\'Y\'),
                    \'week\' => (date(\'W\')-1),
                ),
            )
        ) 
    );
@birgire和@Tom提供的两个答案都是正确的,并且都有效。然而,我将第一个答案标记为已接受。

结束

相关推荐

Wordpress shortcode Issue!

您好,我开发了一个快捷码,根据分类术语列出自定义帖子类型中的帖子。但我有个问题。它显示来自所有术语的所有帖子,而不是被调用的术语代码如下:function course_listings( $atts ) { // Attributes extract( shortcode_atts( array( \'course_category\' => \'\', ), $atts ) ); // C