2022-12-02 更新 根据评论区小伙伴 @MareDevi 的介绍,成功解决了文章浏览量显示的问题,撒花!🌸

想来想去,很多问题还是没有解决,主要还是 Waline 与博客主题不完全兼容,加上自己对前端也不是很了解,最后还是改了回去。真是太折腾了。流石程序员。

# 前言

由于 Valine 评论系统的通知问题以及其他原因,考虑更换 Waline 作为新的评论系统,但是原来的 Shoka 主题使用的是作者修改后的 MiniValine 系统,在修改上碰到了很大的麻烦,最后只能忍痛割爱更换了现在的 butterfly 主题。这次更换也是对博客进行了一个大刀阔斧的修改,但是也摆脱了 Valine 系统这个累赘。原来经常有评论无法及时提醒,而我自己有时候又不会经常上网站查看,因此有的消息过了很久才能发现。最后还是下定决心进行迁移。

经过查找,发现了一个小姐姐提供的修改方法[1],在 Shoka 中能够引入 Waline 。最后还是保留了 Shoka 主题,然后将评论系统换成了 Waline 的系统,虽然还有一些兼容性上的问题,但总归还算保住了现在这个好看的主题。有些小问题折腾了几天也没能完全解决,姑且就到此为止吧。关于遇到的问题,在文章最后一小节有补充。

# 域名注册

这次顺便更换了一个自己的域名。经过一番搜索后选择了 Dynadot 域名商,域名就是现在的 linn-ylz.com 。依照教程[2]购买域名,全部完成之后,使用 CloudflareDNS 服务,参考另一个教程[3]

以上的步骤按照教程基本能够比较轻松地完成,不多赘述。

# 自定义域名

Vercel 中设置自定义域名需要和 Cloudflare 的配置相匹配,具体可以参考这篇教程。需要注意,在 Cloudflare 中,需要将 SSL/TLS 的加密模式设置为完全(Full),否则可能会遇到 “重定向过多” 的错误而无法访问。

# 更换 Waline

按照 Waline教程进行配置。

# LeanCloud 设置

因为之前已经注册配置过 LeanCloud 了,所以这里不再赘述。可以参考之前的文章Shoka 评论推送功能实现

# Vercel 配置

注册 Vercel 完成之后,按照 Waline 的官方教程进行配置。我在这里碰到了一点问题,从 Waline 的入口进入 Vercel 之后,在选择 GitHub 仓库的时无法填写表格,因此无法直接进行 deploy。但是直接选择自己的仓库却又可以。最后只能采用曲线救国的方法,自己 Fork 了仓库,然后再从自己的仓库中进行选择。然而直接 deploy 仓库会报错 This Serverless Function has crashed ,据官方说法,只需要复制 example 文件夹下的内容即可[4]

VercelSettings 中,选择 Environment Variables 添加环境变量,主要是 LEAN_IDLEAN_KEYLEAN_MASTER_KEY 三个值。

如果是使用的国内版的 LeanCloud ,还需要额外设置 LEAN_SERVER 变量。

# 添加自定义域名

参照 Waline 教程中的内容,在 Settings 中选择 Domain 进入域名配置页。教程的说明进行配置。

关于在域名服务器商处添加新的 CNAME 解析记录这一条,由于我是在 Cloudflare 注册的 DNS 服务,因此需要在其中进行配置。

Type Name Value
CNAME example cname.vercel-dns.com
域名配置参数表
Type Name Value
CNAME example cname.vercel-dns.com

按我自己的例子,我的域名是 linn-ylz.com ,我选择的用于 Waline 的域名是 comments.linn-ylz.com ,那么在 Cloudflare 配置中添加 CNAME 配置,名称输入 comments ,对应的值为 cname.vercel-dns.com

Cloudflare 域名配置

上述配置完成之后可以从 Vercel 中打开网页进行评论测试。

# 邮件通知配置

这一部分主要参考 Waline 中的评论通知教程内容。我选择的是其中的邮件通知服务。教程中列举了以下必须配置的内容:

  • SMTP_SERVICE : SMTP 邮件发送服务提供商。
  • SMTP_USER : SMTP 邮件发送服务的用户名,一般为登录邮箱。
  • SMTP_PASS : SMTP 邮件发送服务的密码,一般为邮箱登录密码,部分邮箱 (例如 163) 是单独的 SMTP 密码。
  • SITE_NAME : 网站名称,用于在消息中显示。
  • SITE_URL : 网站地址,用于在消息中显示。
  • AUTHOR_EMAIL : 博主邮箱,用来接收新评论通知。如果是博主发布的评论则不进行提醒通知。

以上变量均在 Vercel 中的环境变量设置中添加。由于官方文档惜字如金,所以这里再详细说一下配置的细节。

