写点什么

深入浅出 Gitalk 留言插件

发布于: 2 小时前
深入浅出 Gitalk 留言插件

你好,我是悟空。


本文已收录至 Github,欢迎 Star:https://github.com/Jackson0714/PassJava-Learning

个人网站:www.passjava.cn

本文主要内容如下:


一、背景

我的开源项目 PassJava 有个在线的技术文档,但是没有评论功能,总感觉缺了点什么,这次来给它加上留言功能。


最后留言的效果图如下:



文档演示地址:http://www.passjava.cn


之前做了一个介绍 PassJava 的短视频,大家可以双击 666 哦!


《插入视频》


首先我的这个文档网站是基于开源的 docsify 的:


docsify 是一个动态生成文档网站的工具。不同于 GitBook、Hexo 的地方是它不会生成将 .md 转成 .html 文件,所有转换工作都是在运行时进行。


如果只是需要快速的搭建一个小型的文档网站,或者不想因为生成的一堆 .html 文件“污染” commit 记录,只需要创建一个 index.html 就可以开始写文档而且直接部署在 GitHub Pages



开源项目 PassJava 地址:https://github.com/Jackson0714/PassJava-Platform,欢迎 Star。

本文已收录至:www.passjava.cn


那如何给 docsify 添加评论呢?这里就是要用到 Gitalk 了。

二、Gitalk 介绍

Gitalk 是一个基于 GitHub Issue 和 Preact 开发的评论插件


扩展知识:Preact 是 React 的 3KB 轻量级替代方案,它拥有着和 React 一样的 API。React 用于构建用户界面的 JavaScript 库。

2.1 Gitalk 特性

  • 使用 GitHub 登录。

  • 支持多语言。

  • 支持个人或组织。

  • 无干扰模式(设置 distractionFreeMode 为 true 开启)。

  • 快捷键提交评论 (cmd|ctrl + enter)。

2.3 Gitalk 原理

2.3.1 原理介绍

Gitalk 嵌入到个人网站中,然后利用了 Github 的 Issue 功能,把 Github 的 Issue 中的 Comments 当作某篇文章的评论。当然,这些功能都是 Gitalk 自带的,我们不用关心,这里我还是剖析下 Gitalk 的原理。



Github 的 Issue 功能,可能大家不知道,可以理解为贴吧的帖子,我截个图大家就懂了。在 Github 的开源项目中,Issue Tab 下可以提出问题,也可以在里面加 comments(评论)。


2.3.2 添加评论的原理

首先创建评论时 Gitalk 会调用 Github API 在 Github 的 Issue 中添加 Comments。我们也可以到 Github 的 Issue 中查看评论或者添加评论。


添加评论的 API:


https://api.github.com/repos/Jackson0714/PassJava-Learning/17/comments
复制代码


请求的参数:


{  body: "有什么问题吗?"}
复制代码


如下图所示:


2.3.3 获取评论列表

当我们打开网站查看评论列表时,Gitalk 会根据仓库名标签 获取 Github 上 Issue 的评论列表。


获取评论列表请求的 API:


https://api.github.com/repos/Jackson0714/PassJava-Learning/issues
复制代码


如下图所示:



仓库名:PassJava-Learning


标签:Gitalk、02.PassJava 架构篇/24.缓存实战(四)SpringCache

2.3.4 授权

Gitalk 要想使用 Github 的 Issue 功能,则需要在 Github 上创建一个授权应用,拿到应用的 id 和 密钥配置到 Gitalk 脚本中就可以了。

2.3.5 显示评论功能

Gitalk 提供了评论功能的 JavaScript 脚本和评论的样式,直接在网站中引入即可。后面会有详细的配置方法。

三、配置 Github 的授权应用

Gitalk 是借助 Github 的仓库的 Issues 功能的,所以我们需要在 Github 上配置授权应用(GitHub OAuth application),让自己的网站能够通过这个授权应用将评论放到 Issues 上。


创建 GitHub OAuth application流程:


1、打开 github 网站登陆后,点击右上角的用户图标,选择Settings2、 在Settings页面选择Developer settings选项。3、在Developer settings选择OAuth Apps,然后会在页面右边有一个New OAuth App按钮,点击这个按钮就进入到新建OAuth application页面 4、也可以直接代开这个链接:进入新建页面


https://github.com/settings/applications/new


如下图所示:



接着填写应用的基本信息:App name,任意填写,Homepage URL 和 Callback URL 填写网站的域名,两个地方的域名保持一致,如下所示:



点击 Register Application 就可以创建成功了,会生成应用的 id 和密钥,如下图所示。这两个信息在配置 gitalk 的时候用到,非常重要。而且 secret 你要第一时间备份下,后面再进来就是隐藏的了,除非重新生成一个新的。


