官方文档对这方面写的比较简洁,不利于主题修改者快速入门typecho,所以总结了一些经验,方便自己也方便主题修改者创建评论模块。

先写一个评论区的总的容器,id 为 comments

<div id="comments"> ... </div>

评论区域分为两个部分:评论输出列表模块评论输入表单模块

评论输出列表模块

有两种方法:

  • 使用官方自带的函数输出,方便简单,只需要加点CSS控制就行
  • 自定义评论列表模块,更灵活满足我们需求

官方自带的函数输出评论

代码如下:

<?php $this->comments()->to($comments); ?> <?php if ($comments->have()): ?><!--如果有评论的才会输出--> <!--显示评论总条数--> <h3><?php $this->commentsNum(_t('暂无评论'), _t('仅有一条评论'), _t('已有 %d 条评论')); ?></h3> <!--输出评论列表--> <?php $comments->listComments(); ?> <!--评论分页--> <?php $comments->pageNav('« 前一页', '后一页 »'); ?> <?php endif; ?>

代码很好理解。不再赘述。

说明一下官方文档—快速入门—调用评论页 给出的代码示例是错误 的!代码示例只能实现简单输出评论,不能对每条评论回复,是个半残品 。但是里面的函数是可以在自定义评论模块中来使用的。

1758956747.png

1758956747.png

我们这里输出评论模块使用的使用官方自带的函数 $comments->listComments(); 。输出的HTML结构也是写死的。所以,接下来是如何自定义评论输出列表模块

自定义评论输出列表模块

官方文档—自定义评论列表区域 这里面给出了很混乱的代码讲解,实质上是写了一个 threadedComments 函数来替代系统自带的 threadedCommentsCallback函数(在/var/widget/comments/archive.php内置)。

这个函数是php与html互写的形式。可以看出这个函数分为了两个部分:

  • php动态控制输出结构
  • html语句直接固定输出结构
<?php function threadedComments($comments, $options) { ... //动态控制结构 ?> ... //html 固定结构 } <?php } ?><!--}是函数的结束符-->

动态控制结构

$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为子级,否则是父级
  • 如果是文章作者的评论添加 .comment-by-author 样式
  • 如果是评论作者的添加 .comment-by-user 样式
  • 通过判断 $comments->_levels 来确定当前评论的是子级评论还是父级评论

这部分一般不需要更改的,即使修改也是增加语句。

HTML固定输出结构

<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; ?>"> <div id="<?php $comments->theId(); ?>"> <div class="comment-author"> <?php $comments->gravatar('40', ''); ?> <cite class="fn"><?php $comments->author(); ?></cite> </div> <div class="comment-meta"> <a href="<?php $comments->permalink(); ?>"><?php $comments->date('Y-m-d H:i'); ?></a> <span class="comment-reply"><?php $comments->reply(); ?></span> </div> <?php $comments->content(); ?> </div> <?php if ($comments->children) { ?> <div class="comment-children"> <?php $comments->threadedComments($options); ?> </div> <?php } ?> </li>

大家马上会发现之前官方文档的错误示例代码提供的函数 ,在这里派上了用场!

代码很好理解,每条评论是一个 <li>列表项目,包含了 评论作者的头像 评论作者的信息子级评论 。子级评论和父级评论的HTML结构是相同的,只是CSS样式不同而已。

我们把两个部分组合在一起,就构成了我们的自定义评论输出模块

<?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 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; ?>"> <div id="<?php $comments->theId(); ?>"> <div class="comment-author"> <?php $comments->gravatar('40', ''); ?> <cite class="fn"><?php $comments->author(); ?></cite> </div> <div class="comment-meta"> <a href="<?php $comments->permalink(); ?>"><?php $comments->date('Y-m-d H:i'); ?></a> <span class="comment-reply"><?php $comments->reply(); ?></span> </div> <?php $comments->content(); ?> </div> <?php if ($comments->children) { ?> <div class="comment-children"> <?php $comments->threadedComments($options); ?> </div> <?php } ?> </li> <?php } ?>

评论输入表单模块

这部分很简单,直接用HTML静态结构来固定输出内容。

先贴出官方文档给出的代码:

<!-- 判断设置是否允许对当前文章进行评论 --> <?php if($this->allow('comment')): ?> <h4 id="response">Leave a Reply</h4> <!-- 输入表单开始 --> <form method="post" action="<?php $this->commentUrl() ?>" id="comment_form"> <!-- 如果当前用户已经登录 --> <?php if($this->user->hasLogin()): ?> <!-- 显示当前登录用户的用户名以及登出连接 --> <p>Logged in as <a href="<?php $this->options->adminUrl(); ?>"><?php $this->user->screenName(); ?></a>. <a href="<?php $this->options->index('Logout.do'); ?>" title="Logout">Logout »</a></p> <!-- 若当前用户未登录 --> <?php else: ?> <!-- 要求输入名字、邮箱、网址 --> <p><input type="text" name="author" class="text" size="35" value="<?php $this->remember('author'); ?>" /><label>Name (Required)</label></p> <p><input type="text" name="mail" class="text" size="35" value="<?php $this->remember('mail'); ?>" /><label>E-mail (Required *will not be published)</label></p> <p><input type="text" name="url" class="text" size="35" value="<?php $this->remember('url'); ?>" /><label>Website</label></p> <?php endif; ?> <!-- 输入要回复的内容 --> <p><textarea rows="10" cols="50" name="text"><?php $this->remember('text'); ?></textarea></p> <p><input type="submit" value="Submit Comment" class="submit" /></p> </form> <?php endif; ?>

看得懂注释,应该也能看的懂代码。注意以下两点:

  1. <?php if($this->allow('comment')): ?> 这个函数详见分离文章的评论和引用通告
  2. typecho 提供了 <?php $this->remember(''); ?> 函数可以用来记住之前已经输入过的名称、邮箱地址和网址和评论内容。
最后修改:2020 年 07 月 05 日
喜欢我的文章吗?
别忘了点赞或赞赏,让我知道创作的路上有你陪伴。