以前写过一个关于自定义评论的文章,时至如今来看,还是有很多不足的,昨晚再新写主题的时候,也重新写了一次自定义评论,嗯,有了新的理解,因为其实真的很简单,仔细阅读本篇文章,相信你会有收获的。
自定义评论模板到底要怎么做
很简单,可以理解为两步:
- 编写自定义评论的模板
- 通过php渲染出自定义模板评论
而为什么大多数人不会,其实就是因为官方的文档真的是,如果懂php的人,可能看了一两遍后明白了怎么回事,但是如果是小白入门,纯前端的童鞋,可能看的一脸蒙蔽。
就算是原封不动的copy官方的示例代码也还是会报错,心累...
因为,你不知道他要做什么,我编写了自定义模板函数threadedComments
;然后呢???
然而官方啥也没说。(当然,我不能保证这篇教程的绝对正确,但是从我的理解和使用上,还是可以正常运作的)
自定义评论模板的编写
我们可以创建一个用于存放模板的php文件,比如list-template.php
模板本身其实就是一个php的函数,不管那些if啥的代码,其实他就是一个空架子
<?php function threadedComments($comments, $options) { ?>
...自定义评论模板具体的html内容
<?php } ?>
那么官方文档中开头那部分$commentClass
是做什么的,其实是一个用于设置class的php变量,这个变量需要判断这条评论是文章作者的,还是其他人评论的,然后$commentLevelClass
则是用来判断,这条评论是主评论还是子评论。
事实上官方在 具体的html内容部分又if判断了一次,这条评论是主评论还是子评论,所以,$commentLevelClass
这段我们可以删掉,并不会影响后面的内容,当然,待会我会仔细讲讲这段代码怎么用,因为官方写错啦!
$commentClass
那么,$commentClass
我们是需要的,如果你的html样式里面不需要判断这条评论是作者的还是其他人的,那么这块代码,包括$commentClass
变量,我们可以去除。
$commentClass = '';
if ($comments->authorId) {
if ($comments->authorId == $comments->ownerId) {
$commentClass .= ' comment-by-author'; //如果是文章作者的评论添加 .comment-by-author 样式
} else {
$commentClass .= ' comment-by-user'; //如果是评论作者的添加 .comment-by-user 样式
}
}
$commentLevelClass
$commentLevelClass = $comments->_levels > 0 ? ' comment-child' : ' comment-parent'; //评论层数大于0为子级,否则是父级
再官方的文档中,可以看到开头这么一段代码,咋一看好像没啥问题,但是他在后面的li元素那,也有一个判断:
<li id="li-<?php $comments->theId(); ?>" class="comment-body<?php
if ($comments->levels > 0) {
echo ' comment-child';
$comments->levelsAlt(' comment-level-odd', ' comment-level-even');
} else {
echo ' comment-parent';
}
$comments->alt(' comment-odd', ' comment-even');
echo $commentClass;
?>">
仔细看,是不是似曾相识:levels
、comment-child
、comment-parent
、> 0
、
这不就是一样的意思吗???为什么要写两遍,所以,我们可以二选一,可以保留li的if判断,删除上面的$commentLevelClass
;
也可以保留$commentLevelClass,删除li里面的if判断。但是,如果你要保留$commentLevelClass的话,那么需要把_levels
改为levels
代码才能正常运行。
而li这边则需要改成:
<li id="li-<?php $comments->theId(); ?>" class="comment-body<?php echo $commentLevelClass;?> <?php if ($comments->levels > 0) { $comments->levelsAlt(' comment-level-odd', ' comment-level-even'); }; $comments->alt(' comment-odd', ' comment-even');?>">
是不是感觉有点麻烦,其实还可以拆分:
<?php echo $commentLevelClass;?>
这句就不多说了,又不是瞎子,是吧!
后面这一大段:
<?php if ($comments->levels > 0) {
$comments->levelsAlt(' comment-level-odd', ' comment-level-even');
};
$comments->alt(' comment-odd', ' comment-even');
?>
仔细看看,其实就是一个判断这条评论是奇数偶数,然后添加对应class的判断而已,何必这么麻烦,是不是,css的选择器::nth-child(odd)
和:nth-child(even)
不香吗???
所以,我个人是建议,这句话干掉他,还我一个干净的html代码。
干掉后代码如下:
<li id="li-<?php $comments->theId(); ?>" class="comment-body <?php echo $commentLevelClass;?>">
就这样,我们完事了。
是不是一下就明白了!
现在对于class变量我们知道了,现在来看具体的html评论代码
html评论代码
先看下预设的php变量
方法 | 作用 |
---|---|
<?php $comments->gravatar(); ?> | 评论者头像(avatar源) |
<?php $comments->author(); ?> | 评论者名字 |
<?php $comments->permalink(); ?> | 评论者当前评论的页面和定位,点击可以跳转到该评论位置 |
<?php $comments->date('Y-m-d H:i'); ?> | 评论的时间,可以到data查看对应的格式 |
<?php $comments->reply('Reply'); ?> | 回复按钮 |
<?php $comments->content(); ?> | 评论的内容 |
id="<?php $comments->theId(); ?>" | 评论的唯一值id |
评论代码只需要在html中套用就行了
<li id="li-<?php $comments->theId(); ?>" class="comment-body <?php echo $commentLevelClass;?>">
<div class="media" id="<?php $comments->theId(); ?>">
<?php $comments->gravatar(); ?>
<div class="media-body">
<?php $comments->author(); ?>
<?php $comments->content(); ?>
</div>
<div class="media-footer">
<time><?php $comments->date('Y-m-d H:i'); ?></time>
<?php $comments->reply('Reply'); ?>
</div>
</div>
</li>
一个经典的bootstrap的medai评论卡片就完成了,当然这里还只是单条的评论,如有子评论,我们还需要加上一个判断
<li id="li-<?php $comments->theId(); ?>" class="comment-body <?php echo $commentLevelClass;?>">
<div class="media" id="<?php $comments->theId(); ?>">
<?php $comments->gravatar(); ?>
<div class="media-body">
<?php $comments->author(); ?>
<?php $comments->content(); ?>
</div>
<div class="media-footer">
<time><?php $comments->date('Y-m-d H:i'); ?></time>
<?php $comments->reply('Reply'); ?>
</div>
</div>
<?php if ($comments->children) { ?>
<div class="comment-children">
<?php $comments->threadedComments($options); ?>
</div>
<?php } ?>
</li>
这样一个完整的评论就产生了,由于子评论嵌套在父评论里面,li的效果会产生padding-left
的左间距,所以,回复评论太多,宽度就会不太够,所以,官方再博客后台评论设置那,可以设置最多回复多少条,一般是5条就需要新开回复了。
那么,如果想避免这个情况,就可以再这里调整下嵌套结构,比如,像我的做法是我会将子评论和li做同级处理,当然这个做法不是很符合Ol>Li的结构,但是也没啥好办法吧,2333,看大家的智慧了
完整代码
现在就是合体了
<?php function threadedComments($comments, $options) {
$commentClass = '';
if ($comments->authorId) {
if ($comments->authorId == $comments->ownerId) {
$commentClass .= ' comment-by-author';
} else {
$commentClass .= ' comment-by-user';
}
}
$commentLevelClass = $comments->levels > 0 ? ' comment-child' : ' comment-parent';
?>
/* 自定义评论的代码结构 */
<li id="li-<?php $comments->theId(); ?>" class="comment-body <?php echo $commentLevelClass;?>">
<div class="media" id="<?php $comments->theId(); ?>">
<?php $comments->gravatar(); ?>
<div class="media-body">
<?php $comments->author(); ?>
<?php $comments->content(); ?>
</div>
<div class="media-footer">
<time><?php $comments->date('Y-m-d H:i'); ?></time>
<?php $comments->reply('Reply'); ?>
</div>
</div>
<?php if ($comments->children) { ?>
<div class="comment-children">
<?php $comments->threadedComments($options); ?>
</div>
<?php } ?>
</li>
<?php } ?>
关于审核提示(不一定是正确的)
官方在文档末尾说:
最新版本更新:首次评论审核提示,在自定义评论代码的适当地方添加以下语句,否则将看不到审核提示语句。
<?php $singleCommentOptions->commentStatus(); ?>
但是这句话使用有问题,最直白的就是:$singleCommentOptions
这边变量哪里来的,在threadedComments函数中,找遍天也没有创建过这个变量。
事实上这个$singleCommentOptions需要改为$options
所以实际代码是这个:
<?php $options->commentStatus(); ?>
但是,当我们在评论里面添加这句话的时候,你会发现,他并不是真的智能输出的,不管你这条评论是不是真的在审核,他都会显示文字:您的评论正等待审核!
我在百度找到了一个判断:
<?php if ('waiting' == $comments->status): ?>
<?php $options->commentStatus(); ?>
<?php endif;?>
通过这个判断来输出是否需要显示审核提示,but,既然我if都能判断了,<?php $options->commentStatus(); ?>
这句话反倒可有可无了,因为我可以自己写提示文字啊。
<?php if ('waiting' == $comments->status): ?>
<span>什么吊评论,还要老子审核!!!</span>
<?php endif;?>
这不香吗???
所以,我感觉这代码真的好尬啊!!!
php渲染出自定义模板评论
现在我们模板已经写好了,是时候让它出现在我们的页面上了。
在我们需要添加评论的页面先引入list-template.php
文件
<?php $this->need("components/list-template.php");?>
$this->need()
方法,他是相对于当前主题目录的,比如你主题名字叫nmd
,那么components就是nmd主题目录下的一个文件夹
nmd 主题文件夹
|
---- components
|----|
| ---- list-template.php
|
...
大概是这样的一个结构,具体就不细说了,意思到位就行!
引入模板后,我们需要使用<?php $comments->listComments(); ?>
这段代码渲染评论,但是要注意,如果你的代码前面,没有声明$comments
代码的话,使用这句话就会报错。
那么代码应该是这样:
<?php //评论列表 模板->$comments对象->渲染?>
<?php $this->need("components/list-template.php");?>
<?php $this->comments()->to($comments); ?>
<?php $comments->listComments(); ?>
ok,到这基本上你已经领悟了typecho的自定义评论了!恭喜出师。。。老父亲留下激动的泪水
注意
在评论中点击回复,可能会导致刷新页面,原因是因为在评论的回复表单那(form)元素,没有添加取消回复的代码:
<?php $comments->cancelReply('放弃回复'); ?>
这个代码记得添加到form表单那,当然form表单那边id啥的记得不要删了,按照官方文档那种基本上没啥问题。
而本次教程只是讲怎么自定了评论列表,如果以后有时间,再讲讲怎么自定评论表单吧!
博主您好,我的站是一个公益性质的小学生读书会,2个作用,一是展示,二是报名。之前我用的是第三方小程序报名,略繁琐,现在我打算就用文章底部的评论报名,中间涉及到一个问题,我需要里面可以做表单,填写孩子的名字,选择家长是否同去,这个表单只在“报名”分类中的文章下面才有。可否提供一些帮助,万分感谢。
这个去找原文的作者看看,文章下面有来源网址,我也只是转载。对这些代码也是小白。
参考页面:https://snail.chiphello.com:65001/index.php/archives/132/
目前我是要求家长回复“孩子姓名+陪同/不陪同”实现的,这样显得不够优雅。
感谢作者,写得很棒,求续集,自定评论表单!