Update:
2024.12.28 尝试引入Github discussions
-Giscus
评论系统.
为什么需要这个系统
- 因为
Quartz
暂时还不支持评论功能 - 如果有评论的话能够更方便的得到反馈
- 依赖评论系统,可以顺便支持访问统计、访客印象等信息。
这里使用的是 Waline
进行评论系统的搭建
为什么要用
Waline
?因为成本低,因为搭建起来方便, 因为目前只找到这个最合适
简要掠过一下搭建过程
Waline
接入Quartz
博客方法
简单方法
直接粘贴一下代码段到你的markdown笔记中即可。
可以让AI帮忙写个脚本在发布前手动执行一下就能自动插入代码(注意要检测是否已经插入过,不要重复插入,可以过滤是否存在https://unpkg.com/@Waline/client@v3/dist/Waline.js
,存在就不重复插入,并且要事先做好数据备份,防止把文件写坏。)
把 换成你部署的服务端url
换成你实际上部署的客户端URL即可
并且 dark: 'html[saved-theme=\'dark\']',
( ) 要换成你实际使用博客的主题变换样式,具体在这里看描述,以便支持动态跟随系统切换暗黑模式。Quartz
不要写双引号,会被过滤的
封装Waline
评论成为Quartz
组件的方法
因为此博客用的是 Quartz
,因此可以通过编写组件的方式来支持所有页面自动插入对应的 Waline
组件,实现自动展示评论。
Quartz
的框架实现
为了写Quartz
的组件, 首先要看下它的实现框架: Architecture (jzhao.xyz)
简单来说就是依赖 bootstrap-cli.mjs
实现了markdown
文本解析,并注册了一大堆复杂的回调结构和钩子,在支持Preact框架的情况下,实现在文本转换、对象前和后构建的时候执行一些javascript
代码实现对静态页面内容的动态调整,同时依赖 SPA
框架实现只加载部分页面提升访问体验。
基于他可以调用
javascript
代码、写JSX
这一点,就可以确定,构建Waline
Quartz
组件的方案是可行的。
Quartz
的组件调用位置
Quartz.layout.ts
里面定义了各个组件的布局,具体参见: Layout (jzhao.xyz)
其中里面有个 Component.Footer()
底部组件是本次要下手(参考)的对象。
Quartz
的组件集成方式
简单看一下这个 Footer
组件,简单来说就是 传入 了 一些 Options
的结构(这个结构具体看这里 Creating your own Quartz components (jzhao.xyz) ),
然后 在 JSX
的支持下,在函数内实现了组件的编排,通过 return
返回构建的组件 DOM
内容,也就是 Html
内容,然后并且通过 Footer.css = style
方式指定样式,通过 Footer.afterDOMLoaded = script
方式指定组件加载完成后要执行的 javascript
脚本的字符串代码( beforeDOMLoaded
是组件加载前执行的代码 )。
也就是说,本次要改 return
和 afterDOMLoaded
的部分
新建 Waline
组件
Html
内容生成
前面讲了为了实现 Waline
要写两部分,首先是 Html
的部分, 直接把 Html
写在一个文件封装好,让外部导入就行,内部通过 Link 引入了评论的 css
样式
Javascript
代码编写
安装依赖
import
一下然后直接导入 init ,传入 {你的Waline客户端URL}
就能完成初始化,然后刷新下页面就能看到评论的出现。
但是这样会有个问题,就是 Waline
是支持重复调用,自动清理资源的,因为 Quartz
SPA
支持的代码实现中,把原来的 Waline
代码会覆盖掉,然后会导致 Waline
清理资源出问题,
简单来说就是你切换一下其他url,不刷新,就只能显示一次,解决方法是主动清理资源,又因为 Quartz
的传参和上下文保存比较麻烦,直接用全局变量保存,然后后面检测释放,代码如下:
这样子就能随意切换切换文件也能展示评论了
然后还有两个地方需要注意一下,404 页面的时候检测一下,不需要添加评论组件
通过组件方式接入Quartz
框架
components/Waline.tsx
将组件布局到界面中展示
quartz.layout.ts
Waline
的附加功能
文章反应、浏览量统计等功能在这里查看: 功能 | Waline
整体 Waline
Quartz
代码实现在这里
- 组件调用处:
quartz.layout.ts
:quartz.layout.ts (github.com) - 组件定义:
components/Waline.tsx
: app_blog/quartz/components/Waline.tsx at blog · observerkei/app_blog (github.com) - 组件
DOM
和实现代码:见下面
评论的实现代码
comment-DOM
comment-Javascript
特别的,如果你想通过 afterDOMLoaded
/beforeDOMLoaded
同时执行多个脚本,在其他脚本是 export default
情况下, 可以这样使用,然后在另一个地方直接引入这个文件赋值给 afterDOMLoaded
/beforeDOMLoaded
属性([[#quartz-的组件集成方式|Quartz
的组件集成方式]]):
设置邮件通知
具体设置方法在: 评论通知 | Waline
这里就不重复赘述了。
搭建的时候碰到的问题
Quartz
并不是使用React
实现的 ,不直接支持React
语法和组件,- 也不能直接使用
Vue
,不支持直接写Vue
(虽然我也不打算写) - 需要通过
Javascript
字符串代码导入方式来写专用组件才能够被调用😂。直接写函数不行,直接 export 也不行,Quartz
框架组件代码执行方式限制了使用方法。上面给出了解决方法。 - 你不能直接在他写的
Html
导入框架里面直接导入Waline
Waline
在组件还在的时候能重复初始化,但是组件被清理之后(Html
的部分),不能重复调用,会报找不到DOM
的异常,因为使用了SPA
, 需要主动取释放资源。Quartz
的组件不能方便的互相调用,主要是脚本的部分,他是直接以文件方式导入成字符串文本,然后以文本方式解析JavaScript
的脚本,再去执行,这样你写多个模块的时候,如果有多个脚本的话,就得再写个脚本,调用其他脚本之后,再提供给Quartz
组件调用,因为是多个文件,封装起来不太优雅。Waline
渲染组件默认用URL路径,如果后续文件路径变更,那么评论就会对不上,,这个问题可以通过.obsidian
插件给笔记计算唯一SHA256
作为ID,然后让Waline
初始化时候path
传入这个ID解决;- 如果访问 404 页面,其实也会显示评论组件,需要调整显示策略,具体怎么做见上面代码。
~~原本不想折腾这个插件的,~~从
Quartz
的复杂插件传递方式来看他限制住了客户端编写 JSX 代码的的灵活性(目前必须通过字符串
引入代码),这是后续可以优化的地方(就像上面提供的放在一个脚本里面的方法其实就可以在内部进行封装), 以及DOM
和他配套的Javascript
代码分开存放就会导致项目文件变得很多,不易阅读(实际上你要改相关代码也得两个部分一起看才能下手),可能是出于性能考虑所以没有用React
吧(随着设备性能的提高好像也不会差多少),
虽说如此,
Quartz
确实是个好的开源项目,前面说的只是一些细节上可以优化的点,使用Javascript
在浏览器的支持下可以通过B/S
架构提供良好的跨平台特性,它能灵活的设定移动端和桌面的显示组件,支持暗黑模式,并且提供了插件和组件的自定义拓展方式,增强了拓展性和功能性,更易于延长项目的生命周期,实现代码复用,在组件化的支持下可以实现很多功能拓展(比如评论功能)。