SMTP_SERVICESMTP_USERSMTP_PASS 这三项内容是对应发送通知邮件的邮箱。比如我有两个邮箱,一个是 QQ 邮箱,另一个是 Outlook 邮箱,我选择用 QQ 邮箱发送消息到我的 Outlook 邮箱,通知有评论相关的内容到达。那么以上三项内容便需要填写 QQ 邮箱相关的信息。比如 QQ 邮箱的 SMTP_SERVICEQQSMTP_USER 即对应 QQ 邮箱,如 [email protected] 。而 SMTP_PASS 并不是 QQ 邮箱的密码,需要在 QQ 邮箱的 设置 中,找到 账户 选项卡,在 POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 一栏有一个提示,最后有一个生成授权码的可点击链接,点击它之后,会要求你向某个号码发送一条指定内容的短信,发送完成之后会弹窗提示你一个授权码,这个授权码即填写到 SMTP_PASS 中的内容。

SITE_NAME 是消息中显示的网站名称, SITE_URL 则是网站的地址。注意这里填写的地址要包含前面的协议部分,以我自己为例就是 https://linn-ylz.com[5]

AUTHOR_EMAIL 就是用于接收评论通知的邮箱。

以上内容如果均配置正确,那么应该能够正常接收通知了。

# 修复 LeanCloud 数据库格式问题

尽管 Waline 也支持 LeanCloud ,但是在读取其中的内容时,因为数据库表格键值的不匹配会在显示上出现一些问题,这点可能和我之前使用的是 MiniValine 有关。

# 阅读量

首先是阅读量的问题,在 LeanCloud 原来的内容中,存储了之前的网页的访问数量。但是转到 Waline 之后数值却从 00 开始计算了。在 LeanCloud 后台,也发现和原来的文章不算同一个数据列。经过一番排查没有找到很好的解决办法,因此只能把之前的计数值复制到新的数据项之中,因为文章数量不多,操作起来倒也没费太多时间。

# 评论

Vercel 搭建好之后,进入 Waline 的管理平台,发现虽然评论能够正常读取,但是评论的时间显示却存在问题,经排查, Waline 使用的是 insertedAt 列的数据作为评论的发表时间,而之前的数据则是直接使用的 createdAt 列的数据,因此 Waline 读取不到之前评论的发表时间,这里把 createdAt 列的内容复制到 insertedAt 列之后可以正常显示时间了。

另一个问题是在文章的底部没有显示对应的评论,经排查,是因为之前的评论系统使用的路径是 A/B/ 这样的格式,而 Waline 使用的是 /A/B 的格式,相差了一个 / 符号,修正过后,评论能够在文章底部正常显示。

# 网站访问量

网站的访客数量统计使用的是 “不蒜子”,但是其无法进行初始化,因此已经搭建好一段时间的网站的数值便不准确,这里参考这篇文章的办法,在主题文件中修改 card_webinfo.pug 文件,在其中添加以下内容:

script.
        function checkPv(){ 
            var init_pv = parseInt(!{theme.busuanzi.init_pv})
            var pv = document.getElementById("busuanzi_value_site_pv")
            if (pv.innerText === ''){
            setTimeout(checkPv, 100)
            } else {
                pv.innerText = parseInt(pv.innerText) + init_pv
            }
        }
    script checkPv()
    script.
        function checkUv(){ 
            var init_uv = parseInt(!{theme.busuanzi.init_uv})
            var uv = document.getElementById("busuanzi_value_site_uv")
            if (uv.innerText === ''){
            setTimeout(checkUv, 100)
            }else{
                uv.innerText = parseInt(uv.innerText) + init_uv
            }
        }
    script checkUv()

# 在 Shoka 中使用 Waline

如文章开头所述,使用了一个小姐姐提供的方法[1:1],成功将评论系统更换为了 Waline 。虽然如此,但是还存在一些问题。

首先是和 MiniValine 的冲突问题,原来博客中的最近评论和文章浏览量统计是通过 MiniValine 的功能实现的,更换为 Waline 之后便失效了。虽然 Waline 也有提供这些功能,但是由于本人对于前端实在是苦手,因此最后也只是解决了最近评论的问题。文章浏览量统计在很多时候还是不能正常显示,只有通过刷新网页才能够正常显示,最后还是妥协成现在这个状况了。

# 最近评论问题

对于最近评论,我采用的办法是在网页 DOM 结构树生成完成之后,通过 Waline 的 API 接口进行查询,然后输出到网页中。这里的代码参考的是刚才提到的小姐姐的 GitHub 中的相关文件[6]

