×

WordPress让文章按照自定义字段排序

优畅主题 Wordpress技术 2014-09-20 15:43 2,848 0 条评论

用Meta Query可以实现WordPress文章按照自定义排序,假设安装了WP-PostRatings给文章打分,该插件会把文章平均分存成名叫ratings_average的自定义字段,现在就来按照这个字段排序。

简洁优雅的方法

就是Meta Query,代码放在主题的functions.php里。

function sort_by_ratings( $query ){
    if ( ( $query->is_home() || $query->is_archive() ) && $query->is_main_query() ) {
        $query->set( 'meta_key', 'ratings_average' );
        $query->set( 'orderby', 'meta_value_num');
        $query->set( 'order', 'DESC' );
    }
}
add_action( 'pre_get_posts', 'sort_by_ratings' );

却有个严重的问题

该插件只会给打过分的文章创建ratings_average字段,而Meta Query只会选择带有这个字段的文章,也就是说所有没打过分的文章都会从blog首页和存档页消失。

解决的方法呢,直接点就是给每篇文章都创建这个字段,值为0。

复杂点呢,stackoverflow上有对这个问题的讨论,按照给出的方案改进了一下,找到一个暂时的解决方法如下,思路是直接修改sql语句。

function sort_by_ratings( $query ){
    if ( ( $query->is_home() || $query->is_archive() ) && $query->is_main_query() ) {
        add_filter( 'posts_fields', 'ratings_fields' );
        add_filter( 'posts_join', 'ratings_join' );
        add_filter( 'posts_where', 'ratings_where' );  
        add_filter( 'posts_groupby', 'ratings_group' );
        add_filter( 'posts_orderby', 'ratings_orderby' );
    }
}
add_action( 'pre_get_posts', 'sort_by_ratings' );
function ratings_fields($fields){
    $order_key = "mt1.meta_value";
    return $fields . ",$order_key AS avg";
}
function ratings_join($join){
    global $wpdb;
    $new_join = "
        INNER JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id
        LEFT JOIN $wpdb->postmeta AS mt1 ON ($wpdb->posts.ID = mt1.post_id AND mt1.meta_key = 'ratings_average')
    ";
    return $join . ' ' . $new_join;
}
function ratings_where($where){
    global $wpdb;
    $new_where = "
        AND ($wpdb->postmeta.meta_key = 'ratings_average'
        OR  mt1.post_id IS NULL )";
    return $where . ' ' . $new_where;
}
function ratings_group( $group ){
    global $wpdb;
    return "$wpdb->posts.ID";
}
function ratings_orderby( $orderby ){
    global $wpdb;
    return "ISNULL(avg), avg,$wpdb->posts.post_date ASC";
}

生成的sql语句如下:

SELECT SQL_CALC_FOUND_ROWS wp_posts.*,mt1.meta_value AS avg FROM wp_posts
INNER JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id
LEFT JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id AND mt1.meta_key = 'ratings_average')
WHERE 1=1
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
AND (wp_postmeta.meta_key = 'ratings_average' OR mt1.post_id IS NULL )
GROUP BY wp_posts.ID
ORDER BY ISNULL(avg), avg,wp_posts.post_date ASC LIMIT 0, 10

结果是分数按照从低分到高分排序,即使order by DESC也是升序排列。如果要让高分上前面,只能用点奇怪的方法,比如最大分数是5,把posts_fields改成这样

function ratings_fields($fields){
    // 只能升序排列,所以要降序排列时先做一次运算
    $max_rating = 5;
    $order_key = "$max_rating - mt1.meta_value";
    return $fields . ",$order_key AS avg";
}

如果还有更简单的方法,欢迎留言指教。


如果本文对你有帮助,你可以扫描右边的二维码打赏,谢谢支持
联系优畅:uctheme#qq.com (#改为@)
微信订阅号:优畅主题(uctheme)
官网淘宝店:http://uctheme.taobao.com
版权声明:版权归 优畅主题 所有,转载请注明出处!
转载请保留链接: https://www.uctheme.com/technical/913.html
谢谢支付宝打赏
谢谢微信打赏

品牌创立:2012-11-18优畅主题

优畅主题成立于2012年11月18日,专业Wordpress导购主题开发商,拥有多年Wordpress主题设计经验,专门为淘宝客和导购客站长量身打造高端赚钱模板,我们注重细节,有着严谨的开发态度,一切从客户角度出发,如果你也喜欢 WordPress导购主题,欢迎和我们一起交流!


5 + 2 = ?

目前还没有评。

切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

切换登录

注册