官方文档对这方面写的比较简洁,不利于主题修改者快速入门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

我们这里输出评论模块使用的使用官方自带的函数 $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 日
喜欢我的文章吗?
别忘了点赞或赞赏,让我知道创作的路上有你陪伴。