什么是 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)
,这将会导致一种错误。
显然,当远程文件未加载完成时,将会概率触发这个问题,未加载完成时就调用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.astro
的function init()
函数内,需要添加对initCommentComponent()
函数的一次调用,这样在打开网页时我们的评论将会被正确加载。
随后紧接着我们还需要在swup
的hooks
部分,添加对这个函数的调用。如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>
Twikoo 主题魔改
在上一节中,我们成功给 Fuwari 主题接入了 Twikoo 评论系统,但 Twikoo 的默认主题与 Fuwari 主题显得并不协调,我们希望能够将其强调色与 Fuwari 统一。并且在黑暗模式下,文本颜色并不会随 Fuwari 变化,仍然显示为默认的黑色,导致难以辨认,这我们可以通过修改 twikoo 的样式来解决。
这里 Twikoo 的样式其实是其twikoo.all.min.js
中所内嵌的样式,当然 Twikoo 也提供了不内嵌 css 的版本供用户使用,从而能够更深度的自定义 Twikoo。在Twikoo 文档中,对不同的 js 文件的功能进行了划分。
我们仍然选择带有内嵌 css 的版本,从而在 Twikoo 内嵌样式的基础上去覆盖 Twikoo 原有样式,当然,从头开始定义 Twikoo 的样式亦可。由于我们仍然选择了内嵌 css 的版本,对 twikoo 的引入部分无需更改。
在src/styles
创建 css 文件,文件名任取,在这里的样式将会被自动加载,我们可以在浏览器的审查模式下,对指定元素进行选中,并根据各个元素的类名,对元素进行选中,并使用 CSS 对其样式进行修改。
在这里,我们使用SCSS
语法与Tailwindcss
来简化开发,完整的 CSS 文件可以在我的Github Gists中下载。将 CSS 应用到 Fuwari 中,我们即可得到一个适配 Fuwari 主题强调色的 Twikoo 评论界面(整体布局布局参考自「园子里的时光」博客)。当然,也可以在我的 CSS 文件中,对主题进行进一步的修改。
其余问题
单击按钮返回顶部
参见Twikoo-Issues-731,目前可以通过修改 Twikoo 源码,将<a>
标签内href="#"
去除,再对 Twikoo 重新编译,并替换 Twikoo 导入。(待寻找更好的方法)
感谢!非常好参考
我跟着 给你的 Fuwari 接入 Twikoo 评论 这篇博文成功添加了 Twikoo 的支持,但是在跟着本文尝试添加事件监听的时候一直没成功,最终写成这样也还是不行:https://github.com/SirTamago/Blog-astro-fuwari/blob/main/src/components/comment/Twikoo.astro
另外,给 twikoo.css 添加一段这个可以让表情组件在表情包数量太多的时候正确显示(不然会被遮挡):
Twikoo.astro
仅接受来自swup
的事件,便于确定加载评论的时机。因此其本身无需发送事件,最后三行可以删除。<script is:inline>
内联式的加载twikoo.all.min.js
可能导致在其未加载完成时,就执行了初始化,从而可能会出现undefined
问题。你可以参考本文的方式,将js的加载一同放到function loadTwikoo
函数中,而不是用<script is:inline>
。twikoo.css
存在的问题。感谢指点,照着本文的修改确实管用了;顺便这个评论的回复邮件居然被qq邮箱过滤到垃圾邮件了,隔了四天才看到()
报错啦
Twikoo.astro的第14行,应该从
改为
把这两个引号去了应该就可以了,没注意到在什么时候加了两个引号上去(
好像还是不行😂是直接在src/layouts/Layout.astro中添加吗
在
src/layouts/Layout.astro
中initCommentComponent()
这个函数加在最外层,比如原有的initCustomScrollbar()
附近。这部分则是替换掉原有的
content:replace
部分。最后,还需要在
function init()
这个原有的函数内添加函数调用我基于Fuwari的最新提交将Twikoo的集成打了个Git patch,你可以参考这个。或者使用
git am
打这个patch