Featured image of post 【建站技术】HUGO 博客中如何记录浏览量和网站运行时间

【建站技术】HUGO 博客中如何记录浏览量和网站运行时间

本文将分享如何在 HUGO 博客中记录每个页面的浏览量(基于 Waline),以及如何在页面底部添加一个动态刷新的网站运行时间指示器。

引言

之前给博客引入了评论系统 Waline,根据 Waline 官方文档的介绍,了解到可以通过 Waline 在个人博客网站中加入浏览量统计的功能。由于本次需要修改博客的底部面板,并需要添加 JavaScript 代码,顺便给我的个人博客加入了动态刷新的建站时间指示器。

基于 Waline 的浏览量统计

Waline 评论系统自带了浏览量统计的功能,如何配置 Waline 的评论系统可以参考《【建站技术】为你的 Hugo 博客加入评论功能 (Waline)》。或者你也可以阅读 Waline 官方文档-浏览量统计,只引入浏览量统计能力而不引入评论能力。

HUGO 配置

在配置文件中,设置 comments-waline 属性中的 pageview 为 true 即可自动开启浏览统计功能。

1
2
waline:
    pageview: true

浏览量显示

开启浏览量统计能力后,waline 会在初始化时(有开启评论的页面将会自动初始化)给带有 class="waline-pageview-count" 的 html 元素自动更新为当前页面的浏览数量。 可以在文章的任意地方,插入类似以下代码,来展示本页面的浏览量。

1
<span class="waline-pageview-count" data-path="<your/article/path>">···</span>

其中,data-path 属性决定了页面路径,如果不填则默认为当前页面。
如果你想把浏览量显示加入到文章头部状态栏中,可以在对应的模板代码中加入类似以下代码:

1
2
3
4
5
6
7
<div>
    {{ partial "helper/icon" "pageview" }}
    <time class="article-time--reading">
        {{ T "article.pageview" }}
            <time class="waline-pageview-count" data-path="{{ .RelPermalink }}">···</time>
    </time>
</div>

其中,{{ partial "helper/icon" "pageview" }} 是浏览量对应的 icon,{{ .RelPermalink }} 属性则能够获取到当前页面的路径。

文章列表中显示浏览量

