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

用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";
}

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

时间: 2024-09-28 16:53:06

WordPress实现文章按照自定义字段排序的相关文章

wordpress文章按日期字段排序修改

按日期排序 首先打开首页 index.php 文件,找如类似于 if (have_posts()) 这样的循环,然后修改成如下的代码: <?php // query_posts函数 query_posts('orderby=comment_count'); //以评论最多到最少的排序方式 //主循环 if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> 查找: <?php endwhile; ?> 修改成: &l

WordPress发布文章/页面时自动添加默认的自定义字段

如果你每篇文章或页面都需要插入同一个自定义字段和值,可以考虑在WordPress发布文章/页面时,自动添加默认的自定义字段.将下面的代码添加到当前主题的 functions.php 即可: 1 2 3 4 5 6 7 8 9 10 11 12 /** * WordPress发布文章/页面时自动添加默认的自定义字段 * https://www.wpdaxue.com/add-custom-field-automatically-post-page-publish.html */ add_actio

wordpress自定义字段实现商务网站价格列表功能

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 WordPress允许日志撰写者为日志分派自定义字段.通过自定义字段,我们可以很容易就给日志或者页面增加额外的内容,并且还能很快的改变信息显示方式. 在正式学习之前我们先来了解一下自定义字段的数据库结构,为后面的学习打下基础. 首先,我们打开phpmyadmin,其实自定义字段是存放在wp_postmeta 这个表里面,这个表的结构是非常简单

WordPress分类目录和标签添加新的自定义字段教程

WordPress的分类目录默认只有名称.别名.父节点和描述这几个字段,有时候我们需要给分类目录拓展一些信息,如想添加一个分类封面图.给分类指定keywords和description等等,这个时候我们就得给分类目录添加自定义字段(或者叫自定义栏目).本文将给你介绍如何给WordPress的分类目录和标签添加新的自定义字段. 下图是WordPress后台的分类目录编辑页面,有心的读者可能注意到,这里多了个分类封面的输入框,这个就是我们所说的给分类目录添加的自定义字段. 插件实现 本文介绍的重点不

让WordPress搜索结果包括自定义文章类型的内容

如果你的WordPress站点添加了自定义文章类型,请记得让WordPress默认搜索支持自定义文章类型,即可以搜索自定义文章类型的内容.实现的方法很简单,将下面的代码添加到主题的functions.php 文件中即可: 让搜索支持自定义文章类型  代码如下 复制代码 function searchAll( $query ) {   if ( $query->is_search ) { $query->set( 'post_type', array( 'post','books', 'prod

phpcms推荐位无法调用自定义字段

  默认phpcms是无法使用推荐位调用自定义字段的,直接写{pc:content action="position" posid="30" catid="24" order="listorder DESC" num="4"}的话不会出错,但就是无法调用数据,显示的是空白. 调用代码 01.{pc:content action="position" posid="30"

WordPress发布文章即时推送到百度,加快百度收录

一.主动推送 先来看下百度对于主动推送的一些说明:     主动推送:最为快速的提交方式,建议您将站点当天新产出链接立即通过此方式推送给百度,以保证新链接可以及时被百度收录.     主动推送支持多种途径:比如curl .post.php以及ruby等.而且支持一次性提交多条网站页面地址,不过每个站点每天可推送的次数暂时限制在50次.    使用主动推送功能会达到怎样效果?    ①.及时发现:可以缩短百度爬虫发现您站点新链接的时间,使新发布的页面可以在第一时间被百度收录    ②.保护原创:对

java中List按照指定字段排序工具类

文章标题:java中List按照指定字段排序工具类. 文章地址: http://blog.csdn.net/5iasp/article/details/17717179   包括如下几个类   1. 实体类   package com.newyear.wish; /** * 实体类 * */ public class Video { public Video(int id, String title, int hits) { super(); this.id = id; this.title =

js表格字段排序的实例代码介绍

 本篇文章只要是对js表格字段排序的实例代码进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助 1.比较函数生成器:    代码如下: /**  * 比较函数生成器  *   * @param iCol  *            数据行数  * @param sDataType  *            该行的数据类型  * @return  */ function  generateCompareTRs(iCol, sDataType) {      return   functio