WordPress实现文章按最新评论时间排序
"有点蓝" 读者已经不下2次在我的博客里留言想要实现这个功能了,还是满足他的这个愿望吧。WordPress的首页、分类页、标签页等存档页,默认是按照发布时间对文章进行排序的,现在想按最新评论时间排序,其实这个功能就是类似论坛的帖子列表效果,新发布的帖子置顶,有新评论的帖子也同样置顶,这样做的好处是可以增加互动,增加帖子评论数。在WordPress下也是可以实现这样的功能:
- 新发布(新更改)的文章排在顶部
- 有新评论的文章立即排到顶部
- 所有文章按照其最新一条评论的时间排序
实现的方法是给每篇文章添加一个自定义字段_commentTime,这个字段的值为最新一条评论的时间,然后使用query_posts函数实现所有文章按照自定义字段_commentTime的值进行排序。实现原理就这么简单,下面讲讲具体的实现方法:
一、给所有文章添加自定义字段_commentTime
给每篇文章添加这个自定义字段的目的是为了方便对文章进行排序。可能叫你手动一篇一篇文章地添加自定义字段,尤其是你有几百上千篇文章的情况下,一定会是你抓狂。不过请你放心,我不会让你用这么做,这里我写了个PHP脚本,可以帮你自动给所有文章添加字段_commentTime。使用方法:下载以下文件,然后上传到跟wp-config.php相同的目录(就是WordPress的安装目录)下,然后在浏览器中运行这个文件,如 http://WordPress的安装目录地址/meta-sql.php
二、添加相应action代码
这一步添加的代码可以实现发布新文章(或新更改)、有新评论的时候,自动添加/更新自定义字段_commentTime的值,不需要你手动干预。在你当前使用主题的functions.php中添加以下php代码:
/**
* WordPress实现文章按最新评论时间排序,action代码
* 作者:露兜
* 博客:https://www.ludou.org/
* 最后修改:2014年7月16日
*/
function ludou_comment_meta_add($post_ID) {
// 发布新文章或修改文章,更新/添加_commentTime字段值
global $wpdb;
if(!wp_is_post_revision($post_ID)) {
update_post_meta($post_ID, '_commentTime', time());
}
}
function ludou_comment_meta_update($comment_ID) {
// 发布新评论更新_commentTime字段值
$comment = get_comment($comment_ID);
$my_post_id = $comment->comment_post_ID;
update_post_meta($my_post_id, '_commentTime', time());
}
function ludou_comment_meta_delete($post_ID) {
// 删除文章同时删除_commentTime字段
global $wpdb;
if(!wp_is_post_revision($post_ID)) {
delete_post_meta($post_ID, '_commentTime');
}
}
add_action('save_post', 'ludou_comment_meta_add');
add_action('delete_post', 'ludou_comment_meta_delete');
add_action('comment_post', 'ludou_comment_meta_update');
三、query_posts更改文章排序
如果你只想实现首页的文章按最新评论时间排序,那么此步只修改主题目录下的index.php即可,如果还想修改其他存档页面如分类页、标签页等,那就修改相应的模板文件,如archive.php。
举例说明,在index.php中查找代码 if (have_posts())
或 while (have_posts())
,在上一行添加query_posts函数即可:
if(!$wp_query)
global $wp_query;
$args = array(
'meta_key' => '_commentTime',
'orderby' => 'meta_value_num', // WordPress 2.8以上版本
'order' => DESC
);
$args = array_merge( $args, $wp_query->query );
query_posts($args);
对archive.php的修改也一样!如果对query_posts的用法不熟悉,可以看这篇文章: WordPress函数query_posts用法汇总。
数据库清理脚本
如果某一天你不想使用这个功能了,你可以下载以下文件帮助你自动清理数据库中的无用信息,放到WordPress的安装目录下,然后在浏览器中执行一下就可以了,如http://example/meta-clear-sql.php
好了,全部教程到此就结束了,完成以上步骤后就什么都不用管了,文章就是按照最新评论时间进行排序了。如果还有问题请给我留言
-- 完 --
本文采用 「CC BY-NC-SA 4.0」创作共享协议,转载请标注以下信息:
原文出处:露兜即刻 https://www.ludou.org/wordpress-post-orderby-comment-time.html
突然发现可以用你上面的删除commentTime字段内容的sql为所有文章添加一个字段,如何给这个commentTime字段添加一个默认的值呢?格式有要求吗
$insertSQL = 'INSERT INTO ' . $table_prefix . 'postmeta (post_id, meta_key, meta_value) VALUES ';
if($postids) {
do {
$insertSQL .= '(' . $postid['ID'] . ', \'commentTime\', \'-1\'), ';
} while ( $postid = mysql_fetch_assoc($postids) );
// 去除末尾的半角逗号 ,
$insertSQL = substr($insertSQL, 0, strlen($insertSQL)-2);
}
// 给每篇文章添加自定义字段commentTime,值都为-1
mysql_query($insertSQL);
@高高 其中的 -1 就是默认值
@Ludou 好吧,我理解错误,以为上面那是清除字段值的sql,已经试验成功,多谢了
请问博主,我要加字段的话,能不能手动添加,是那张表,字段是int类型还是字符串啊,
@丢丢 文章编辑页面,右上角 显示选项,勾选自定义栏目,此时页面底部出现自定义栏目,可自行添加字段。
@Ludou 谢谢博主,没想到竟然会给我回复,
又遇到一个问题,自己在学写主题,想调用自己的jquery,但是就是不成功,网上各种方法都试过了,还是不起作用,我是中文版的,升级为3.5.2zh之后就不起作用了,不知道为什么,求指教
@丢丢 可在header.php或footer.php中加入你的jquery调用代码,如:
<script src="http://abc/jquery.js"></script>
@Ludou 找到问题了,新建的jquery里面为空,幼稚的错误,还是谢谢博住^_^
请问可以转帖么?我非常喜欢这一篇文章,想放到自己的网站上去,当然会保留出处
@wordpress花园 没意见
來學習一下代碼
其中一个主题,添加到 index.php 无效,并且把主题里面所有包含if (have_posts()) 或 while (have_posts())的上一行都加上了那段代码。还是无效。
另外一个主题,根据我的思路 添加到了,excerpt.php 这里面就生效了,(因为index.php 有 include 'modules/excerpt.php'; 这段代码,所以我找到这个文件 加到这里了就生效了。
但是我想要的是让第一次描述的这个主题生效,但不知道怎么办了。!
ludou 求解?
@啊 可能跟主题的某些代码冲突了
@Ludou 是啊,但你还是能够解决这个问题。O(∩_∩)O谢谢
@Ludou 其实非常希望可以知道 update_post_meta($comment_post_id, 'commentTime', time()); 这段代码表示的意思!和 为什么要放在 ht-posts.php
@啊 更新自定义栏目的值。你的主题写得乱七八糟,评论的ajax处理代码在这个文件中,我也不懂里面的运行机制。
@Ludou 回复的好快啊 -0 –
好像4.1不行了啊
麻烦看看
大哥你好,我用了这段代码很好,但是最近我想在首页循环出的所有文章中去除一个分类目录下的文章,比如去除分类目录ID为1的该分类下的所有文章 我把代码 query_posts($args)改query_posts("cat=-1");),然后确实是把这个分类目录下的文章去除了,但是按照评论最新时间的排序就失效了,想问下大哥看有没有解决的方法呢?谢谢了
@visvis $args = array(
'meta_key' => '_commentTime',
'orderby' => 'meta_value_num', // WordPress 2.8以上版本
'order' => DESC
);
改成
$args = array(
'meta_key' => '_commentTime',
'orderby' => 'meta_value_num', // WordPress 2.8以上版本
'order' => DESC
'cat' =>1
);
@露兜 我昨天自己瞎弄了下,在大哥的代码 if(!$wp_query) 上加了句这个代码<?php query_posts("cat=-1"); ?>就可以了,不知道和大哥提供的有什么区别。
很开心哦,大哥能够回复我!
@visvis 你这种写法会导致代码间相互冲突。query_posts只需传递一次参数即可,你的写法导致query_posts被调用了两次。
cat属于参数之一,上条回复的中的代码是将cat与其他原有的参数整合。
正好需要,感谢提供,带忽而试一试
LZ,怎么查看WordPress的数据库设计?
露兜大哥您好,每次遇到难题都来您的博客查找,受益匪浅。
这次我的需求与您这篇相似,但略有区别,我只想让文章形式为“chat”的文章按照最新评论往前排,其他文章还是按照发布时间排序。
我的大体思路是:
1.先用下面函数把chat单独处理“if( has_post_format( 'chat') ) {}”
2.按照您上面的方法,把chat文章形式的文章最新评论时间储存到_commentTime中
3.然后把_commentTime中的内容用wp_update_post更新到文章发布时间中
也就是通过更新评论时,更新文章发布时间的方式来实现chat形式的文章往前排序的功能。
但是……说了半天,其实我并不会写代码,大神能帮忙看看怎样实现吗?
感激不尽!
大大,我刚刚弄好了 为什么评论文章,不会到第一个来,怎么回事
@小可 可能是旧文章,没有生成自定义栏目_commentTime
@露兜 那怎么解决啊。。求指点
@小可 看看你有没有操作第一步
@露兜 第一步是复制那个文件到网站目录访问meta-sql.php,出现ok,第二部改代码主题的functions.php里面添加你的代码。。。其他的没有做了
@小可 第三步呢?
@露兜 博主,可以帮看看什么问题布
@露兜 第三部我在index.php里面搜索不了 if (have_posts()) 或 while (have_posts()),在上一行添加query_posts代码
@小可 你可以查找:get_template_part,可找到类似代码:<?php get_template_part( 'content', 'page' ); ?>,在content-page.php中的查找if (have_posts())
@露兜 我的git主题没有content-page.php文件,index.php里面没有get_template_part类似的代码,怎么办。
博主大大,为什么我用了不显示,没有效果啊,不会按最新评论排序怎么解决