1407 字
7 分钟
Fuwari 主题魔改 - 给你的Fuwari添加Twikoo评论支持
2025-03-26

什么是 Twikoo#

Twikoo是一个简洁、安全、免费的静态网站评论系统,能够为个人博客等站点提供优质的评论体验,并能够对评论进行便捷的管理。

为 Fuwari 接入 Twikoo#

我们先在项目目录src/components/comment下创建文件Twikoo.astro文件,它代表着 Twikoo 组件,在这里我们使用 Twikoo 官方文档中的「通过 CDN 引入」方式。如同Fuwari-PR-37所做的那样。

<script is:inline src="https://cdn.staticfile.org/twikoo/1.6.32/twikoo.all.min.js" ></script> <script is:inline define:vars={{ config }}> twikoo.init(config); </script>

但这种方式存在一个问题,若twikoo.all.min.js未加载完成,但程序已经执行到了twikoo.init(config),这将会导致一种错误。

image-20250306182955541

显然,当远程文件未加载完成时,将会概率触发这个问题,未加载完成时就调用twikoo.all.min.js将会导致twikoo未定义,因此,我们应该在twikoo.all.min.js加载完成后,再执行init方法。即这篇文章所讲诉的方法。

<div id="comment"></div> <script> function loadTwikoo() { const script = document.createElement("script"); script.src = "https://cdn.jsdelivr.net/npm/twikoo@1.6.41/dist/twikoo.all.min.js"; script.defer = true; script.onload = () => { twikoo.init(); //在这里传入你的Twikoo配置信息 }; document.body.appendChild(script); } </script> <!--Twikoo.astro-->

但这种方式似乎仍然不够完善,在这种情况下,评论组件仍然会偶现无法加载。这是由于 Fuwari 使用了swup来确保类似单页应用的平滑过渡体验,在使用swup后,JavaScript脚本并不会在每次都被重新加载,这将会导致虽然没有上述的错误,但评论组件仍然会无法正常显示。

要解决这种情况,我们可以使用swup组件库中的hooks,在swup的特定的生命周期时,hooks内的函数将会被触发并调用。因此我们可以通过hooks手动通知组件重载评论区组件。Fuwari 的hooks处理部分的函数在src/layouts/Layout.astro中,我们可以把新添加的代码书写在这里。

function initCommentComponent() { const event = new Event("loadComment"); document.dispatchEvent(event); }

在这里我们新建了一个函数,专用于创建loadComment的事件,即通知评论组件进行一次加载。

Layout.astrofunction init()函数内,需要添加对initCommentComponent()函数的一次调用,这样在打开网页时我们的评论将会被正确加载。

随后紧接着我们还需要在swuphooks部分,添加对这个函数的调用。如Swup 文档所述,使用content:replace,这部分的函数将会在「页面的旧内容被新内容代替」时调用。我们可以紧接已存在的content:replace函数进行调用。

window.swup.hooks.on("content:replace", () => { initCustomScrollbar(); initCommentComponent(); // 添加代码调用 });

在此,我们完成了对事件的传递。在Twikoo.astro中我们还要对事件进行监听,对Twikoo.astro完善后如下文所示。

--- interface Props { path: string; } const config = { el: "#comment", path: Astro.props.path, }; --- <!-- 简化了配置部分的代码,实际上可以把配置文件统一写入fuwari的配置文件统一读取 --> <div id="comment"></div> <script define:vars={{ config }}> function loadTwikoo() { const script = document.createElement("script"); script.src = "https://cdn.jsdelivr.net/npm/twikoo@1.6.41/dist/twikoo.all.min.js"; script.defer = true; script.onload = () => { twikoo.init({ ...config, envId: "", // 你的envId,获取方法请参照Twikoo文档 lang: "zh-CN", // 评论区语言 }); // 传入配置信息 }; document.body.appendChild(script); } document.addEventListener("loadComment", loadTwikoo, { once: true }); // 监听加载评论事件,但是我们只能监听一次,从而避免多次触发。 </script>

随后,在src/pages/posts/[...slug].astro中导入这个组件,我们即可看到一个标准的Twikoo评论区组件。(思路参考了这篇文章

<!--16行左右,不要忘了引入组件--> import Twikoo from '@components/comment/Twikoo.astro' <!--- 111行左右新增 --> <div class="card-base p-6 mb-4"><Twikoo path={`/posts/${entry}`} /></div> <div class="flex flex-col md:flex-row justify-between mb-4 gap-4 overflow-hidden w-full" > <!--原有的代码,方便参照代码插入位置--> </div>

image-20250306234247213

Twikoo 主题魔改#

在上一节中,我们成功给 Fuwari 主题接入了 Twikoo 评论系统,但 Twikoo 的默认主题与 Fuwari 主题显得并不协调,我们希望能够将其强调色与 Fuwari 统一。并且在黑暗模式下,文本颜色并不会随 Fuwari 变化,仍然显示为默认的黑色,导致难以辨认,这我们可以通过修改 twikoo 的样式来解决。

image-20250307154449987

这里 Twikoo 的样式其实是其twikoo.all.min.js中所内嵌的样式,当然 Twikoo 也提供了不内嵌 css 的版本供用户使用,从而能够更深度的自定义 Twikoo。在Twikoo 文档中,对不同的 js 文件的功能进行了划分。

image-20250307154938348

我们仍然选择带有内嵌 css 的版本,从而在 Twikoo 内嵌样式的基础上去覆盖 Twikoo 原有样式,当然,从头开始定义 Twikoo 的样式亦可。由于我们仍然选择了内嵌 css 的版本,对 twikoo 的引入部分无需更改。

src/styles创建 css 文件,文件名任取,在这里的样式将会被自动加载,我们可以在浏览器的审查模式下,对指定元素进行选中,并根据各个元素的类名,对元素进行选中,并使用 CSS 对其样式进行修改。

image-20250307155942114

在这里,我们使用SCSS语法与Tailwindcss来简化开发,完整的 CSS 文件可以在我的Github Gists中下载。将 CSS 应用到 Fuwari 中,我们即可得到一个适配 Fuwari 主题强调色的 Twikoo 评论界面(整体布局布局参考自「园子里的时光」博客)。当然,也可以在我的 CSS 文件中,对主题进行进一步的修改。

image-20250307161015897

其余问题#

单击按钮返回顶部#

参见Twikoo-Issues-731,目前可以通过修改 Twikoo 源码,将<a>标签内href="#"去除,再对 Twikoo 重新编译,并替换 Twikoo 导入。(待寻找更好的方法)

Fuwari 主题魔改 - 给你的Fuwari添加Twikoo评论支持
https://www.persicif.xyz/posts/blog-theme-mod/
作者
HyperCherry
发布于
2025-03-26
许可协议
CC BY-NC-SA 4.0
评论
昵称
邮箱
网址
0/500
  • OωO
  • |´・ω・)ノ
  • ヾ(≧∇≦*)ゝ
  • (☆ω☆)
  • (╯‵□′)╯︵┴─┴
  •  ̄﹃ ̄
  • (/ω\)
  • ∠( ᐛ 」∠)_
  • (๑•̀ㅁ•́ฅ)
  • →_→
  • ୧(๑•̀⌄•́๑)૭
  • ٩(ˊᗜˋ*)و
  • (ノ°ο°)ノ
  • (´இ皿இ`)
  • ⌇●﹏●⌇
  • (ฅ´ω`ฅ)
  • (╯°A°)╯︵○○○
  • φ( ̄∇ ̄o)
  • ヾ(´・ ・`。)ノ"
  • ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
  • (ó﹏ò。)
  • Σ(っ °Д °;)っ
  • ( ,,´・ω・)ノ"(´っω・`。)
  • ╮(╯▽╰)╭
  • o(*////▽////*)q
  • >﹏<
  • ( ๑´•ω•) "(ㆆᴗㆆ)
  • 😂
  • 😀
  • 😅
  • 😊
  • 🙂
  • 🙃
  • 😌
  • 😍
  • 😘
  • 😜
  • 😝
  • 😏
  • 😒
  • 🙄
  • 😳
  • 😡
  • 😔
  • 😫
  • 😱
  • 😭
  • 💩
  • 👻
  • 🙌
  • 🖕
  • 👍
  • 👫
  • 👬
  • 👭
  • 🌚
  • 🌝
  • 🙈
  • 💊
  • 😶
  • 🙏
  • 🍦
  • 🍉
  • 😣
  • 颜文字
  • Emoji
  • Bilibili
4 条评论
bbz

感谢!非常好参考

 Windows 11
 Microsoft Edge 138.0.0.0
Rimrose

我跟着 给你的 Fuwari 接入 Twikoo 评论 这篇博文成功添加了 Twikoo 的支持,但是在跟着本文尝试添加事件监听的时候一直没成功,最终写成这样也还是不行:https://github.com/SirTamago/Blog-astro-fuwari/blob/main/src/components/comment/Twikoo.astro

 Windows 11
 Microsoft Edge 135.0.0.0
Rimrose
回复 @Rimrose :

另外,给 twikoo.css 添加一段这个可以让表情组件在表情包数量太多的时候正确显示(不然会被遮挡):

.card-base {
    overflow: visible;
}
 Windows 11
 Microsoft Edge 135.0.0.0
Cherry Cherry
回复 @Rimrose :
  • Twikoo.astro仅接受来自swup的事件,便于确定加载评论的时机。因此其本身无需发送事件,最后三行可以删除。
  • 如果使用<script is:inline>内联式的加载twikoo.all.min.js可能导致在其未加载完成时,就执行了初始化,从而可能会出现undefined问题。你可以参考本文的方式,将js的加载一同放到function loadTwikoo函数中,而不是用<script is:inline>
  • 感谢指出twikoo.css存在的问题。
 Linux
 Chrome 135.0.0.0
Rimrose
回复 @Cherry :

感谢指点,照着本文的修改确实管用了;顺便这个评论的回复邮件居然被qq邮箱过滤到垃圾邮件了,隔了四天才看到()

 Windows 11
 Microsoft Edge 135.0.0.0
展开
Ylan

报错啦

  Stack trace:
    at Function.entries (<anonymous>)
    at D:\博客\新建文件夹\fuwari\src\components\comment\Twikoo.astro:1:1
    [...] See full stack trace in the browser, or rerun with --verbose.
 Windows 11
 Chrome 134.0.0.0
Cherry Cherry
回复 @Ylan :

Twikoo.astro的第14行,应该从

<script define:vars="{{" config }}>

改为

<script define:vars={{ config }}>

把这两个引号去了应该就可以了,没注意到在什么时候加了两个引号上去(:tv_惊吓:

 Linux
 Chrome 134.0.0.0
Ylan
回复 @Cherry :

好像还是不行😂是直接在src/layouts/Layout.astro中添加吗

function initCommentComponent() {
  const event = new Event("loadComment");
  document.dispatchEvent(event);
}
window.swup.hooks.on("content:replace", () => {
  initCustomScrollbar();
  initCommentComponent(); // 添加代码调用
});
 Windows 11
 Chrome 134.0.0.0
Cherry Cherry
回复 @Ylan :

src/layouts/Layout.astro
initCommentComponent()这个函数加在最外层,比如原有的initCustomScrollbar()附近。


window.swup.hooks.on("content:replace", () => {
  initCustomScrollbar();
  initCommentComponent(); // 添加代码调用
});

这部分则是替换掉原有的content:replace部分。

最后,还需要在function init()这个原有的函数内添加函数调用

function init() {
   // 省略
    initCommentComment(); // 添加
}

我基于Fuwari的最新提交将Twikoo的集成打了个Git patch,你可以参考这个。或者使用git am打这个patch

 Linux
 Chrome 134.0.0.0
展开
查看更多