hexo-theme-fluid 1.9.6 → 1.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -135,7 +135,7 @@ layout: about
135
135
 
136
136
  英文文档翻译:[@EatRice](https://eatrice.top/) [@橙子杀手](https://ruru.eatrice.top) [@Sinetian](https://sinetian.github.io/)
137
137
 
138
- 其他贡献:[@zhugaoqi](https://github.com/zhugaoqi) [@julydate](https://github.com/julydate)
138
+ 其他贡献:[@zhugaoqi](https://github.com/zhugaoqi) [@julydate](https://github.com/julydate) [@xiyuvi](https://xiyu.pro/)
139
139
 
140
140
  如你也想贡献代码,可参照[贡献指南](https://hexo.fluid-dev.com/docs/contribute/)
141
141
 
package/_config.yml CHANGED
@@ -24,7 +24,7 @@ favicon: /img/fluid.png
24
24
  # Icon for Apple touch
25
25
  apple_touch_icon: /img/fluid.png
26
26
 
27
- # 浏览器标签页中的标题分隔符,效果: 文章名 - 站点名
27
+ # 浏览器标签页中的标题分隔符,效果:文章名 - 站点名
28
28
  # Title separator in browser tab, eg: article - site
29
29
  tab_title_separator: " - "
30
30
 
@@ -62,7 +62,7 @@ code:
62
62
  highlightjs:
63
63
  # 在链接中挑选 style 填入
64
64
  # Select a style in the link
65
- # See: https://highlightjs.org/static/demo/
65
+ # See: https://highlightjs.org/demo/
66
66
  style: "github gist"
67
67
  style_dark: "dark"
68
68
 
@@ -109,8 +109,10 @@ fun_features:
109
109
  element: h1,h2,h3,h4,h5,h6
110
110
  # Options: left | right
111
111
  placement: left
112
- # Options: hover | always | touch
112
+
113
+ # Options: hover | always
113
114
  visible: hover
115
+
114
116
  # Options: § | # | ❡
115
117
  icon: ""
116
118
 
@@ -128,7 +130,7 @@ fun_features:
128
130
  dark_mode:
129
131
  enable: true
130
132
  # 默认的选项(当用户手动切换后则不再按照默认模式),选择 `auto` 会优先遵循 prefers-color-scheme,其次按用户本地时间 18 点到次日 6 点之间进入暗色模式
131
- # Default option (when the visitor switches manually, the default mode is no longer followed), choosing `auto` will give priority to prefers-color-scheme, and then enter the dark mode from 18:00 to 6:00 in the visitors local time
133
+ # Default option (when the visitor switches manually, the default mode is no longer followed), choosing `auto` will give priority to prefers-color-scheme, and then enter the dark mode from 18:00 to 6:00 in the visitor's local time
132
134
  # Options: auto | light | dark
133
135
  default: auto
134
136
 
@@ -154,7 +156,7 @@ color:
154
156
  navbar_text_color_dark: "#d0d0d0"
155
157
 
156
158
  # 副标题字体色
157
- # Color of navigation bar text
159
+ # Color of subtitle text
158
160
  subtitle_color: "#fff"
159
161
  subtitle_color_dark: "#d0d0d0"
160
162
 
@@ -239,7 +241,7 @@ custom_css:
239
241
 
240
242
  # 网页访问统计
241
243
  # Analysis of website visitors
242
- web_analytics: # 网页访问统计
244
+ web_analytics:
243
245
  enable: false
244
246
 
245
247
  # 遵循访客浏览器"请勿追踪"的设置,如果开启则不统计其访问
@@ -265,16 +267,6 @@ web_analytics: # 网页访问统计
265
267
  sid:
266
268
  cid:
267
269
 
268
- # 51.la 站点统计 ID
269
- # 51.la analytics
270
- # See: https://www.51.la/user/site/index
271
- woyaola: # 51.la 站点统计 ID,参见
272
-
273
- # 友盟/cnzz 站点统计 web_id
274
- # cnzz analytics
275
- # See: https://web.umeng.com/main.php?c=site&a=show
276
- cnzz:
277
-
278
270
  # LeanCloud 计数统计,可用于 PV UV 展示,如果 `web_analytics: enable` 没有开启,PV UV 展示只会查询不会增加
279
271
  # LeanCloud count statistics, which can be used for PV UV display. If `web_analytics: enable` is false, PV UV display will only query and not increase
280
272
  leancloud:
@@ -290,6 +282,40 @@ web_analytics: # 网页访问统计
290
282
  # If true, ignore localhost & 127.0.0.1
291
283
  ignore_local: false
292
284
 
285
+ # Umami Analytics,仅支持自部署。如果要展示 PV UV 需要填写所有配置项,否则只填写 `src` 和 `website_id` 即可
286
+ # Umami Analytics, only Self-host support. If you want to display PV UV need to set all config items, otherwise only set 'src' and 'website_id'
287
+ # See: https://umami.is/docs/authentication
288
+ umami:
289
+ # umami js 文件地址,需要在 umami 后台创建站点后获取
290
+ # umami js file url, get after create website in umami
291
+ src:
292
+
293
+ # umami 的 website id,需要在 umami 后台创建站点后获取
294
+ # umami website id, get after create website in umami
295
+ website_id:
296
+
297
+ # 如果你只想统计特定的域名可以填入此字段,多个域名通过逗号分隔,这可以避免统计 localhost。
298
+ # If you only want to tracker to specific domains you can fill in this field, multiple domain names are separated by commas, which can avoid tracker localhost
299
+ domains:
300
+
301
+ # 用于统计 PV UV 的开始时间,格式为 "YYYY-MM-DD"
302
+ # statistics on the start time, the format is "YYYY-MM-DD"
303
+ start_time: 2024-01-01
304
+
305
+ # 新建一个 umami viewOnly 用户,然后通过 login api 获取该用户 token
306
+ # create an umami viewOnly user, and then get user token through the login api
307
+ token:
308
+
309
+ # 填写 umami 部署的服务器地址,如 "https://umami.example.com"
310
+ # server url of umami deployment, such as "https://umami.example.com"
311
+ api_server:
312
+
313
+ # Canonical 用于向 Google 搜索指定规范网址,开启前确保 hexo _config.yml 中配置 `url: http://yourdomain.com`
314
+ # Canonical, to specify a canonical URL for Google Search, need to set up `url: http://yourdomain.com` in hexo _config.yml
315
+ # See: https://support.google.com/webmasters/answer/139066
316
+ canonical:
317
+ enable: false
318
+
293
319
  # 对页面中的图片和评论插件进行懒加载处理,可见范围外的元素不会提前加载
294
320
  # Lazy loading of images and comment plugin on the page
295
321
  lazyload:
@@ -309,7 +335,7 @@ lazyload:
309
335
 
310
336
  # 图标库,包含了大量社交类图标,主题依赖的不包含在内,因此可自行修改,详见 https://hexo.fluid-dev.com/docs/icon/
311
337
  # Icon library, which includes many social icons, does not include those theme dependent, so your can modify link by yourself. See: https://hexo.fluid-dev.com/docs/en/icon/
312
- iconfont: //at.alicdn.com/t/font_1736178_lbnruvf0jn.css
338
+ iconfont: //at.alicdn.com/t/c/font_1736178_k526ubmyhba.css
313
339
 
314
340
 
315
341
  #---------------------------
@@ -430,9 +456,9 @@ footer:
430
456
  statistics:
431
457
  enable: false
432
458
 
433
- # 统计数据来源,使用 leancloud 需要设置 `web_analytics: leancloud` 中的参数;使用 busuanzi 不需要额外设置,但是有时不稳定,另外本地运行时 busuanzi 显示统计数据很大属于正常现象,部署后会正常
434
- # Data source. If use leancloud, you need to set the parameter in `web_analytics: leancloud`
435
- # Options: busuanzi | leancloud
459
+ # 统计数据来源,使用 leancloud, umami 需要设置 `web_analytics` 中对应的参数;使用 busuanzi 不需要额外设置,但是有时不稳定,另外本地运行时 busuanzi 显示统计数据很大属于正常现象,部署后会正常
460
+ # Data source. If use leancloud, umami, you need to set the parameter in `web_analytics`
461
+ # Options: busuanzi | leancloud | umami
436
462
  source: "busuanzi"
437
463
 
438
464
  # 国内大陆服务器的备案信息
@@ -463,7 +489,7 @@ index:
463
489
  # Available: 0 - 100
464
490
  banner_img_height: 100
465
491
 
466
- # 头图黑色蒙版的不透明度,available: 0 - 1.0, 1 是完全不透明
492
+ # 头图黑色蒙版的不透明度,available: 0 - 1.0,1 是完全不透明
467
493
  # Opacity of the banner mask, 1.0 is completely opaque
468
494
  # Available: 0 - 1.0
469
495
  banner_mask_alpha: 0.3
@@ -575,7 +601,7 @@ post:
575
601
  enable: false
576
602
  # 统计数据来源
577
603
  # Data Source
578
- # Options: busuanzi | leancloud
604
+ # Options: busuanzi | leancloud | umami
579
605
  source: "busuanzi"
580
606
 
581
607
  # 在文章开头显示文章更新时间,该时间默认是 md 文件更新时间,可通过 front-matter 中 `updated` 手动指定(和 date 一样格式)
@@ -644,7 +670,8 @@ post:
644
670
  enable: true
645
671
 
646
672
  # CreativeCommons license
647
- # Options: BY | BY-SA | BY-ND | BY-NC | BY-NC-SA | BY-NC-ND
673
+ # See: https://creativecommons.org/share-your-work/cclicenses/
674
+ # Options: BY | BY-SA | BY-ND | BY-NC | BY-NC-SA | BY-NC-ND | ZERO
648
675
  license: 'BY'
649
676
 
650
677
  # 显示作者
@@ -955,7 +982,7 @@ about:
955
982
  name: "Fluid"
956
983
  intro: "An elegant theme for Hexo"
957
984
  # 更多图标可从 https://hexo.fluid-dev.com/docs/icon/ 查找,`class` 代表图标的 css class,添加 `qrcode` 后,图标不再是链接而是悬浮二维码
958
- # More icons can be found from https://hexo.fluid-dev.com/docs/en/icon/ `class` is the css class of the icon. If adding `qrcode`, The icon is no longer a link, but a hovering QR code
985
+ # More icons can be found from https://hexo.fluid-dev.com/docs/en/icon/ `class` is the css class of the icon. If adding `qrcode`, the icon is no longer a link, but a hovering QR code
959
986
  icons:
960
987
  - { class: "iconfont icon-github-fill", link: "https://github.com", tip: "GitHub" }
961
988
  - { class: "iconfont icon-douban-fill", link: "https://douban.com", tip: "豆瓣" }
@@ -1057,7 +1084,7 @@ static_prefix:
1057
1084
  internal_css: /css
1058
1085
  internal_img: /img
1059
1086
 
1060
- anchor: https://lib.baomitu.com/anchor-js/4.3.1/
1087
+ anchor: https://lib.baomitu.com/anchor-js/5.0.0/
1061
1088
 
1062
1089
  github_markdown: https://lib.baomitu.com/github-markdown-css/4.0.0/
1063
1090
 
@@ -1087,7 +1114,7 @@ static_prefix:
1087
1114
 
1088
1115
  valine: https://lib.baomitu.com/valine/1.5.1/
1089
1116
 
1090
- waline: https://cdn.staticfile.org/waline/2.15.5/
1117
+ waline: https://registry.npmmirror.com/@waline/client/2.15.8/files/dist/
1091
1118
 
1092
1119
  gitalk: https://lib.baomitu.com/gitalk/1.8.0/
1093
1120
 
@@ -1098,3 +1125,5 @@ static_prefix:
1098
1125
  discuss: https://lib.baomitu.com/discuss/1.2.1/
1099
1126
 
1100
1127
  hint: https://lib.baomitu.com/hint.css/2.7.0/
1128
+
1129
+ moment: https://lib.baomitu.com/moment.js/2.29.4/
package/languages/de.yml CHANGED
@@ -57,6 +57,7 @@ post:
57
57
  SA: 'SA - Share-alike'
58
58
  NC: 'NC - Non-commercial'
59
59
  ND: 'ND - No derivative works'
60
+ ZERO: 'CC0 - No Copyright'
60
61
 
61
62
  footer:
62
63
  pv: 'Alle Aufrufe: {}'
package/languages/en.yml CHANGED
@@ -57,6 +57,7 @@ post:
57
57
  SA: 'SA - Share-alike'
58
58
  NC: 'NC - Non-commercial'
59
59
  ND: 'ND - No derivative works'
60
+ ZERO: 'CC0 - No Copyright'
60
61
 
61
62
  footer:
62
63
  pv: 'Views: {}'
package/languages/eo.yml CHANGED
@@ -57,6 +57,7 @@ post:
57
57
  SA: 'SA - Share-alike'
58
58
  NC: 'NC - Non-commercial'
59
59
  ND: 'ND - No derivative works'
60
+ ZERO: 'CC0 - No Copyright'
60
61
 
61
62
  footer:
62
63
  pv: 'Vidoj: {}'
package/languages/es.yml CHANGED
@@ -57,6 +57,7 @@ post:
57
57
  SA: 'SA - Compartir igual'
58
58
  NC: 'NC - No comercial'
59
59
  ND: 'ND - Sin obras derivadas'
60
+ ZERO: 'CC0 - Sin derechos autorales'
60
61
 
61
62
  footer:
62
63
  pv: 'Vistas: {}'
package/languages/ja.yml CHANGED
@@ -57,6 +57,7 @@ post:
57
57
  SA: 'SA - Share-alike'
58
58
  NC: 'NC - Non-commercial'
59
59
  ND: 'ND - No derivative works'
60
+ ZERO: 'CC0 - No Copyright'
60
61
 
61
62
  footer:
62
63
  pv: '閲覧合計数: {}'
package/languages/ru.yml CHANGED
@@ -22,7 +22,7 @@ tag:
22
22
  title: 'Теги'
23
23
  subtitle: 'Теги'
24
24
  post_total: '%d сообщений всего'
25
-
25
+
26
26
  about:
27
27
  menu: 'О'
28
28
  title: 'О'
@@ -57,6 +57,7 @@ post:
57
57
  SA: 'SA - Share-alike'
58
58
  NC: 'NC - Non-commercial'
59
59
  ND: 'ND - No derivative works'
60
+ ZERO: 'CC0 - No Copyright'
60
61
 
61
62
  footer:
62
63
  pv: 'Просмотров: {}'
@@ -42,7 +42,7 @@ post:
42
42
  toc: '目录'
43
43
  prev_post: '上一篇'
44
44
  next_post: '下一篇'
45
- updated: '本文最后更新于:%s'
45
+ updated: '本文最后更新于 %s'
46
46
  meta:
47
47
  wordcount: '%s 字'
48
48
  min2read: '%s 分钟'
@@ -57,6 +57,7 @@ post:
57
57
  SA: 'SA - 相同方式共享'
58
58
  NC: 'NC - 非商业性使用'
59
59
  ND: 'ND - 禁止演绎'
60
+ ZERO: 'CC0 - 无版权'
60
61
 
61
62
  footer:
62
63
  pv: '总访问量 {} 次'
@@ -57,6 +57,7 @@ post:
57
57
  SA: 'SA - 相同方式共享'
58
58
  NC: 'NC - 非商業性使用'
59
59
  ND: 'ND - 禁止演繹'
60
+ ZERO: 'CC0 - 無著作權'
60
61
 
61
62
  footer:
62
63
  pv: '總訪問量 {} 次'
@@ -57,6 +57,7 @@ post:
57
57
  SA: 'SA - 相同方式共享'
58
58
  NC: 'NC - 非商業性使用'
59
59
  ND: 'ND - 禁止演繹'
60
+ ZERO: 'CC0 - 無著作權'
60
61
 
61
62
  footer:
62
63
  pv: '總訪問量 {} 次'
@@ -2,8 +2,8 @@
2
2
  <div id="waline"></div>
3
3
  <script type="text/javascript">
4
4
  Fluid.utils.loadComments('#waline', function() {
5
- Fluid.utils.createCssLink('<%= url_join(theme.static_prefix.waline, 'waline.min.css') %>')
6
- Fluid.utils.createScript('<%= url_join(theme.static_prefix.waline, 'waline.min.js') %>', function() {
5
+ Fluid.utils.createCssLink('<%= url_join(theme.static_prefix.waline, 'waline.css') %>')
6
+ Fluid.utils.createScript('<%= url_join(theme.static_prefix.waline, 'waline.js') %>', function() {
7
7
  var options = Object.assign(
8
8
  <%- JSON.stringify(theme.waline || {}) %>,
9
9
  {
@@ -8,7 +8,7 @@
8
8
 
9
9
  <!-- 主题依赖的图标库,不要自行修改 -->
10
10
  <!-- Do not modify the link that theme dependent icons -->
11
- <%- css('//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css') %>
11
+ <%- css('//at.alicdn.com/t/c/font_1749284_5i9bdhy70f8.css') %>
12
12
 
13
13
  <%- css(theme.static_prefix.iconfont || theme.iconfont) %>
14
14
 
@@ -1,6 +1,6 @@
1
1
  <div class="statistics">
2
- <% var pv_texts = (theme.footer.statistics.pv_format || __('footer.pv')).split('{}') %>
3
- <% var uv_texts = (theme.footer.statistics.uv_format || __('footer.uv')).split('{}') %>
2
+ <% let pv_texts = (theme.footer.statistics.pv_format || __('footer.pv')).split('{}') %>
3
+ <% let uv_texts = (theme.footer.statistics.uv_format || __('footer.uv')).split('{}') %>
4
4
 
5
5
  <% if (theme.footer.statistics.source === 'leancloud') { %>
6
6
  <% if (pv_texts.length >= 2) { %>
@@ -35,5 +35,23 @@
35
35
  </span>
36
36
  <% } %>
37
37
  <% import_js(theme.static_prefix.busuanzi, 'busuanzi.pure.mini.js', 'defer') %>
38
+
39
+ <% } else if (theme.footer.statistics.source === 'umami') { %>
40
+ <% if (pv_texts.length >= 2) { %>
41
+ <span id="umami-site-pv-container" style="display: none">
42
+ <%- pv_texts[0] %>
43
+ <span id="umami-site-pv"></span>
44
+ <%- pv_texts[1] %>
45
+ </span>
46
+ <% } %>
47
+ <% if (uv_texts.length >= 2) { %>
48
+ <span id="umami-site-uv-container" style="display: none">
49
+ <%- uv_texts[0] %>
50
+ <span id="umami-site-uv"></span>
51
+ <%- uv_texts[1] %>
52
+ </span>
53
+ <% } %>
54
+ <% import_js(theme.static_prefix.internal_js, 'umami-view.js', 'defer') %>
38
55
  <% } %>
56
+
39
57
  </div>
@@ -11,8 +11,4 @@
11
11
  <!-- 备案信息 ICP for China -->
12
12
  <%- partial('_partials/footer/beian.ejs') %>
13
13
  <% } %>
14
- <% if(theme.web_analytics.cnzz) { %>
15
- <!-- cnzz Analytics Icon -->
16
- <span id="cnzz_stat_icon_<%= theme.web_analytics.cnzz %>" style="display: none"></span>
17
- <% } %>
18
14
  </div>
@@ -15,8 +15,13 @@ var ogConfig = Object.assign({ image: ogImage && url_for(ogImage) }, theme.open_
15
15
 
16
16
  <head>
17
17
  <meta charset="UTF-8">
18
+
18
19
  <link rel="apple-touch-icon" sizes="76x76" href="<%= url_for(theme.apple_touch_icon) %>">
19
20
  <link rel="icon" href="<%= url_for(theme.favicon) %>">
21
+ <% if (theme.canonical.enable) { %>
22
+ <link rel="canonical" href="<%= url_join(config.url, page.canonical_path.replace('index.html', '')) %>"/>
23
+ <% } %>
24
+
20
25
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
21
26
  <meta http-equiv="x-ua-compatible" content="ie=edge">
22
27
  <% if (theme.force_https) { %>
@@ -15,7 +15,7 @@
15
15
  </script>
16
16
  <% } %>
17
17
 
18
- <% if (theme.web_analytics.google){ %>
18
+ <% if (theme.web_analytics.google && theme.web_analytics.google.measurement_id){ %>
19
19
  <!-- Google tag (gtag.js) -->
20
20
  <script async>
21
21
  if (!Fluid.ctx.dnt) {
@@ -25,12 +25,25 @@
25
25
  dataLayer.push(arguments);
26
26
  }
27
27
  gtag('js', new Date());
28
- gtag('config', '<%- theme.web_analytics.google.measurement_id %>');
28
+ gtag('config', '<%= theme.web_analytics.google.measurement_id %>');
29
29
  });
30
30
  }
31
31
  </script>
32
32
  <% } %>
33
33
 
34
+ <% if(theme.web_analytics.umami && theme.web_analytics.umami.src && theme.web_analytics.umami.website_id) { %>
35
+ <script async>
36
+ if (!Fluid.ctx.dnt) {
37
+ let umami = document.createElement('script');
38
+ umami.async = true;
39
+ umami.src = "<%= theme.web_analytics.umami.src %>";
40
+ umami.setAttribute("data-website-id", "<%= theme.web_analytics.umami.website_id %>");
41
+ umami.setAttribute("data-domains", "<%= theme.web_analytics.umami.domains %>");
42
+ document.head.appendChild(umami);
43
+ }
44
+ </script>
45
+ <% } %>
46
+
34
47
  <% if(theme.web_analytics.tencent && theme.web_analytics.tencent.sid && theme.web_analytics.tencent.cid) { %>
35
48
  <!-- Tencent Analytics -->
36
49
  <script async>
@@ -51,24 +64,6 @@
51
64
  </script>
52
65
  <% } %>
53
66
 
54
- <% if(theme.web_analytics.woyaola) { %>
55
- <!-- 51.la Analytics -->
56
- <script async>
57
- if (!Fluid.ctx.dnt) {
58
- Fluid.utils.createScript('//js.users.51.la/<%= theme.web_analytics.woyaola %>.js');
59
- }
60
- </script>
61
- <% } %>
62
-
63
- <% if(theme.web_analytics.cnzz) { %>
64
- <!-- cnzz Analytics -->
65
- <script async>
66
- if (!Fluid.ctx.dnt) {
67
- Fluid.utils.createScript('//s4.cnzz.com/z_stat.php?id=<%= theme.web_analytics.cnzz %>&show=pic');
68
- }
69
- </script>
70
- <% } %>
71
-
72
67
  <% if(theme.web_analytics.leancloud && theme.web_analytics.leancloud.app_id && theme.web_analytics.leancloud.app_key) { %>
73
68
  <% import_js(theme.static_prefix.internal_js, 'leancloud.js', 'defer') %>
74
69
  <% } %>
@@ -0,0 +1,30 @@
1
+ <%
2
+ var lang = (config.language || 'zh-cn').toLowerCase();
3
+
4
+ import_script(`
5
+ <script>
6
+ var relativeDate = function() {
7
+ var updatedTime = document.getElementById('updated-time');
8
+ if (updatedTime) {
9
+ var text = updatedTime.textContent;
10
+ var reg = /\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:Z|[+-]\\d{2}:\\d{2})/;
11
+ var matchs = text.match(reg);
12
+ if (matchs) {
13
+ var relativeTime = moment(matchs[0]).fromNow();
14
+ updatedTime.textContent = text.replace(reg, relativeTime);
15
+ }
16
+ updatedTime.style.display = '';
17
+ }
18
+ };
19
+ Fluid.utils.createScript('${url_join(theme.static_prefix.moment, 'moment.min.js')}', function() {
20
+ if (!'${lang}'.startsWith('en')) {
21
+ Fluid.utils.createScript('${url_join(theme.static_prefix.moment, 'locale/' + lang + '.min.js')}', function() {
22
+ relativeDate();
23
+ });
24
+ } else {
25
+ relativeDate();
26
+ }
27
+ });
28
+ </script>
29
+ `)
30
+ %>
@@ -42,10 +42,16 @@
42
42
  <% for (var idx = 0; idx < items.length; idx++) { %>
43
43
  <a class="print-no-link" target="_blank" href="https://creativecommons.org/licenses/<%= license.toLowerCase() %>/4.0/">
44
44
  <span class="hint--top hint--rounded" aria-label="<%- __('post.copyright.' + items[idx]) %>">
45
- <i class="iconfont icon-<%= items[idx].toLowerCase() %>"></i>
45
+ <i class="iconfont icon-cc-<%= items[idx].toLowerCase() %>"></i>
46
46
  </span>
47
47
  </a>
48
48
  <% } %>
49
+ <% } else if (license === 'ZERO') { %>
50
+ <a class="print-no-link" target="_blank" href="https://creativecommons.org/publicdomain/zero/1.0/">
51
+ <span class="hint--top hint--rounded" aria-label="<%- __('post.copyright.ZERO') %>">
52
+ <i class="iconfont icon-cc-zero"></i>
53
+ </span>
54
+ </a>
49
55
  <% } else { %>
50
56
  <%- license %>
51
57
  <% } %>
@@ -51,12 +51,20 @@
51
51
  <%- views_texts[0] %><span id="leancloud-page-views"></span><%- views_texts[1] %>
52
52
  </span>
53
53
  <% import_js(theme.static_prefix.internal_js, 'leancloud.js', 'defer') %>
54
+
54
55
  <% } else if (theme.post.meta.views.source === 'busuanzi') { %>
55
56
  <span id="busuanzi_container_page_pv" style="display: none">
56
57
  <i class="iconfont icon-eye" aria-hidden="true"></i>
57
58
  <%- views_texts[0] %><span id="busuanzi_value_page_pv"></span><%- views_texts[1] %>
58
59
  </span>
59
60
  <% import_js(theme.static_prefix.busuanzi, 'busuanzi.pure.mini.js', 'defer') %>
61
+
62
+ <% } else if (theme.post.meta.views.source === 'umami') { %>
63
+ <span id="umami-page-views-container" class="post-meta" style="display: none">
64
+ <i class="iconfont icon-eye" aria-hidden="true"></i>
65
+ <%- views_texts[0] %><span id="umami-page-views"></span><%- views_texts[1] %>
66
+ </span>
67
+ <% import_js(theme.static_prefix.internal_js, 'umami-view.js', 'defer') %>
60
68
  <% } %>
61
69
  <% } %>
62
70
  </div>
package/layout/about.ejs CHANGED
@@ -18,7 +18,7 @@ page.banner_mask_alpha = page.banner_mask_alpha || theme.about.banner_mask_alpha
18
18
  <% var isQr = each.qrcode %>
19
19
  <a <%= isQr ? '' : ('href=' + url_for(each.link)) %> class="<%= isQr ? 'qr-trigger' : '' %>
20
20
  <%= !isQr && each.tip ? 'hint--bottom hint--rounded' : '' %>"
21
- <%= !isQr && each.tip ? 'aria-label=' + each.tip : '' %>
21
+ <% if (!isQr && each.tip) { %>aria-label="<%= each.tip %>"<% } %>
22
22
  target="<%= isQr ? '_self' : '_blank' %>"
23
23
  >
24
24
  <i class="<%= cls %>" aria-hidden="true"></i>
package/layout/post.ejs CHANGED
@@ -16,14 +16,15 @@ page.banner_mask_alpha = page.banner_mask_alpha || theme.post.banner_mask_alpha
16
16
  <article class="post-content mx-auto">
17
17
  <h1 id="seo-header"><%= page.subtitle || page.title %></h1>
18
18
  <% if (theme.post.updated.enable && theme.post.updated && compare_date(page.date, page.updated)) { %>
19
- <p class="note note-<%= theme.post.updated.note_class || 'info' %>">
19
+ <p id="updated-time" class="note note-<%= theme.post.updated.note_class || 'info' %>" style="<%= theme.post.updated.relative ? 'display: none' : '' %>">
20
20
  <% if (theme.post.updated.relative) { %>
21
21
  <% if (theme.post.updated.content) { %>
22
22
  <!-- compatible with older versions-->
23
- <%- theme.post.updated.content %><%- relative_date(page.updated, theme.post.updated.date_format) %>
23
+ <%- theme.post.updated.content %><%- date(page.updated, 'YYYY-MM-DDTHH:mm:ssZ') %>
24
24
  <% } else { %>
25
- <%- __('post.updated', relative_date(page.updated, theme.post.updated.date_format)) %>
25
+ <%- __('post.updated', date(page.updated, 'YYYY-MM-DDTHH:mm:ssZ')) %>
26
26
  <% } %>
27
+ <%- partial('_partials/plugins/moment.ejs') %>
27
28
  <% } else { %>
28
29
  <% if (theme.post.updated.content) { %>
29
30
  <!-- compatible with older versions-->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-fluid",
3
- "version": "1.9.6",
3
+ "version": "1.9.8",
4
4
  "description": "An elegant Material-Design theme for Hexo.",
5
5
  "main": "package.json",
6
6
  "files": [
@@ -16,7 +16,7 @@ module.exports = (hexo) => {
16
16
  | _| |_ | | | \\_/ |, | || \\__/ | |
17
17
  | |_____| [___]'.__.'_/[___]'.__.;__] |
18
18
  | |
19
- | 感谢使用 Fluid 主题 ! |
19
+ | 感谢使用 Fluid 主题 |
20
20
  | 文档: https://hexo.fluid-dev.com/docs/ |
21
21
  | |
22
22
  ------------------------------------------------
@@ -32,7 +32,7 @@ module.exports = (hexo) => {
32
32
  | _| |_ | | | \\_/ |, | || \\__/ | |
33
33
  | |_____| [___]'.__.'_/[___]'.__.;__] |
34
34
  | |
35
- | Thank you for using Fluid theme ! |
35
+ | Thank you for using Fluid theme |
36
36
  | Docs: https://hexo.fluid-dev.com/docs/en/ |
37
37
  | |
38
38
  ------------------------------------------------
@@ -49,5 +49,7 @@ hexo.extend.generator.register('post', function(locals) {
49
49
  hexo.extend.filter.register('after_post_render', (page) => {
50
50
  // 移除 hexo-renderer-pandoc 生成的 <colgroup>
51
51
  page.content = page.content.replace(/<colgroup>.+?<\/colgroup>/gims, '');
52
+ // 移除 hexo-renderer-pandoc 生成的 <span class="footnote-text">...<br>...</span>
53
+ page.content = page.content.replace(/(class="footnote-text".+?)<br.+?>(.+?rev="footnote")/gims, '$1$2');
52
54
  return page;
53
55
  });
@@ -5,16 +5,13 @@
5
5
  const { stripHTML } = require('hexo-util');
6
6
 
7
7
  const getWordCount = (post) => {
8
- const lang = post.lang.toLowerCase();
9
8
  // post.origin is the original post content of hexo-blog-encrypt
10
9
  const content = stripHTML(post.origin || post.content).replace(/\r?\n|\r/g, '').replace(/\s+/g, '');
11
10
 
12
11
  if (!post.wordcount) {
13
- if (['zh-cn', 'zh-hk', 'zh-tw'].includes(lang)) {
14
- post.wordcount = (content.match(/[\u4E00-\u9FA5]/g) || []).length;
15
- } else {
16
- post.wordcount = (content.replace(/[\u4E00-\u9FA5]/g, '').match(/[a-zA-Z0-9_\u0392-\u03c9\u0400-\u04FF]+|[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af\u0400-\u04FF]+|[\u00E4\u00C4\u00E5\u00C5\u00F6\u00D6]+|\w+/g) || []).length;
17
- }
12
+ const zhCount = (content.match(/[\u4E00-\u9FA5]/g) || []).length;
13
+ const enCount = (content.replace(/[\u4E00-\u9FA5]/g, '').match(/[a-zA-Z0-9_\u0392-\u03c9\u0400-\u04FF]+|[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af\u0400-\u04FF]+|[\u00E4\u00C4\u00E5\u00C5\u00F6\u00D6]+|\w+/g) || []).length;
14
+ post.wordcount = zhCount + enCount
18
15
  }
19
16
  return post.wordcount;
20
17
  };
@@ -16,14 +16,15 @@ const checkbox = (args) => {
16
16
 
17
17
  const checked = (args[1] || '').length > 0 && args[1].trim() !== 'false';
18
18
  const inline = (args[2] || '').length > 0 && args[2].trim() !== 'false';
19
- const enabled = (args[3] || '').length > 0 && args[3].trim() === 'false';
19
+ const disabled = (args[3] || '').length > 0 && args[3].trim() !== 'false';
20
+ const content = hexo.render.renderSync({ text: text, engine: 'markdown' }).replace(/(<p>)|(<\/p>)/g, '').replace(/<br>/g, '');
20
21
 
21
22
  return `${!inline ? '<div>' : ''}
22
- <input type="checkbox" ${enabled ? '' : 'disabled'} ${checked ? 'checked="checked"' : ''}>${text}
23
+ <input type="checkbox" ${disabled ? 'disabled' : ''} ${checked ? 'checked="checked"' : ''}>${content}
23
24
  ${!inline ? '</div>' : ''}`;
24
25
 
25
26
  };
26
27
 
27
- // {% cb text, checked?, inline? %}
28
+ // {% cb text, checked?, inline?, disabled? %}
28
29
  hexo.extend.tag.register('checkbox', checkbox, { ends: false });
29
30
  hexo.extend.tag.register('cb', checkbox, { ends: false });
@@ -11,8 +11,10 @@ hexo.extend.tag.register('fold', (args, content) => {
11
11
  <div class="fold-title fold-${classes.trim()} collapsed" data-toggle="collapse" href="#${id}" role="button" aria-expanded="false" aria-controls="${id}">
12
12
  <div class="fold-arrow">▶</div>${text}
13
13
  </div>
14
- <div class='fold-content collapse' id="${id}">
15
- ${hexo.render.renderSync({ text: content, engine: 'markdown' }).split('\n').join('')}
14
+ <div class="fold-collapse collapse" id="${id}">
15
+ <div class="fold-content">
16
+ ${hexo.render.renderSync({ text: content, engine: 'markdown' }).split('\n').join('')}
17
+ </div>
16
18
  </div>
17
19
  </div>`;
18
20
  }, {
@@ -24,6 +24,7 @@
24
24
 
25
25
  i
26
26
  font-size 0.875rem
27
+ line-height inherit
27
28
 
28
29
  i:only-child
29
30
  margin 0 .2rem
@@ -42,8 +42,8 @@ dark-colors()
42
42
  --button-hover-bg-color $button-hover-bg-color-dark
43
43
  --highlight-bg-color $highlight-bg-color-dark
44
44
  --inlinecode-bg-color $inlinecode-bg-color-dark
45
- --fold-title-color $text-color
46
- --fold-border-color $line-color
45
+ --fold-title-color $text-color-dark
46
+ --fold-border-color $line-color-dark
47
47
 
48
48
  img
49
49
  -webkit-filter brightness(.9)
@@ -8,11 +8,17 @@
8
8
  padding-left 2rem
9
9
  padding-right 2rem
10
10
 
11
+ .page-content, .post-content
12
+ overflow hidden
13
+
11
14
  @media (max-width: 424px)
12
15
  .post-content, post-custom
13
16
  padding-left 1rem
14
17
  padding-right 1rem
15
18
 
19
+ .page-content, .post-content
20
+ overflow hidden
21
+
16
22
  .anchorjs-link-left
17
23
  opacity 0 !important
18
24
 
@@ -20,17 +26,13 @@
20
26
  strong
21
27
  font-weight bold
22
28
 
23
- & > *:first-child
29
+ & > *:nth-child(2)
24
30
  margin-top 0
25
31
 
26
32
  img
27
33
  object-fit cover
28
34
  max-width 100%
29
35
 
30
- @media (max-width: 767px)
31
- .page-content, .post-content
32
- overflow-x hidden
33
-
34
36
  .post-metas
35
37
  display flex
36
38
  flex-wrap wrap
@@ -23,30 +23,31 @@
23
23
  transition transform .3s ease-out
24
24
 
25
25
  .fold-content
26
- & > *
27
- margin 0
26
+ padding 1rem 1rem
28
27
 
29
- & > p
30
- padding 1rem 1rem
28
+ & > *:last-child
29
+ margin-bottom 0
31
30
 
32
- .fold-default
33
- background rgba(#bbbbbb, 0.25)
31
+ .fold-default, .fold-secondary
32
+ background-color rgba(#bbbbbb, 0.25)
34
33
 
35
34
  .fold-primary
36
- background rgba(#b7a0e0, 0.25)
35
+ background-color rgba(#b7a0e0, 0.25)
37
36
 
38
37
  .fold-info
39
- background rgba(#a0c5e4, 0.25)
38
+ background-color rgba(#a0c5e4, 0.25)
40
39
 
41
40
  .fold-success
42
- background rgba(#aedcae, 0.25)
41
+ background-color rgba(#aedcae, 0.25)
43
42
 
44
43
  .fold-warning
45
- background rgba(#f8d6a6, 0.25)
44
+ background-color rgba(#f8d6a6, 0.25)
46
45
 
47
46
  .fold-danger
48
- background rgba(#eca9a7, 0.25)
47
+ background-color rgba(#eca9a7, 0.25)
49
48
 
49
+ .fold-light
50
+ background-color rgba(#fefefe, 0.25)
50
51
 
51
52
  // note
52
53
  .note
@@ -65,14 +66,14 @@
65
66
  *:last-child
66
67
  margin-bottom 0
67
68
 
69
+ .note-default, .note-secondary
70
+ background-color rgba(#bbbbbb, 0.25)
71
+ border-color #777
72
+
68
73
  .note-primary
69
74
  background-color rgba(#b7a0e0, 0.25)
70
75
  border-color #6f42c1
71
76
 
72
- .note-secondary, note-default
73
- background-color rgba(#bbbbbb, 0.25)
74
- border-color #777
75
-
76
77
  .note-success
77
78
  background-color rgba(#aedcae, 0.25)
78
79
  border-color #5cb85c
@@ -103,23 +104,23 @@
103
104
  color var(--text-color)
104
105
  transition color .2s ease-in-out
105
106
 
106
- .label-default
107
- background rgba(#bbbbbb, 0.25)
107
+ .label-default, .label-secondary
108
+ background-color rgba(#bbbbbb, 0.25)
108
109
 
109
110
  .label-primary
110
- background rgba(#b7a0e0, 0.25)
111
+ background-color rgba(#b7a0e0, 0.25)
111
112
 
112
113
  .label-info
113
- background rgba(#a0c5e4, 0.25)
114
+ background-color rgba(#a0c5e4, 0.25)
114
115
 
115
116
  .label-success
116
- background rgba(#aedcae, 0.25)
117
+ background-color rgba(#aedcae, 0.25)
117
118
 
118
119
  .label-warning
119
- background rgba(#f8d6a6, 0.25)
120
+ background-color rgba(#f8d6a6, 0.25)
120
121
 
121
122
  .label-danger
122
- background rgba(#eca9a7, 0.25)
123
+ background-color rgba(#eca9a7, 0.25)
123
124
 
124
125
  // button
125
126
  .markdown-body .btn
@@ -248,7 +248,7 @@
248
248
  theme: giscusTheme,
249
249
  }
250
250
  };
251
- giscus.style.cssText += 'color-scheme: normal;';
251
+ // giscus.style.cssText += 'color-scheme: normal;';
252
252
  giscus.contentWindow.postMessage({ 'giscus': message }, 'https://giscus.app');
253
253
  }
254
254
  }
@@ -125,7 +125,7 @@ Fluid.events = {
125
125
  var url = src.match(/\((.*?)\)/)[1].replace(/(['"])/g, '');
126
126
  var img = new Image();
127
127
  img.onload = function() {
128
- window.NProgress && window.NProgress.inc(0.2);
128
+ window.NProgress && window.NProgress.status !== null && window.NProgress.inc(0.2);
129
129
  };
130
130
  img.src = url;
131
131
  if (img.complete) { img.onload(); }
@@ -137,7 +137,7 @@ Fluid.events = {
137
137
  const old = img.onload;
138
138
  img.onload = function() {
139
139
  old && old();
140
- window.NProgress && window.NProgress.inc(0.5 / total);
140
+ window.NProgress && window.NProgress.status !== null && window.NProgress.inc(0.5 / total);
141
141
  };
142
142
  if (img.complete) { img.onload(); }
143
143
  }
@@ -166,19 +166,19 @@ Fluid.events = {
166
166
  }
167
167
  // eslint-disable-next-line no-console
168
168
  console.log(`
169
- ------------------------------------------------
170
- | |
171
- | ________ __ _ __ |
172
- | |_ __ |[ | (_) | ] |
173
- | | |_ \\_| | | __ _ __ .--.| | |
174
- | | _| | |[ | | | [ |/ /'\`\\' | |
175
- | _| |_ | | | \\_/ |, | || \\__/ | |
176
- | |_____| [___]'.__.'_/[___]'.__.;__] |
177
- | |
178
- | Powered by Hexo x Fluid |
179
- | GitHub: https://git.io/JqpVD |
180
- | |
181
- ------------------------------------------------
169
+ -------------------------------------------------
170
+ | |
171
+ | ________ __ _ __ |
172
+ | |_ __ |[ | (_) | ] |
173
+ | | |_ \\_| | | __ _ __ .--.| | |
174
+ | | _| | |[ | | | [ |/ /'\`\\' | |
175
+ | _| |_ | | | \\_/ |, | || \\__/ | |
176
+ | |_____| [___]'.__.'_/[___]'.__.;__] |
177
+ | |
178
+ | Powered by Hexo x Fluid |
179
+ | https://github.com/fluid-dev/hexo-theme-fluid |
180
+ | |
181
+ -------------------------------------------------
182
182
  `);
183
183
  }
184
184
  };
@@ -0,0 +1,99 @@
1
+ // 从配置文件中获取 umami 的配置
2
+ const website_id = CONFIG.web_analytics.umami.website_id;
3
+ // 拼接请求地址
4
+ const request_url = `${CONFIG.web_analytics.umami.api_server}/websites/${website_id}/stats`;
5
+
6
+ const start_time = new Date(CONFIG.web_analytics.umami.start_time).getTime();
7
+ const end_time = new Date().getTime();
8
+ const token = CONFIG.web_analytics.umami.token;
9
+
10
+ // 检查配置是否为空
11
+ if (!website_id) {
12
+ throw new Error("Umami website_id is empty");
13
+ }
14
+ if (!request_url) {
15
+ throw new Error("Umami request_url is empty");
16
+ }
17
+ if (!start_time) {
18
+ throw new Error("Umami start_time is empty");
19
+ }
20
+ if (!token) {
21
+ throw new Error("Umami token is empty");
22
+ }
23
+
24
+ // 构造请求参数
25
+ const params = new URLSearchParams({
26
+ startAt: start_time,
27
+ endAt: end_time,
28
+ });
29
+ // 构造请求头
30
+ const request_header = {
31
+ method: "GET",
32
+ headers: {
33
+ "Content-Type": "application/json",
34
+ "x-umami-api-key": "oZKCH3msvqt10VlXKwoJvHclmaS4bVx0",
35
+ },
36
+ };
37
+
38
+ // 获取站点统计数据
39
+ async function siteStats() {
40
+ try {
41
+ const response = await fetch(`${request_url}?${params}`, request_header);
42
+ const data = await response.json();
43
+ const uniqueVisitors = data.uniques.value; // 获取独立访客数
44
+ const pageViews = data.pageviews.value; // 获取页面浏览量
45
+
46
+ let pvCtn = document.querySelector("#umami-site-pv-container");
47
+ if (pvCtn) {
48
+ let ele = document.querySelector("#umami-site-pv");
49
+ if (ele) {
50
+ ele.textContent = pageViews; // 设置页面浏览量
51
+ pvCtn.style.display = "inline"; // 将元素显示出来
52
+ }
53
+ }
54
+
55
+ let uvCtn = document.querySelector("#umami-site-uv-container");
56
+ if (uvCtn) {
57
+ let ele = document.querySelector("#umami-site-uv");
58
+ if (ele) {
59
+ ele.textContent = uniqueVisitors;
60
+ uvCtn.style.display = "inline";
61
+ }
62
+ }
63
+ } catch (error) {
64
+ console.error(error);
65
+ return "-1";
66
+ }
67
+ }
68
+
69
+ // 获取页面浏览量
70
+ async function pageStats(path) {
71
+ try {
72
+ const response = await fetch(`${request_url}?${params}&url=${path}`, request_header);
73
+ const data = await response.json();
74
+ const pageViews = data.pageviews.value;
75
+
76
+ let viewCtn = document.querySelector("#umami-page-views-container");
77
+ if (viewCtn) {
78
+ let ele = document.querySelector("#umami-page-views");
79
+ if (ele) {
80
+ ele.textContent = pageViews;
81
+ viewCtn.style.display = "inline";
82
+ }
83
+ }
84
+ } catch (error) {
85
+ console.error(error);
86
+ return "-1";
87
+ }
88
+ }
89
+
90
+ siteStats();
91
+
92
+ // 获取页面容器
93
+ let viewCtn = document.querySelector("#umami-page-views-container");
94
+ // 如果页面容器存在,则获取页面浏览量
95
+ if (viewCtn) {
96
+ let path = window.location.pathname;
97
+ let target = decodeURI(path.replace(/\/*(index.html)?$/, "/"));
98
+ pageStats(target);
99
+ }