四、如何引入 Gitalk

官方的使用方式很简单,直接在自己的网站中加入 Gitalk 的脚本库文件和 css 文件


<link rel="stylesheet" href="//cdn.bootcss.com/gitalk/1.5.0/gitalk.min.css"><script src="//cdn.bootcss.com/gitalk/1.5.0/gitalk.min.js"></script>
复制代码


在 html 文件中添加一个容器,Gitalk 组件会在此处显示


<div id="gitalk-container"></div>
复制代码


然后使用下面的 JavaScript 代来生成 Gitalk 评论


var gitalk = new Gitalk({  clientID: '7de8e380bec2231f0544', // GitHub Application Client ID  clientSecret: 'xxxx', // GitHub Application Client Secret  repo: 'PassJava-Learning'      // 存放评论的仓库  owner: 'Jackson0714',          // 仓库的创建者,  admin: ['Jackson0714'],        // 如果仓库有多个人可以操作,那么在这里以数组形式写出  id: location.pathname,      // 用于标记评论是哪个页面的,确保唯一,并且长度小于50})
gitalk.render('gitalk-container'); // 渲染Gitalk评论组件
复制代码


更多参数介绍详见本文附录。

五、改造 Gitalk 的脚本

Gitalk 官方提供的使用脚本对于我用 docsify 搭建的网站有些不足之处,所以我就动手自己改了。

5.1 问题一:URL 中文转义问题

首先我的网站每个页面的标题都携带了中文,比如这个:


http://www.passjava.cn/#/94.Git/01.Git常见问题
复制代码


如果评论这篇文章,就会在我的 PassJava-Learning 仓库的 issues 中生成一个 url 编码后的标题:


就像下面这样,没人看得懂吧,所以需要在 gitalk 的脚本中 url 解码 下。



加一行解码的代码搞定:


decodeURI(title)
复制代码


当然,如果你不需要到 github 上来看留言记录或者删除留言记录,这个标题其实无所谓,主要是为了后期好找哪篇文章有评论。

5.2 问题二:截取标题

因为 docsify 是用 # 符号来表示每篇文章的 url 的,我想把 # 符号后面的取出来。比如下面这个:


http://www.passjava.cn/#/02.PassJava架构篇/22.缓存实战(二)Redis分布式锁
复制代码


我只想要 02.PassJava架构篇/22.缓存实战(二)Redis分布式锁 作为标题。改造如下:


title = location.hash.match(/#(.*?)([?]|$)/)if (title != null) {  title = location.hash.match(/#(.*?)([?]|$)/)[1]}title = decodeURI(title.substring(1, title.length))
复制代码

5.3 问题三: Gitalk id 只支持 50 个字符

id 和 title 我都是用的 URL 中 # 后的标题。有时候标题太长了,导致发起评论和加载评论。页面会报 create-issues api 问题。


所以我就把 id 和 title 限制在 50 个字符以内,如果超出了就用 home page作为 id 和 title。


// 限制 50 个字符if (title != null) {    title = decodeURI(title.substring(1, title.length))    if (title.length >= 50) {        title = title.substring(title.length - 50, title.length)    }} else {    title = 'home page'}
复制代码


经过上面的改造后,Gitlab 中 issue 的列表就是下面这样了



大家可以看到有两个标签,一个是 Gitalk,一个是 url 标题,Gitalk 就是通过这两个标签来获取评论列表的,我们可以点一个 issue 进去看下:



因为 Gitalk 是基于 Gitlab 的 Issue 功能,所以我们可以直接在 issue 里面加评论的,博客上会同步显示这些评论哦。


注意:千万别点 close issue 按钮,关闭 issue 后,评论就都看不到了,而且即使你再 reopen issue,也不行。只能重新在博客评论,但是会在 Github 上自动新建一个 issue,不能和之前的评论关联起来,有点坑呀。。

5.4 问题四:切换文章后,评论列表未变

由于 docsify 的链接 URL 使用的是 hash 的方式,导致切换页面的时候不会刷新页面,导致整个网站的 Gitalk 评论使用的是一个评论,因此做了监听 hash 事件,来刷新页面,这样就能每次切换页面刷新,然后加载对应的评论。


window.onhashchange = function(event) {    if(event.newURL.split('?')[0] !== event.oldURL .split('?')[0]) {        location.reload()    }}
复制代码


经过改造的代码,在公众号悟空聊架构回复 博客获取。

六、遇到的坑

在使用 Gitalk 也遇到了一些奇怪的问题,这里做个记录:

6.1 收到一堆提醒邮件

这个问题是我的好朋友 飞羽 提出的。


如果你在某篇文章中评论了, 如果有其他人跟帖,你也会收到 Gitlab 的邮件提醒哦,类似朋友圈功能。



如果你想取消掉,直接在你评论的 issue 里面取消订阅就可以了。如下图所示:


6.1 未找到相关的 issues 进行评论


用 F12 调试工具看了后,是因为自己写的 JS 报错了。

6.2 HTTP 请求 401 权限问题

这是因为我最开始创建的 Github 应用是 Github App 而不是 OAuth App,这里大家注意下。

6.4 每篇文章对应的评论都是一样的

需要在切换文章时,重新给 location 变量赋值,详见本文 5.4 的改进代码。

6.5 HTTP 请求 422 问题

id 太长了,修复代码详见本文 5.3。


经过改造的代码,在公众号悟空聊架构回复 博客获取。


七、附录

7.1 主要的参数

  • clientID 类型:字符串,必填,申请的OAuth AppClient ID

  • clientSecret 类型:字符串,必填,申请的OAuth AppClient Secret

  • repo 类型:字符串,必填,github 上的仓库名字,用于存放 Gitalk 评论

  • owner 类型:字符串,必填,github 仓库的所有者的名字

  • admin 类型:数组(元素是字符串),必填,github 仓库的所有者和合作者 (对这个 repository 有写权限的用户)

  • id 类型:字符串,选填,页面的唯一标识。长度必须小于 50。此参数用于评论和页面对应的标识,如果想让两个页面用一个评论,可设置两个页面的 id 一样。默认值:location.href(页面 URL)

  • title 类型:字符串,选填,GitHub issue 的标题,默认值:document.title(HTML 中 title 标签中的值)


注意


虽然idtitle参数是不是必填的选项,但是这个两个参数很重要建议填上:


1、id参数用于评论记录和页面对应的唯一标记,有的时候发现好几个页面评论是一样的,就是由于配置id参数的时候,这几个页面的 id 是一样导致。由于id参数默认值是location.href页面 URL,而有的时候 URL 中带着页面标题的链接,导致 URL 长度超过了 50 个字符长度,会导致创建评论 issues 失败(长度超过 50 个会创建失败),这点要注意。


2、title用于在 Github 仓库 issues 的标题,如果你想管理评论可以设置一下这个参数,来区分该评论是来自于那个文章。

7.2 其他参数

number: 类型:数字,选填,页面的 issue ID 标识,若未定义 number 属性则会使用 id 进行定位。默认值:-1。


labels:类型:数组,选填,GitHub issue 的标签,默认值:Gitalk


body:类型:字符串,选填, GitHub issue 的内容,默认值:URL + HTML 中 meta 标签中 description 的值。


language:类型:字符串,选填,设置语言,支持 [en, zh-CN, zh-TW]。默认值:navigator.language 或者 navigator.userLanguage。


perPage:类型:数字,选填,每次加载的数据大小,最多 100。默认值:10。


distractionFreeMode:类型:布尔值,选填,类似 Facebook 评论框的全屏遮罩效果。默认值:false。


pagerDirection:类型:字符串,选填,评论排序方式,last为按评论创建时间倒叙,first为按创建时间正序。默认值:last。


createIssueManually:类型:布尔值,选填,如果当前页面没有相应的 isssue 且登录的用户属于 admin,则会自动创建 issue。如果设置为 true,则显示一个初始化页面,创建 issue 需要点击 init 按钮。 默认值:false。


proxy:类型:字符串,选填,GitHub oauth 请求到反向代理,为了支持 CORS。默认值:https://cors-anywhere.herokuapp.com/https://github.com/login/oauth/access_token


flipMoveOptions:类型:对象,选填,评论列表的动画。参考 react-flip-move


enableHotKey:类型:布尔值,选填,启用快捷键(cmd/ctrl + enter)提交评论。默认值:true。


参考资料:


https://segmentfault.com/a/1190000018072952


https://github.com/gitalk/gitalk


开源项目 PassJava 地址:https://github.com/Jackson0714/PassJava-Platform,欢迎 Star。

本文已收录至:www.passjava.cn


欢迎关注我的公众号:「悟空聊架构


我的 Github


作者简介:8 年互联网职场老兵|全栈工程师|90 后超级奶爸|开源践行者|公众号万粉原创号主。 蓝桥签约作者,著有《JVM 性能调优实战》专栏,手写了一套 7 万字 SpringCloud 实战总结和 3 万字分布式算法总结。 欢迎关注我的公众号「悟空聊架构」,免费获取资料学习。


我是悟空,努力变强,变身超级赛亚人!

发布于: 2 小时前阅读数: 6
用户头像

用故事、大白话讲解Java、分布式、架构设计 2018.05.06 加入

公众号:「悟空聊架构」

评论

发布
暂无评论
深入浅出 Gitalk 留言插件