当你做完上述设置后,就可以在文章页面的头部状态栏中看到当前页面的浏览量了。但是,当你返回首页或者其他文章列表页面时,会发现每篇文章的浏览量不能正常显示了,这是因为 waline 只会在评论功能初始化时拉取数据,要想在没有评论系统的页面展示浏览量信息,则需要手动请求对应的数据。
这里借鉴了 Jqtmviyu 大佬的文章 《为Hugo博客添加评论和统计功能》,并对代码做了部分修改,将以下代码引入页面 footer 或 header 的模板中,就可以自动拉取页面中每篇文章的浏览数据了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<script>
    (async ()=>{
      let indexCountEle = document.querySelector('.waline-index-count')
      let walineUrl = indexCountEle.getAttribute('waline-url')

      let pageCountEles = document.querySelectorAll('.waline-pageview-count')
      let pagePathNames = Array.from(pageCountEles).map(item => item.getAttribute('data-path'))

      // 获取访问统计函数
      function getViewCount (urlList) {
        let url = walineUrl + 'api/article/?path='
        urlList.forEach((item,index) => {
          url += index === 0 ? item :  (',' + item)
        })
        return fetch(url)
        .then(res => res.json())
        .then(res => {
          if(res.errno == 0) {
            return res.data.map(item => item.time)
          } else {
            throw new Error('获取失败')
          }
        })
        .catch(err => {
          return new Promise((resolve,reject) => {
            reject(err)
          })
        })
      }
      // 添加访问统计函数
      function addViewCount (pathname) {
        let data = { path: pathname}
        return fetch(`${walineUrl}/api/article`,{
            method:'POST',
            headers: {
              'Content-Type': 'application/json'
            },
            body:JSON.stringify(data)
        })
        .then(res => res.json())
        .then(res => {
          if(res.errno == 0) {
            return res.data[0].time
          } else {
            throw new Error('获取失败')
          }
        })
        .catch(err => {
          return new Promise((resolve,reject) => {
            reject(err)
          })
        })
      }

      // 获取列表页的访问统计
      if(window.location.pathname == '/' || window.location.pathname.includes('/posts/')){
        getViewCount(pagePathNames).then(pageCounts => {
          pageCounts.forEach((item,index) => {
            pageCountEles[index].innerText = item
          })
        })
      }

      // 更新页面底部访问统计,localStorage记录访问时间和访问统计
      // 没有访问过,往api添加访问记录并更新访问统计
      // 在1小时内访问过,从本地存储拿
      // 超过1小时,重新获取
      let indexCount = localStorage.getItem('indexCount')
      let lastVisitTime = localStorage.getItem('lastVisitTime')
      if (!!lastVisitTime == false) {
        addViewCount('/').then(indexCount => {
          localStorage.setItem('indexCount',indexCount)
          localStorage.setItem('lastVisitTime', Date.now())
          indexCountEle.innerHTML = indexCount
        })
      }
      if(!!lastVisitTime && !!indexCount && Date.now() - lastVisitTime < 3600000 ){
        indexCount = localStorage.getItem('indexCount')
        indexCountEle.innerHTML = indexCount
      }
      if(!!lastVisitTime && Date.now() - lastVisitTime >= 3600000){
        getViewCount(["/"]).then(res => {
          indexCount = res[0]
          localStorage.setItem('indexCount',indexCount)
          localStorage.setItem('lastVisitTime', Date.now())
          indexCountEle.innerHTML = indexCount
        })
      }
    })()
</script>

网站总浏览量统计

细心的朋友会发现,上面的代码包括了对整个站点的浏览量更新,因此我们可以在 footer 模板中加入以下代码来显示站点的浏览量信息。

1
 <span class="waline-index-count waline-pageview-count" waline-url="{{ .Site.Params.comments.waline.serverURL }}" data-path="/">0</span>

网站运行时间指示器

由于本次需要修改博客的底部面板,并需要添加 JavaScript 代码,因此顺便给我的个人博客加入了动态刷新的建站时间指示器。

计时代码

类似浏览量统计,将以下代码引入页面 footer 或 header 的模板中,就可以每秒自动更新网站的运行时长数据。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
  function updateTime() {
      const targetDate = new Date("2024-09-19T00:00:00");
      const now = new Date();
      const diff = now - targetDate;

      if (diff > 0) {
          const seconds = Math.floor((diff / 1000) % 60);
          const minutes = Math.floor((diff / (1000 * 60)) % 60);
          const hours = Math.floor((diff / (1000 * 60 * 60)) % 60);
          const days = Math.floor(diff / (1000 * 60 * 60 * 24));

          const timeString = `${days}d ${hours}h ${minutes}m ${seconds}s`;
          document.getElementById("overTime").textContent = timeString;
      }
  }
  // 初始化立即执行一次
  updateTime();
  // 每秒更新
  setInterval(updateTime, 1000);
</script>

这段代码将每秒运行一次,并对 id 为 overTime 的标签进行赋值。

计时显示

与总浏览量的显示相同,在 footer 模板中添加以下代码即可显示网站运行时长。

1
<span id="overTime" style="font-weight: bold;">0day</span>

尾声

至此,你就可以在看到每个页面的浏览量信息,并且在网站底部拥有一个动态更新的网站运行时长指示器啦~

作者信息

邮箱: [email protected] 欢迎交流技术知识

本文原载于 jianyese.com,遵循 CC BY-NC-SA 4.0 协议,复制请保留原文出处。

使用 Hugo 构建,  主题 StackJimmy 设计,  
浏览量: 0,   本站已运行: 0day