不知道大家有没有这样一种情况,突然间看到一句话,说的很好,就想记录下来,又或者是当下的一些心情/知识碎片...,然因其文字长度不足已形成一篇文章,那么用类似微博,QQ空间的说说这样的形式去记录反而会更好点,所以就有了做这么一个页面的需求。
可以说,网上关于WordPress做类似说说页面的教程是非常多,但是符合自己想法的却非常少,所以只好自己动手丰衣足食了。
赶紧先放个成品的说说页面链接,点我查看。
目前我的想法和设计如下:
1、类似QQ空间的说说可以评论和回复
2、说说页面的数量可以分页显示(根据WordPress后台设置的显示),并可以实现无刷新式查看
3、说说页面并不需要像文章那样需要填写标题,关于这点,我看了下网上绝大多数的说说页面的实现方案,大多数是通过修改文章形式来判断是不是说说页面,显然这不符合我的需求,所以最后我采用了直接在页面上评论其实就是相当于每条说说了(这样我就可以直接复制自己主题相关的评论代码,省事啊,然,还是遇到了很多坑啊,后面会说)。
如果是以评论的形式来展示说说页面的话:
①那么其实可以省略掉每条评论的第一个评论的头像,这样也减少了服务器的带宽使用啊(这个理由占比大),可能描述的不太好,有兴趣的盆友,直接看案例吧。
②可以读取自定义文章页的评论做为说说页面展示。
应该就这么多的idea吧,那么先看下,如果要实现这个功能,WordPress中需要用到的方法有哪些?下面列举两个主要会用到的吧,因为实际情况下,用的方法还是非常多的。
comments_template:用来构造评论模板的,正常情况下这个方法基本能满足大部分的需求了(它的第一个参数传入的是一个自定义评论模板的路径,这也是为啥我说能满足的原因了),然而因为新建的说说页面已经创建了一个文件,我并不希望再创建一个评论模板的文件(强迫在作祟),这样其实是不太方便我管理啊,就把所有的代码集中到一个文件就可以了,方便维护和管理,就因为这样,我入坑了好久才搞明白怎么实现一个读取自定义的评论,然后又能保证相关的评论方法可以用。
wp_list_comments:获取评论的列表数据
那么就正常开始制作一个说说页面了,步骤如下;
1、在自己主题的根目录下新建一个文件,名称为【template-shuoshuo.php】,然后复制如下的说说页面完整代码到新建文件里面去就可以了(一定要注意了,照搬的话,大概率是会有问题,因为每个主题的评论结构是不一样的,特别是异步获取评论数据这部分的js我是根据我主题的HTML结构去写的,所以大家如果会改的话,一定要修改对应的部分,我也会写上注释吧。)
<?php
/*
Template Name: 说说
*/
?>
<?php get_header(); ?>
<?php
/**
* 其实这步就是照搬了内置的comments_template方法里面的代码
* 然后做了些许了修改,实现了读取自定义的文章评论数据
*/
function init_comments_info($separate_comments = false)
{
global $wp_query, $post, $user_ID, $overridden_cpage, $custom_post_id;
/*
* Comment author information fetched from the comment cookies.
*/
$commenter = wp_get_current_commenter();
/*
* The name of the current comment author escaped for use in attributes.
* Escaped by sanitize_comment_cookies().
*/
$comment_author = $commenter['comment_author'];
/*
* The email address of the current comment author escaped for use in attributes.
* Escaped by sanitize_comment_cookies().
*/
$comment_author_email = $commenter['comment_author_email'];
/*
* The url of the current comment author escaped for use in attributes.
*/
$comment_author_url = esc_url($commenter['comment_author_url']);
$comment_args = array(
'orderby' => 'comment_date_gmt',
'order' => 'ASC',
'status' => 'approve',
'post_id' => $custom_post_id,
'no_found_rows' => false,
'update_comment_meta_cache' => false, // We lazy-load comment meta for performance.
);
if (get_option('thread_comments')) {
$comment_args['hierarchical'] = 'threaded';
} else {
$comment_args['hierarchical'] = false;
}
if ($user_ID) {
$comment_args['include_unapproved'] = array($user_ID);
} elseif (!empty($comment_author_email)) {
$comment_args['include_unapproved'] = array($comment_author_email);
}
$per_page = 0;
if (get_option('page_comments')) {
$per_page = (int) get_query_var('comments_per_page');
if (0 === $per_page) {
$per_page = (int) get_option('comments_per_page');
}
$comment_args['number'] = $per_page;
$page = (int) get_query_var('cpage');
if ($page) {
$comment_args['offset'] = ($page - 1) * $per_page;
} elseif ('oldest' === get_option('default_comments_page')) {
$comment_args['offset'] = 0;
} else {
// If fetching the first page of 'newest', we need a top-level comment count.
$top_level_query = new WP_Comment_Query();
$top_level_args = array(
'count' => true,
'orderby' => false,
'post_id' => $custom_post_id,
'status' => 'approve',
);
if ($comment_args['hierarchical']) {
$top_level_args['parent'] = 0;
}
if (isset($comment_args['include_unapproved'])) {
$top_level_args['include_unapproved'] = $comment_args['include_unapproved'];
}
$top_level_count = $top_level_query->query($top_level_args);
$comment_args['offset'] = (ceil($top_level_count / $per_page) - 1) * $per_page;
}
}
/**
* Filters the arguments used to query comments in comments_template().
*
* @since 4.5.0
*
* @see WP_Comment_Query::__construct()
*
* @param array $comment_args {
* Array of WP_Comment_Query arguments.
*
* @type string|array $orderby Field(s) to order by.
* @type string $order Order of results. Accepts 'ASC' or 'DESC'.
* @type string $status Comment status.
* @type array $include_unapproved Array of IDs or email addresses whose unapproved comments
* will be included in results.
* @type int $post_id ID of the post.
* @type bool $no_found_rows Whether to refrain from querying for found rows.
* @type bool $update_comment_meta_cache Whether to prime cache for comment meta.
* @type bool|string $hierarchical Whether to query for comments hierarchically.
* @type int $offset Comment offset.
* @type int $number Number of comments to fetch.
* }
*/
$comment_args = apply_filters('comments_template_query_args', $comment_args);
$comment_query = new WP_Comment_Query($comment_args);
$_comments = $comment_query->comments;
// Trees must be flattened before they're passed to the walker.
if ($comment_args['hierarchical']) {
$comments_flat = array();
foreach ($_comments as $_comment) {
$comments_flat[] = $_comment;
$comment_children = $_comment->get_children(array(
'format' => 'flat',
'status' => $comment_args['status'],
'orderby' => $comment_args['orderby']
));
foreach ($comment_children as $comment_child) {
$comments_flat[] = $comment_child;
}
}
} else {
$comments_flat = $_comments;
}
/**
* Filters the comments array.
*
* @since 2.1.0
*
* @param array $comments Array of comments supplied to the comments template.
* @param int $post_ID Post ID.
*/
$wp_query->comments = apply_filters('comments_array', $comments_flat, $custom_post_id);
$comments = &$wp_query->comments;
$wp_query->comment_count = count($wp_query->comments);
$wp_query->max_num_comment_pages = $comment_query->max_num_pages;
if ($separate_comments) {
$wp_query->comments_by_type = separate_comments($comments);
$comments_by_type = &$wp_query->comments_by_type;
} else {
$wp_query->comments_by_type = array();
}
$overridden_cpage = false;
if ('' == get_query_var('cpage') && $wp_query->max_num_comment_pages > 1) {
set_query_var('cpage', 'newest' == get_option('default_comments_page') ? get_comment_pages_count() : 1);
$overridden_cpage = true;
}
}
//自定义获取评论的id,默认取得是当前模板页的id
$custom_post_id = get_the_ID();
init_comments_info();
/**
* 说说(评论)列表的展示
*/
function shuoshuo_comment($comment, $args, $depth)
{
$GLOBALS['comment'] = $comment;
extract($args, EXTR_SKIP);
if ('div' == $args['style']) {
$tag = 'div';
$add_below = 'comment';
} else {
$tag = 'li class="nana"';
$add_below = 'div-comment';
}
?>
<<?php echo $tag; ?> <?php comment_class(empty($args['has_children']) ? '' : 'parent') ?> id="comment-<?php comment_ID() ?>">
<?php if ('div' != $args['style']) : ?>
<div id="div-comment-<?php comment_ID() ?>" class="comment-body">
<?php endif; ?>
<?php
if ($comment->comment_parent > 0) {
echo my_avatar($comment->comment_author_email, 50, $default = '', $comment->comment_author);
}
?>
<div class="comment-author">
<?php if ($comment->comment_parent > 0) { ?>
<strong><span class="duzhe"><?php commentauthor(); ?></span></strong>
<span class="reply_tz">
<?php if (!get_option('ygj_pldj')) { ?>
<?php get_author_class($comment->comment_author_email, $comment->user_id); ?>
<?php if (user_can($comment->user_id, 'administrator')) {
echo '<span class="dengji">【' . stripslashes(get_option('ygj_adminch')) . '】</span>';
} ?>
<?php } ?>
<?php printf(__('%1$s %2$s', 'Nana'), get_comment_date('Y-m-d'), get_comment_time('H:i')); ?>
<?php comment_reply_link(array_merge($args, array('reply_text' => ' <i class="fa fa-reply"></i> 回复', 'add_below' => $add_below, 'depth' => $depth, 'max_depth' => 10000))); ?>
</span>
<?php } else { ?>
<strong>
<span class="duzhe"><?php commentauthor(); ?></span>
<?php if (!get_option('ygj_pldj')) { ?>
<?php get_author_class($comment->comment_author_email, $comment->user_id); ?>
<?php if (user_can($comment->user_id, 'administrator')) {
echo '<span class="dengji">【' . stripslashes(get_option('ygj_adminch')) . '】</span>';
} ?>
<?php } ?>
</strong>
<span class="reply_t">
<?php comment_reply_link(array_merge($args, array('reply_text' => ' @回复', 'add_below' => $add_below, 'depth' => $depth, 'max_depth' => 10000))); ?></span>
<br />
<span class="comment-meta commentmetadata">
<span class="comment-aux">
<?php
echo '<span class="xiaoshi">发表于</span>';
printf(__('%1$s %2$s', 'Nana'), get_comment_date('Y-m-d'), get_comment_time('H:i'));
?>
<?php
if (is_user_logged_in()) {
$url = home_url();
echo '<a id="delete-' . $comment->comment_ID . '" href="' . wp_nonce_url("$url/wp-admin/comment.php?action=deletecomment&p=" . $comment->comment_post_ID . '&c=' . $comment->comment_ID, 'delete-comment_' . $comment->comment_ID) . '" > 删除</a>';
}
?>
<?php edit_comment_link('编辑', ' ', ''); ?>
</span>
</span>
<?php } ?>
</div>
<?php comment_text(); ?>
<?php if ($comment->comment_approved == '0') : ?>
<div class="comment-awaiting-moderation" style="color:red">您的评论正在等待审核!</div>
<?php endif; ?>
<?php if ('div' != $args['style']) : ?>
</div>
<?php endif; ?>
<?php
}
?>
<style>
.author_avatar img.avatar {
overflow: hidden;
}
ol.comment-list {
padding: 0;
background: none;
list-style: none;
}
.comment-list .children li,
.comment-list .children .children li {
margin-left: 10px;
margin-bottom: 0 !important;
border-top: 1px solid #eee;
}
ol.comment-list li.nana {
background: #fff;
padding: 0 20px;
margin: 0;
margin-bottom: 10px;
}
@media screen and (max-width: 767px) {
.comment-list .children li,
.comment-list .children .children li {
margin-left: 0;
padding: 0;
}
}
ol.comment-list li.nana .comment-body {
border: none;
}
.comment-list>li.nana>.comment-body>p {
padding-left: 0;
}
.comment-loading {
display: none;
text-align: center;
color: dodgerblue;
margin-bottom: 10px;
}
</style>
<div id="content" class="site-content">
<div id="comments" class="comments-area">
<?php if (!comments_open()) : ?>
<p class="no-comments">评论已关闭!</p>
<?php else : ?>
<div id="respond" class="comment-respond">
<h3 id="reply-title" class="comment-reply-title">发表评论
<small><?php cancel_comment_reply_link('取消回复'); ?></small>
</h3>
<?php if (get_option('comment_registration') && !$user_ID) : ?>
<p><?php print '您必须'; ?><a href="<?php echo get_option('siteurl'); ?>/wp-login.php?redirect_to=<?php echo urlencode(get_permalink()); ?>"> 登录 </a>才能发表留言!</p>
<?php else : ?>
<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
<?php if ($user_ID) : ?>
<div class="user_avatar">
<?php
$current_user = wp_get_current_user();
echo my_avatar($current_user->user_email, 40, $default = '', $current_user->display_name); ?>登录者:<a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>
<a href="<?php echo wp_logout_url(get_permalink()); ?>" title="退出"><?php print ' 退出'; ?></a>
</div>
<?php elseif ('' != $comment_author) : ?>
<div class="author_avatar">
<?php echo my_avatar($comment_author_email, 40, $default = '', $comment->comment_author); ?>
<?php printf('欢迎 <b>%s</b>', $comment_author); ?> 再次光临【<b><a href="javascript:toggleCommentAuthorInfo();" id="toggle-comment-author-info">修改信息</a></b>】
</div>
<?php endif; ?>
<?php if (!$user_ID) : ?>
<div id="comment-author-info">
<p class="comment-form-author">
<input type="text" name="author" id="author" class="commenttext" value="<?php echo $comment_author; ?>" tabindex="1" />
<label for="author">昵称<?php if ($req) echo "(必填)"; ?></label>
</p>
<p class="comment-form-email">
<input type="text" name="email" id="email" class="commenttext" value="<?php echo $comment_author_email; ?>" tabindex="2" />
<label for="email">邮箱<?php if ($req) echo "(必填)"; ?></label>
</p>
<p class="comment-form-url">
<input type="text" name="url" id="url" class="commenttext" value="<?php echo $comment_author_url; ?>" tabindex="3" />
<label for="url">网址</label>
</p>
</div>
<?php endif; ?>
<p class="smiley-box"></p>
<p class="comment-form-comment"><textarea id="comment" name="comment" rows="4" tabindex="4"></textarea></p>
<p class="comment-tool"></p>
<p class="form-submit">
<input id="submit" name="submit" type="submit" tabindex="5" value="提交评论">
<?php comment_id_fields();
do_action('comment_form', $post->ID); ?>
</p>
</form>
<script type="text/javascript">
document.getElementById("comment").onkeydown = function(moz_ev) {
var ev = null;
if (window.event) {
ev = window.event;
} else {
ev = moz_ev;
}
if (ev != null && ev.ctrlKey && ev.keyCode == 13) {
document.getElementById("submit").click();
}
}
</script>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="comment-loading"><i class="fa fa-spinner fa-spin"></i>加载中,请稍候...</div>
<?php if (have_comments()) : ?>
<ol class="comment-list">
<?php wp_list_comments('type=comment&callback=shuoshuo_comment'); ?>
</ol><!-- .comment-list -->
<?php endif; // have_comments()
?>
</div>
<?php if (get_comment_pages_count() > 1 && get_option('page_comments')) : ?>
<nav id="comment-navigation">
<div class="pagination"><?php paginate_comments_links('prev_text=<i class="fa fa-angle-left"></i>&next_text=<i class="fa fa-angle-right"></i>'); ?></div>
</nav>
<div class="clear"></div>
<?php endif; // Check for comment navigation.
?>
</div>
<script>
//这块一定要记得修改,根据自己主题的HTML结构,可参考:https://zhang.ge/5012.html
(() => {
$('#content').on('click', '#comment-navigation .page-numbers', (e) => {
e.preventDefault();
let url = $(e.currentTarget).attr('href');
//点击当前分页页码也可以刷新评论
if (url === undefined) {
// 这里原本是打算拼接地址栏来构造评论页的地址,但是考虑到地址栏有可能存在一些异常的参数还要做过滤
// 索性换了个思路拿已经存在DOM中的评论页的地址,这样就可以确保评论页的地址一定正确,而我只要替换其中的页码即可
let commentHref = $(e.currentTarget).siblings("a.page-numbers[href*='comment-page-']").attr('href');
url = commentHref.replace(/comment-page-\d+/g, `comment-page-${$(e.currentTarget).html()}`);
}
$.ajax({
type: "GET",
url,
beforeSend() {
//取消回复(我看了下网上大部分异步获取评论代码,都漏了这个bug)
$('#cancel-comment-reply-link').click();
//移除评论列表
$('#comments > ol.comment-list').remove();
//移除评论分页
$('nav#comment-navigation > .pagination').remove();
$('#comments > .comment-loading').slideDown();
},
dataType: "html",
success(res) {
let commentlist = $(res).find('ol.comment-list');
let commentnavigation = $(res).find('nav#comment-navigation > .pagination');
$('#comments > .comment-loading').slideUp('fast');
$('#comments').append(commentlist);
$('nav#comment-navigation').append(commentnavigation);
},
error() {
alert("评论加载失败,请尝试刷新下页面。");
}
});
});
})()
</script>
<?php get_footer(); ?>
2、登录到网站后台——页面——新建页面——模块——选择【说说】
相关问题
折腾这个说说页面功能的时候,遇到的问题,我都做了相应的记录,有兴趣的可以查看。
WordPress更新到5.5+部分主题的评论楼层数为0/不显示的解决方法
升级高版本的WordPress(5.1+)后评论回复不自动跟随了怎么办?
其实折腾完这个说说页面后,我愈发的想做个自己的主题(爱咋写就咋写,多香呢),且最近的念头也越来越大,因为我深刻的感受到改别人的代码是有多痛苦,维护成本实在高,我还看了下在写这个说说页面的时候还顺带修复了不少主题遗留的历史bug。