Typecho 文档:评论置顶功能(类完美版)
适用程序:Typecho
程序版本:1.2.1
文档作者:Lopwon
作者博客:Lopwon.com
发布页面:Lopwon.com/3648.html
许可方式:CC BY-NC-SA
注意:此文档源于作者在博客改造中的一些经验总结,转载还请署名。
敬告:此文档操作涉及程序核心文件的修改,作者不对你在使用中产生的任何问题造成的不良后果,承担责任。
文档说明
在给 Snapic Plus v5 相册主题新增置顶文章功能时,了解到了 Typecho 对文章列表和评论列表的处理机制,这也是之前为什么无法把评论在列表里全局置顶,只能在该评论所处分页下置顶的原因,于是乎,在时隔一年后,再次折腾起评论置顶,相较于插件 Lopwon Pin 和另一篇文档,本文档介绍的方法可以较为完美的实现评论置顶,包含其所属的子评论,还不用动数据库。
主要功能
1. 在后台主题设置里,自定义需要置顶的评论,将在各自的评论列表里置顶显示。
2. 同一 cid 下,可以单条评论置顶也可以多条,父级评论下的子级评论也会同时置顶。
3. 置顶评论沿用自己主题的评论样式。
使用方法
A 涉及文件
var/Widget/Comments/Archive.php
usr/themes/***/functions.php
B 改造文件
作用:新增评论置顶功能。
打开文件 var/Widget/Comments/Archive.php 替换一处、新增两处代码:
1. 搜索找到以下代码:
$outputComments[$coid] = $comment;
2. 将以上代码替换为以下代码:
$pinchatOpt = $this->options->pinchat;
if (!empty($pinchatOpt)) {
$pinchatCoid = explode(',', $pinchatOpt);
$pinchatCoid = array_map('trim', $pinchatCoid);
$pinchatCoid = array_unique($pinchatCoid);
if (in_array($comment['coid'], $pinchatCoid)) {
if (0 != $parent && isset($this->stack[$parent])) {
$comment['parent'] = $parent;
$this->threadedComments[$parent][$coid] = $comment;
} else {
$pinchat[$coid] = $comment;
}
} else {
$outputComments[$coid] = $comment;
}
} else {
$outputComments[$coid] = $comment;
}
2. 搜索找到以下代码:
$outputComments = [];
3. 在以上代码的上一行(或下一行)添加以下代码:
$pinchat = [];
4. 搜索找到以下代码:
$this->stack = $outputComments;
5. 在以上代码的上一行添加以下代码:
$outputComments = array_merge($outputComments, $pinchat); // 如果评论是以(较旧的)显示在前面,则将 $pinchat 和 $outputComments 对调位置
至此,已完成对置顶评论的输出,接着,打开文件 usr/themes/***/functions.php 创建用于自定义置顶评论的表单,在函数 themeConfig() 里添加以下代码:
$pinchat = new Typecho_Widget_Helper_Form_Element_Text(
'pinchat', NULL, NULL,
_t('置顶评论'),
_t('
1. 填入需要置顶的评论 coid 多个以半角逗号隔开,将在各自的评论列表里置顶显示。<br>
2. 仅限填入父级评论的 coid 其下的子级评论也会一并置顶。
'),
);
$form->addInput($pinchat);
至此,已完成评论置顶功能,进入主题设置里找到(置顶评论)按需设置,即可。
拓展功能
在完成以上(新增评论置顶功能)改造后,可以使用 JavaScript 在前端给置顶的评论添加标记(选择性操作)。
1. 打开文件 usr/themes/***/footer.php 或主题页脚文件,在页末添加以下代码(留意注释,以及按需修改):
<script>
$(document).ready(function() { // 页面加载完成后执行代码
var coids = '<?php echo $this->options->formPinchatText; ?>';
var pinchatArray = coids && coids.trim() ? coids.split(',') : []; // 获取并处理初始数据,将 coid 字符串转换为数组
var $commentList = $('.comment-list [id^="comment-"]'); // 如果你的评论区做了自定义,请根据实际情况修改
$commentList.each(function() {
var $commentEl = $(this);
var commentId = $commentEl.attr('id');
if (commentId) {
var commentNumber = commentId.replace('comment-', ''); // 提取评论容器内的编号
if (pinchatArray.indexOf(commentNumber) !== -1) { // 检查编号是否存在于 pinchat 数组中
if (!$commentEl.find('.pinchat').length) { // 检查是否已存在,避免重复添加
$commentEl.find('.comment-content').append('<span class="pinchat">置顶</span>'); // 在 .comment-content 内添加 .pinchat 容器
}
}
}
});
});
</script>
2. 如果你在用的主题未引入 jQuery 库,则使用以下原生 JS 方式:
<script>
document.addEventListener('DOMContentLoaded', function() { // 页面加载完成后执行代码
var coids = '<?php echo $this->options->formPinchatText; ?>';
var pinchatArray = coids && coids.trim() ? coids.split(',') : []; // 获取并处理初始数据,将 coid 字符串转换为数组
var commentList = document.querySelectorAll('.comment-list [id^="comment-"]'); // 如果你的评论区做了自定义,请根据实际情况修改
Array.from(commentList).forEach(function(commentEl) {
var commentId = commentEl.getAttribute('id');
if (commentId) {
var commentNumber = commentId.replace('comment-', ''); // 提取评论容器内的编号
if (pinchatArray.indexOf(commentNumber) !== -1) { // 检查编号是否存在于 pinchat 数组中
if (!commentEl.querySelector('.pinchat')) { // 检查是否已存在,避免重复添加
// 在 .comment-content 内添加 .pinchat 容器
var contentEl = commentEl.querySelector('.comment-content');
var pinchatSpan = document.createElement('span');
pinchatSpan.className = 'pinchat';
pinchatSpan.textContent = '置顶';
contentEl.appendChild(pinchatSpan);
}
}
}
});
});
</script>
至此,已为置顶评论添加了容器 <span class="pinchat">置顶</span> 通过定义 .pinchat 适配样式。