const getRecentComments = function () {
  console.log("getRecentComments triggered.")
  if (CONFIG.waline.serverURL) {
    var t = document.querySelector(".waline-recent-comments");
    function renderTime(date) {
        let myDate = new Date(date).toJSON();
        return new Date(+new Date(myDate) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '')
    }
    function formatTime(time) {
        let d = Math.floor(time / (1000 * 60 * 60 * 24));
        let h = Math.floor(time / (1000 * 60 * 60) % 24);
        let m = Math.floor(time / (1000 * 60) % 60);
        let s = Math.floor(time / 1000 % 60);
        if (d > 0) {
            return d + ' 天前'
        } else if (h > 0) {
            return h + ' 小时前'
        } else if (m > 0) {
            return m + ' 分钟前'
        } else if (s > 0) {
            return s + ' 秒钟前'
        }
    }
    let str = ' @ '
    let reg = /<.*?>/ig;
    let date = new Date();
    let url = CONFIG.waline.serverURL;
    let count = 10;
    var t = document.querySelector(".waline-recent-comments");
    if (t && !t.classList.contains("loaded")) {
      console.log("load recent comments");
      fetch(url+'/comment?type=recent&count='+count)
        .then(response => response.json())
        .then(data => {
            let arr = data.filter(item => item.pid !== undefined);
            let i = arr.length;
            console.log("total " + i + " comments");
            for (var r = "", o = 0; o < i; o++) {
                let comment = arr[o].comment.replace(reg, '');
                let gap = formatTime(date - new Date(renderTime(arr[o].createdAt)))
                r += `<li class="item"><a href="${arr[o].url + '#' + arr[o].objectId}">
                    <span class="breadcrumb">${arr[o].nick + str + gap}</span>
                    <span>${comment}</span></a></li>`;
                t.innerHTML = r;
                t.classList.add("loaded"); 
                // e.config.pjax && e.config.pjax.refresh(t)
            }
        }).catch(console.error)
      }
  }
}

上述内容我添加在 source/js/_app/pjax.js 文件中,直接添加在最底部即可。上述函数添加后,再添加一个事件监听器:

window.addEventListener('DOMContentLoaded', getRecentComments);

该监听器表示在 DOM 资源生成完毕之后,执行该函数进行查询。

# 文章浏览量统计

文章浏览量统计和最近评论的解决思路类似,也是在 DOM 结构树生成完毕之后,进行查询。

const getPageView = function () {
  console.log("getPageView triggered.");
  if (CONFIG.waline.serverURL) {
    var t = document.querySelector(".leancloud-visitors-count");
    let path = window.location.pathname;
    let url = CONFIG.waline.serverURL;
    if (t) {
      console.log("Load page views");
      console.log("Current page path: " + path);
      let https = url+'/article?path='+path;
      fetch(https)
        .then(response => response.json())
        .then(data => {
          console.log("Pageview: " + data);
          t.innerHTML = data;
        }).catch(console.error);
    }
  }
}
window.addEventListener('DOMContentLoaded', getPageView);

除此之外,还需要修改 layout/_partials/post/footer.njk 这一文件中的内容。首先把 if theme.valine.appId and theme.valine.appKey and theme.valine.visitor 这一语句修改成 if theme.waline.serverURL ,否则在没有 Valine 配置的情况下,文章浏览量的元素不会显示。然后把 <span id="{{ page.path | replace('index.html', '') }}"..."> 这个标签中的内容修改掉,比如我修改成了 <span class="item"> 。这里之所以把 <span> 标签中的内容修改掉是因为我发现如果保留该标签,该数值一直是 00,应该是会被某个脚本执行的内容覆盖掉。具体原理还不明确。

但是这个方法存在的问题是,除非刷新网页,否则浏览数据不会正常显示。

尽管花了很多时间尝试别的方法,但是最后还是没有彻底解决。如果有哪位前端大佬能够不吝赐教,感激不尽。

# 评论系统样式问题

由于 Waline 系统的默认样式和 Shoka 不是非常搭配,因此仍然参考小姐姐的教程[1:2]进行了配置,但是发现并没有生效。经过排查是因为原来主题中存在的 MiniValine 相关的样式覆盖了配置的样式。最好把相关的 MiniValine 的内容全部注释掉。

#

花了几天总算是把博客主题折腾好了。虽然花了不少功夫,还额外给网页增加了几十次浏览量。 还有些问题没有完全解决,但是能够保住这个主题还是很高兴的。只要能保住太原,他要多少我给多少!


  1. 在 Shoka 中添增 Waline 评论系统并自定义样式 ↩︎ ↩︎ ↩︎

  2. Dynadot 网站注册账户、购买域名、支付宝付款、解析域名教程 ↩︎

  3. 使用 Cloudflare 免费 DNS 服务器解析域名到搬瓦工 VPS 主机建站教程 ↩︎

  4. Vercel 重新部署后 Serverless Function has crashed ↩︎

  5. [BUG] 配置邮件通知成功后,无法定位到评论所在的具体文章 ↩︎

  6. 最近评论获取 ↩︎

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Linn 微信支付

微信支付

Linn 支付宝

支付宝