6000 字 | 终于,给网站插上了留言的翅膀

这是悟空的第 111 篇原创文章css

本文主要内容以下:

1、背景

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

最后留言的效果图以下:java

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

以前作了一个介绍 PassJava 的短视频,你们能够双击 666 哦!git

一款基于 Spring Cloud 的面试刷题系统github

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

docsify 是一个动态生成文档网站的工具。不一样于 GitBook、Hexo 的地方是它不会生成将 .md 转成 .html 文件,全部转换工做都是在运行时进行。面试

若是只是须要快速的搭建一个小型的文档网站,或者不想由于生成的一堆 .html 文件“污染” commit 记录,只须要建立一个 index.html 就能够开始写文档并且直接部署在 GitHub Pages。小程序

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

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

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

2、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。

仓库名是配置出来的,标签是 Gitalk 自动获取的。

2.3.4 受权

Gitalk 要想使用 Github 的 Issue 功能,则须要在 Github 上建立一个受权应用,拿到应用的 id 和 密钥配置到 Gitalk 脚本中就能够了。

2.3.5 显示评论功能

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

3、配置 Github 的受权应用

Gitalk 是借助 Github 的仓库的 Issues 功能的,因此咱们须要在 Github 上配置受权应用(GitHub OAuth application),让本身的网站可以经过这个受权应用将评论放到 Issues 上。

建立 GitHub OAuth application流程:

一、打开github网站登录后,点击右上角的用户图标,选择Settings

二、 在Settings页面选择Developer settings选项。 

三、在Developer settings选择OAuth Apps,而后会在页面右边有一个New OAuth App按钮,点击这个按钮就进入到新建OAuth application页面。

四、也能够直接代开这个连接:进入新建页面。

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

以下图所示:

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

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

4、如何引入 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评论组件

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

5、改造 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 中 # 后的标题。有时候标题太长了,致使发起评论和加载评论。页面会报 Github 的 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()
    }
}

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

6、遇到的坑

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

6.1 收到一堆提醒邮件

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

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

若是你想取消掉,直接在你评论的 issue 里面取消订阅就能够了。以下图所示:

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

用 F12 调试工具看了后,是由于本身写的 JS 报错了。

6.3 HTTP 请求 401 权限问题

这是由于我最开始建立的Github 应用是 Github App 而不是 OAuth App,这里你们注意下。

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

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

6.5 HTTP 请求 422 问题

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

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

6.6 Github 访问太慢了

7、附录

7.1 Gitalk 主要的参数

  • 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参数是否是必填的选项,可是这个两个参数很重要建议填上:

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

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

7.2 Gitalk 其余参数

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

- END -

写了两本 PDF, 回复  分布式  或  PDF  载。
个人 JVM 专栏已上架,回复  JVM  领取

我是悟空,努力变强,变身超级赛亚人!
点击阅读原文体验留言功能

本文分享自微信公众号 - 悟空聊架构(PassJava666)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索