Typecho 自定义评论模板
百度了好多篇文章,用起来都会报错,花了一天时间研究,终于搞明白自定义评论是怎么做的。
typecho的评论模板是comments.php文件,在这个文件,可能会有人在开头加上这句话:
<?php if (!defined('__TYPECHO_ROOT_DIR__')) exit; ?>
事实上这句话是不需要的,记得删除它。
自定义评论的基本结构
很多人在看官方的文档时就会迷糊,说了那么多,到底自定义评论的完整结构是啥,这里我就简单列出来,就三个部分。
comments.php
|
---- 自定义评论列表函数
|
---- 评论表单
|
---- 评论列表输出
其中评论表单和评论列表输出是可以相互更换位置的,但是自定义评论列表函数一定要在最上面。
自定义评论列表函数
该函数可以控制评论列表的输出内容,我们可以自定义输出什么东西,什么位置。
<?php function threadedComments($comments, $options) {
$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 = $comments->_levels > 0 ? ' comment-child' : ' comment-parent'; //评论层数大于0为子级,否则是父级
?>
/* 自定义评论列表部分 */
<?php } ?>
这样写就是基本的起手式了,自定义评论列表写之前我们要知道几个调用的方法。
方法 | 作用 |
---|---|
<?php $comments->author(); ?> | 评论者头像(avatar源) |
<?php $comments->author(); ?> | 评论者名字 |
<?php $comments->permalink(); ?> | 评论者当前评论的页面和定位,点击可以跳转到该评论位置 |
<?php $comments->date('Y-m-d H:i'); ?> | 评论的时间,可以到data查看对应的格式 |
<?php $comments->reply('Reply'); ?> | 回复按钮 |
<?php $comments->content(); ?> | 评论的内容 |
然后我们根据自己的要求写出对应的html结构
/* 自定义评论列表部分 */
<div>
<?php $comments->gravatar('40', ''); ?>
<h2><?php $comments->author(); ?></h2>
<p>评论时间:<?php $comments->date('Y-m-d H:i'); ?></p>
<div>
<?php $comments->content(); ?>
</div>
<p><?php $comments->reply(); ?></p>
</div>
这样一个基本结构有了,我们还要考虑子评论,也就是该评论的回复评论。
<?php if ($comments->children) { ?>
<?php $comments->threadedComments($options); ?>
<?php } ?>
这句话表示如果有子评论,将按照刚刚自定义的评论列表函数输出子评论。也就是说,评论列表永远都是使用同一个模板,不断的嵌套的。
完整代码:
<?php function threadedComments($comments, $options) {
$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 = $comments->_levels > 0 ? ' comment-child' : ' comment-parent'; //评论层数大于0为子级,否则是父级
?>
/* 自定义评论列表部分 */
<div>
<?php $comments->gravatar('40', ''); ?>
<h2><?php $comments->author(); ?></h2>
<p>评论时间:<?php $comments->date('Y-m-d H:i'); ?></p>
<div>
<?php $comments->content(); ?>
</div>
<p><?php $comments->reply(); ?></p>
</div>
/*子评论*/
<?php if ($comments->children) { ?>
<?php $comments->threadedComments($options); ?>
<?php } ?>
<?php } ?>
这里自定义评论部分结束!
评论表单
表单部分和官方文档一样,可以自行修改,这里就贴代码出来示意一下
<form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" role="form">
<?php if($this->user->hasLogin()): ?>
<p><?php _e('登录身份: '); ?><a href="<?php $this->options->profileUrl(); ?>"><?php $this->user->screenName(); ?></a>. <a href="<?php $this->options->logoutUrl(); ?>" title="Logout"><?php _e('退出'); ?> »</a></p>
<?php else: ?>
<p>
<label for="author" class="required"><?php _e('称呼'); ?></label>
<input type="text" name="author" id="author" class="text" value="<?php $this->remember('author'); ?>" required />
</p>
<p>
<label for="mail"<?php if ($this->options->commentsRequireMail): ?> class="required"<?php endif; ?>><?php _e('Email'); ?></label>
<input type="email" name="mail" id="mail" class="text" value="<?php $this->remember('mail'); ?>"<?php if ($this->options->commentsRequireMail): ?> required<?php endif; ?> />
</p>
<p>
<label for="url"<?php if ($this->options->commentsRequireURL): ?> class="required"<?php endif; ?>><?php _e('网站'); ?></label>
<input type="url" name="url" id="url" class="text" placeholder="<?php _e('http://'); ?>" value="<?php $this->remember('url'); ?>"<?php if ($this->options->commentsRequireURL): ?> required<?php endif; ?> />
</p>
<?php endif; ?>
<p>
<label for="textarea" class="required"><?php _e('内容'); ?></label>
<textarea rows="8" cols="50" name="text" id="textarea" class="textarea" required ><?php $this->remember('text'); ?></textarea>
</p>
<p>
<button type="submit" class="submit"><?php _e('提交评论'); ?></button>
</p>
</form>
这里我们可以注意到每个input表单元素都有一个required属性,这个属性就是typecho调用表单验证的地方,如果不需要博客自带的验证就可以去掉对应的判断php代码,但是我觉得还是用比较好,没必要自己再去写,现成的不好吗,又能减少代码书写,岂不美哉。
禁止评论
博客可以设置禁止评论,所以在使用表单之前还要判断有没有禁用评论
<?php if ($this->allow('comment')) : ?>
<!-- 评论表单form放的地方-->
<?php else : ?>
<h3><?php _e('评论已关闭'); ?></h3>
<?php endif; ?>
评论列表输出
<!-- 回复列表 -->
<?php $this->comments()->to($comments); ?>
<?php if ($comments->have()) : ?>
<!-- 评论头部提示信息 -->
<h4><?php $this->commentsNum(_t('暂无评论'), _t('仅有一条评论'), _t('已有 %d 条评论')); ?></h4>
<!-- 评论的内容 -->
<?php $comments->listComments(); ?>
<!-- 评论page -->
<?php $comments->pageNav('« 前一页', '后一页 »'); ?>
</div>
</div>
<?php endif; ?>
通过<?php $comments->listComments(); ?>
可以直接输出所有的评论,而且是按照最顶部的自定义模板输出的。
完整代码:
<?php function threadedComments($comments, $options) {
$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 = $comments->_levels > 0 ? ' comment-child' : ' comment-parent'; //评论层数大于0为子级,否则是父级
?>
/* 自定义评论列表部分 */
<div id="<?php $comments->theId(); ?>">
<?php $comments->gravatar('40', ''); ?>
<h2><?php $comments->author(); ?></h2>
<p>评论时间:<?php $comments->date('Y-m-d H:i'); ?></p>
<div>
<?php $comments->content(); ?>
</div>
<p><?php $comments->reply(); ?></p>
</div>
/*子评论*/
<?php if ($comments->children) { ?>
<?php $comments->threadedComments($options); ?>
<?php } ?>
<?php } ?>
<?php $this->comments()->to($comments); ?>
<?php if ($this->allow('comment')) : ?>
<!-- 评论表单form放的地方-->
<div id="<?php $this->respondId(); ?>">
<div> <!-- 取消回复 -->
<?php $comments->cancelReply(); ?>
</div>
<form method="post" action="<?php $this->commentUrl() ?>" id="comment-form" role="form">
<?php if($this->user->hasLogin()): ?>
<p><?php _e('登录身份: '); ?><a href="<?php $this->options->profileUrl(); ?>"><?php $this->user->screenName(); ?></a>. <a href="<?php $this->options->logoutUrl(); ?>" title="Logout"><?php _e('退出'); ?> »</a></p>
<?php else: ?>
<p>
<label for="author" class="required"><?php _e('称呼'); ?></label>
<input type="text" name="author" id="author" class="text" value="<?php $this->remember('author'); ?>" required />
</p>
<p>
<label for="mail"<?php if ($this->options->commentsRequireMail): ?> class="required"<?php endif; ?>><?php _e('Email'); ?></label>
<input type="email" name="mail" id="mail" class="text" value="<?php $this->remember('mail'); ?>"<?php if ($this->options->commentsRequireMail): ?> required<?php endif; ?> />
</p>
<p>
<label for="url"<?php if ($this->options->commentsRequireURL): ?> class="required"<?php endif; ?>><?php _e('网站'); ?></label>
<input type="url" name="url" id="url" class="text" placeholder="<?php _e('http://'); ?>" value="<?php $this->remember('url'); ?>"<?php if ($this->options->commentsRequireURL): ?> required<?php endif; ?> />
</p>
<?php endif; ?>
<p>
<label for="textarea" class="required"><?php _e('内容'); ?></label>
<textarea rows="8" cols="50" name="text" id="textarea" class="textarea" required ><?php $this->remember('text'); ?></textarea>
</p>
<p>
<button type="submit" class="submit"><?php _e('提交评论'); ?></button>
</p>
</form>
</div>
<?php else : ?>
<h3><?php _e('评论已关闭'); ?></h3>
<?php endif; ?>
<!-- 回复列表 -->
<?php if ($comments->have()) : ?>
<!-- 评论头部提示信息 -->
<h4><?php $this->commentsNum(_t('暂无评论'), _t('仅有一条评论'), _t('已有 %d 条评论')); ?></h4>
<!-- 评论的内容 -->
<?php $comments->listComments(); ?>
<!-- 评论page -->
<?php $comments->pageNav('« 前一页', '后一页 »'); ?>
</div>
</div>
<?php endif; ?>
自定义评论完成,这才是最正宗的,完美版本。
bug修复
评论列表报错
这次我再次使用的时候出现了一个问题,就是回复列表输出时出现了have()输出null的情况,找了半天发现漏了一句<?php $this->comments()->to($comments); ?>
,没有这个$comments
变量就不存在,have函数也不存在就会报错,目前已经更正了。
评论头像修复
<?php $comments->gravatar('40', ''); ?>
会直接输出一个img元素,所以不需要再套一个img元素,目前已更正
关于评论列表报错的更多理解
由于缺少了指定变量所以报错,而且这个变量还有个地方使用到了,就是点击回复会将评论表单插入到当前回复内容下面,会有一个关闭按钮,这个关闭按钮也需要用到$comments
,所以在使用的时候可以把上面那句变量丢在表单元素的上面。
点击回复表单不自动插入到当前评论内容下
原因是因为我忘记给每个评论加上对应的id了,将评论内容加上id
/* 自定义评论列表部分 */
<div id="<?php $comments->theId(); ?>">
<?php $comments->gravatar('40', ''); ?>
<h2><?php $comments->author(); ?></h2>
<p>评论时间:<?php $comments->date('Y-m-d H:i'); ?></p>
<div>
评论审核提示
将下面的代码放入评论的内容后面即可;
<?php if ('waiting' == $comments->status) { ?>
<?php $options->commentStatus(); ?>
<?php } ?>
当然我这里只是讲解了下typecho自定义评论的基本原理,使用的时候估计还是会遇到一些奇奇怪怪的问题,我们可以参考下官方的文档和官方的默认主题里的comments文件,相信你会有很大的收获。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
全部评论 16
木灵鱼儿
FireFox Windows 10KSNFSFXFFS
Google Chrome Windows 10木灵鱼儿
FireFox Windows 10KSNFSFXFFS
Google Chrome Windows 1054646
Google Chrome Windows 10哈哈
Google Chrome Windows 10青枫
FireFox Windows 10袁某人
Google Chrome Android木灵鱼儿
FireFox Windows 10abctoby
Google Chrome Windows 10评论审核提示代码具体加在哪儿???
木灵鱼儿
FireFox Windows 10chenmo
QQ Browser Android Pie木灵鱼儿
FireFox Windows 10jclser
FireFox Windows 7木灵鱼儿
FireFox Windows 10jclser
FireFox Windows 7