一个简单的评论系统

在设置好pelican的disqus后,一个小小的种子就埋在心里了。应该自己搞一个评论系统啊。随着再次(第n次了)恢复写博客,以及看到disqus那不忍直视的广告,那么...躁动的心起来了!来吧!

竞品

其实不能算竞品,因为形成不了竞争关系。市面上已经有不少云产品或自部署的评论系统了,如果只是要替换disqus,那其实肯定是选另一个已有产品。首先肯定是自部署了,“自主可控”。这里面好像比较有名的是go实现的remark42和python实现的Isso,同时我觉得不错的还有artalk界面很好看。 不过这些项目都比较复杂了,自己造轮子比较困难,我的需求也只是个留言板,反正也没有人评论啊。后来我又发现了cusdis这个其实是满足我的需求的,简单有效。作者Randy还是播客代码之外的主播。cusdis现在还提供云服务。cusdis是使用nextjs和svetle实现前后端的,都是我不会的。 不管怎样,🛞还是要造的,一方面是实现需求,另一方面是通过这个简单的项目验证自己的一些技术栈想法。

功能取舍

第一步先写PRD是不是?最基本功能要有,内嵌到目标页面,根据内嵌页面的url,显示不同的评论,然后访问者可以提交评论。 这里面,用户登陆态是比较不好处理,或者让逻辑复杂的部分,同时在评论这个场景,我觉得需求也不是那么重要,所以首先去掉,一律匿名评论,可以任意填写用户名和邮箱,靠后台审核来确保垃圾评论。这点是和cusdis一样的,不过我看作者的db结构是有一些user provider字段的,可能是想后续支持这个功能。 还有一个地方可以简化,就是多站点支持。目前的这些系统都支持多个站点,就是你部署好评论系统,可以支持给多个不同网站来使用,我不确定他们的管理员用户系统是否也支持不同站点不同管理员。总之,这个地方是可以简化的,就只有一个管理员,只有一个站点(当然可以通过完整url来区分不同的站点)。 至于垃圾过滤,邮件或消息通知,这些刚开始也是没有的,后面看需求了。我看akismet并不便宜啊,以后调用AI chat接口怎么样?

技术栈

之前说了,技术验证也是重要的一方面。我想验证一套go+sqlite+htmx搭建小型服务的流程。这里面go虽然上班用,但是不写http服务,orm也不用的大众库,所以还是很不一样的。sqlite,也没用过。htmx,就更没用过了。

gin

http框架go有不少,这个先选个大众的,因为这方面我觉得先没有太大价值来折腾,找一个出了问题好解决的,插件中间件也会比较丰富。

entgo

db连接方面,我觉得小项目有两个极端方向,要么裸写sql或接近裸写sql,要么用一个大而全的框架。原因是要么项目简单,几句sql能完成需求,那么裸写sql就可以简化代码结构,简化逻辑。而为什么有大而全的orm呢?同样是小项目需求简单,orm可以提供快速的实现功能,不必关心db类型/迁移等,不用去关心一些orm的问题,性能啊/复杂查询/自由度等。 我暂时选择orm方案,因为我的时间不多,快速实现功能还是首要目标。这里选择entgo orm,可能不如gorm用的人多(从ai代码补全也能看出来,到了orm的时候,经常填充的不对),不过我觉得比较好用,函数调用风格我觉得挺好的。 db这块我觉得还是可以再研究一下合适的解决方案的,因为目标是只面向sqlite,所以如果有更有针对性的库,那是最好的。

sqlite

为什么是sqlite呢?其实我也不熟悉,工作中一直是mysql,然后其实最近postgresql也很火。但是对于小型web应用来说,我觉得sqlite还是有很大便捷性的,对于个人项目来说,sqlite可以让复杂性降低,然后最后的产品也会很简洁。不知道大家有没有听说过pocketbase,相当于sqlite版的supabase,算是一种headless cms。配合go,编译出一个文件供用户使用,非常简洁。加上sqlite,一个db一个bin,两个文件直接带走。 sqlite生态还有不少有趣的项目,比如这个litestream,利用sqlite的wal模式,把增量数据备份到s3,来实现准实时增量备份。我也打算把这个集成进我的技术栈里。 还有看起来已经实现分布式功能的libsql

htmx

前端我react和vue我都过过一遍doc的tutorial,但是感觉离实际使用还差很远。而同时,如果要做个页面,我觉得关键好像是在css,这方面真是难的一批。好在现在ai也可以在这方面有所帮助了,tailwindcss在创建时有想到ai让它的流行度再上一个台阶吗? 既然前端学不会,那就用后端的方式来。不知道是什么原因,htmx这个库火了,从我的体验来说,使用体验真的不错。和传统的后端模版工作流还是略有点区别,但是很接近。一旦你适应了这套工作模式,会很顺畅。当然了,它也是“反范式”的,在local first的当下,它是一点也不local,连显示隐藏这这种功能也没有(至少我没找到)。为了点击reply显示回复框,我又引入了alpinejs,是的,又是一个不写js的库。它们两个还是挺搭配的,一个负责网络请求,一个负责本地的动态响应。一起使用可以在不写js的情况下完成页面功能。 go方面还可以配合templ这个库,这相当于用go语法来写html,有点react的感觉,当然仅仅是模版渲染方面,不包含动态的数据处理。

tailwindcss & daisy ui

页面ui这块是真不会。我照着cusdis开始写div,慢慢问ai了解各个class是什么意思,然后修改。这块没什么好说的。

功能

目前就只有留言和显示留言和审批留言的基本功能。dockerfile还在调试,autotls我还没有测试成功,readme没有写,页面高度自动调整还有问题,还差很多东西。未来想集成liteatream自动备份db数据,黑白主题,自定义primary color(看了verge的评论区,感觉那条紫线很好看),通知,自动垃圾过滤?更方便的初始化,评论数接口等等吧。