博客篇:文章列表添加评论数显示

前言

目前博客文章列表只会显示字数和阅读时间,不会显示评论数,不过博客接入了twikoo评论系统,我翻了翻官方文档,发现有提供获取评论数的API接口。如图:

那么事情就变得简单起来了,只需要调用这个接口,然后把返回的数据渲染到对于的文章列表上即可。

说说缺点

不过依赖于外部插件,对于Astro框架的静态博客不是很友好,会拖慢网站加载速度,虽然可以忽约不计,但是多少有点影响。

目前博客集成第三方主要就是twikoo友链朋友圈lsky图床,对于友链朋友圈和图床我都是单开一个页面,实际对博客的影响非常小,即使服务崩溃也不会影响网站正常运行。

为了尽可能的达到对这些第三方集成完美控制,我都有在config.ts做开关配置,可以配置是否开启这些功能或页面。

主要代码

PostCard

src->components->PostCard.astro

在阅读时长旁边添加评论数显示元素。

import { commentConfig } from "src/config";

<!-- word count, read time and comment count  -->
<div class="text-sm text-black/30 dark:text-white/30 flex gap-4 transition">
    <div>
        {remarkPluginFrontmatter.words} {" " + i18n(remarkPluginFrontmatter.words === 1 ? I18nKey.wordCount : I18nKey.wordsCount)}
    </div>
    <div>|</div>
    <div>
        {remarkPluginFrontmatter.minutes} {" " + i18n(remarkPluginFrontmatter.minutes === 1 ? I18nKey.minuteCount : I18nKey.minutesCount)}
    </div>
    {commentConfig.enable && (
        <>
            <div>|</div>
            <span class="comment-count" data-path={url}>
                <span>0</span>
                <span>{i18n(I18nKey.commentsCount)}</span>
            </span>
        </>
    )}
</div>

twikoo-loader

public->lib->twikoo-loader.js

新建一份twikoo-loader.js文件,请求API和渲染操作都在这个文件中完成。

// public/lib/twikoo-loader.js

(function () {
	if (window.__twikooLoaderInitialized) return;
	window.__twikooLoaderInitialized = true;

	let twikooLoadTimer;

	// 加载评论数量
	const loadTwikooCommentCount = () => {
		if (!window.twikoo) return;

		const commentEls = document.querySelectorAll(".comment-count[data-path]");
		if (commentEls.length === 0) return;

		const paths = Array.from(commentEls)
			.map((el) => el.dataset.path)
			.map((path) => path.split("/").map(encodeURIComponent).join("/"));

		// 从全局配置获取Twikoo参数
		const twikooConfig = window.commentConfig?.twikoo || {};

		window.twikoo
			.getCommentsCount({
				envId: twikooConfig.envId || "选填",
				region: twikooConfig.region || "选填",
				urls: paths,
				includeReply: true,
			})
			.then((res) => {
				res.forEach((item) => {
					const el = document.querySelector(
						`.comment-count[data-path="${decodeURIComponent(item.url)}"] span:nth-child(1)`,
					);
					if (el) el.textContent = `${item.count}`;
				});
			})
			.catch(console.error);
	};

	// 确保 Twikoo 加载
	const ensureTwikooLoaded = () => {
		clearTimeout(twikooLoadTimer);
		twikooLoadTimer = setTimeout(() => {
			if (window.twikooLoaded) {
				loadTwikooCommentCount();
			} else if (!window.twikooLoading) {
				window.twikooLoading = true;
				const script = document.createElement("script");
				script.src =
					"https://registry.npmmirror.com/twikoo/1.6.44/files/dist/twikoo.min.js"; // 国内默认CDN
				script.onload = () => {
					window.twikooLoaded = true;
					loadTwikooCommentCount();
				};
				document.head.appendChild(script);
			}
		}, 200);
	};

	// 绑定事件(只绑定一次)
	const bindEvents = () => {
		const safeReload = () => ensureTwikooLoaded();
		document.addEventListener("astro:page-load", safeReload);
		document.addEventListener("swup:page:view", safeReload);
	};

	// 初始化
	ensureTwikooLoaded();
	bindEvents();
})();

这个js文件主要完成的操作就是根据官方文档所描述的配置getCommentsCount方法,发送请求,然后将返回的数据渲染到页面上。需要注意的是script.src的值需要自己调整,我这里是使用的官方推荐的国内cdn

通过-cdn-引入:前端部署 | Twikoo 文档

Config

src->Config.ts

在配置文件中添加评论组件的相关配置,这个之前在集成twikoo就添加过了astrofuwai配置教程

主要注意envId的配置就行了,我是私有部署的,所以我这里填的是我部署的评论系统后端的ip|域名地址。

修改enablefalse就能关闭评论,包括评论数展示。

export const commentConfig = {
	enable: true,
	provider: "twikoo",
	twikoo: {
		envId: "https://api.pljzy.top", // 部署的项目地址
		region: "",
		lang: "zh-CN",
	},
};

Layout

最后在Layout页面导入并使用twikoo-loader.js

import { commentConfig } from "src/config";


{commentConfig.enable && (
  <>
    <script is:inline define:vars={{ commentConfig }}>
	  window.commentConfig = commentConfig;
      // 动态加载 Twikoo Loader(保证执行顺序)
      const script = document.createElement('script');
      script.src = '/scripts/twikoo-loader.js';
      script.defer = true; // 延迟到 HTML 解析后执行
      document.head.appendChild(script);
    </script>
  </>
)}

实现效果

总结

对于文章添加评论数显示,主要代码逻辑在twikoo-loader.js中完成,然后只需在母版页中导入并使用即可。

为了可以控制评论组件和评论数是否显示,可以直接修改Config.ts中的enable属性。

相关链接