hexo-theme-stellar 1.19.0 → 1.21.0

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.
Files changed (89) hide show
  1. package/README.md +3 -3
  2. package/_config.yml +49 -22
  3. package/languages/zh-CN.yml +1 -1
  4. package/languages/zh-TW.yml +1 -1
  5. package/layout/404.ejs +1 -1
  6. package/layout/_partial/cover/wiki_cover.ejs +10 -16
  7. package/layout/_partial/head.ejs +3 -3
  8. package/layout/_partial/main/article/article_footer.ejs +86 -54
  9. package/layout/_partial/main/article/read_next.ejs +17 -12
  10. package/layout/_partial/main/navbar/breadcrumb.ejs +55 -17
  11. package/layout/_partial/main/navbar/list_post.ejs +6 -4
  12. package/layout/_partial/main/navbar/list_wiki.ejs +4 -3
  13. package/layout/_partial/main/post_list/post_card.ejs +1 -1
  14. package/layout/_partial/main/post_list/wiki_card.ejs +6 -11
  15. package/layout/_partial/{main/article/ai_abstract.ejs → plugins/ai/tianli_gpt.ejs} +3 -2
  16. package/layout/_partial/plugins/comments/beaudar/script.ejs +1 -1
  17. package/layout/_partial/plugins/comments/giscus/script.ejs +1 -1
  18. package/layout/_partial/plugins/comments/layout.ejs +2 -2
  19. package/layout/_partial/plugins/comments/utterances/script.ejs +1 -1
  20. package/layout/_partial/sidebar/header.ejs +1 -1
  21. package/layout/_partial/sidebar/index.ejs +4 -4
  22. package/layout/_partial/widgets/ghissues.ejs +1 -1
  23. package/layout/_partial/widgets/ghrepo.ejs +1 -1
  24. package/layout/_partial/widgets/ghuser.ejs +1 -1
  25. package/layout/_partial/widgets/recent.ejs +3 -3
  26. package/layout/_partial/widgets/related.ejs +13 -21
  27. package/layout/_partial/widgets/toc.ejs +20 -12
  28. package/layout/index.ejs +13 -11
  29. package/layout/mermaid.ejs +8 -4
  30. package/layout/page.ejs +3 -0
  31. package/layout/post.ejs +1 -1
  32. package/layout/wiki.ejs +4 -1
  33. package/package.json +1 -1
  34. package/scripts/events/lib/doc_tree.js +142 -97
  35. package/scripts/filters/index.js +4 -1
  36. package/scripts/helpers/category_color.js +18 -5
  37. package/scripts/tags/index.js +5 -3
  38. package/scripts/tags/inline-labels.js +2 -2
  39. package/scripts/tags/lib/banner.js +68 -0
  40. package/scripts/tags/lib/{ablock.js → box.js} +4 -4
  41. package/scripts/tags/lib/checkbox.js +1 -1
  42. package/scripts/tags/lib/folders.js +1 -1
  43. package/scripts/tags/lib/folding.js +1 -1
  44. package/scripts/tags/lib/gallery.js +51 -0
  45. package/scripts/tags/lib/hashtag.js +36 -0
  46. package/scripts/tags/lib/image.js +5 -1
  47. package/scripts/tags/lib/mark.js +1 -1
  48. package/scripts/tags/lib/navbar.js +15 -34
  49. package/scripts/tags/lib/note.js +1 -1
  50. package/scripts/tags/lib/okr.js +140 -0
  51. package/scripts/tags/lib/swiper.js +1 -1
  52. package/scripts/tags/lib/timeline.js +3 -3
  53. package/scripts/tags/lib/toc.js +1 -1
  54. package/source/css/_common/highlight.styl +3 -0
  55. package/source/css/_custom.styl +2 -2
  56. package/source/css/_defines/theme.styl +0 -1
  57. package/source/css/_layout/list.styl +12 -4
  58. package/source/css/_layout/md.styl +11 -8
  59. package/source/css/_layout/partial/bread-nav.styl +32 -0
  60. package/source/css/_layout/partial/cover.styl +2 -0
  61. package/source/css/_layout/partial/paginator.styl +9 -5
  62. package/source/css/_layout/tag-plugins/banner.styl +106 -0
  63. package/source/css/_layout/tag-plugins/common.styl +33 -39
  64. package/source/css/_layout/tag-plugins/folding.styl +1 -1
  65. package/source/css/_layout/tag-plugins/frame.styl +1 -1
  66. package/source/css/_layout/tag-plugins/gallery.styl +46 -0
  67. package/source/css/_layout/tag-plugins/grid.styl +0 -9
  68. package/source/css/_layout/tag-plugins/hashtag.styl +17 -0
  69. package/source/css/_layout/tag-plugins/mark.styl +2 -5
  70. package/source/css/_layout/tag-plugins/note.styl +2 -1
  71. package/source/css/_layout/tag-plugins/okr.styl +106 -0
  72. package/source/css/_layout/tag-plugins/timeline.styl +14 -1
  73. package/source/css/_layout/widgets/ghuser.styl +5 -6
  74. package/source/css/_plugins/copycode.styl +17 -6
  75. package/source/css/_plugins/fancybox.styl +4 -0
  76. package/source/css/_plugins/index.styl +2 -0
  77. package/source/css/_plugins/mermaid.styl +125 -10
  78. package/source/css/{_layout/partial/ai_abstract.styl → _plugins/tianli_gpt.styl} +2 -2
  79. package/source/js/main.js +25 -3
  80. package/source/js/plugins/copycode.js +1 -7
  81. package/source/js/plugins/fcircle.js +3 -3
  82. package/source/js/plugins/friends.js +3 -3
  83. package/source/js/plugins/linkcard.js +1 -1
  84. package/source/js/plugins/memos.js +133 -0
  85. package/source/js/plugins/sites.js +4 -4
  86. package/source/js/plugins/timeline.js +3 -3
  87. package/source/js/plugins/weibo.js +3 -3
  88. package/scripts/tags/lib/tag.js +0 -35
  89. package/source/css/_layout/tag-plugins/tag.styl +0 -13
package/README.md CHANGED
@@ -10,10 +10,10 @@ Stellar 是一个内置文档系统的简约商务风 Hexo 主题,支持丰富
10
10
  Check your environment:
11
11
 
12
12
  ```yaml
13
- Hexo: 5.4.0 ~ 6.3.0
13
+ Hexo: 6.3.0 ~ 7.0.0
14
14
  hexo-cli: 4.3.0 ~ latest
15
- node.js: 14.17.3 ~ 18.12.0
16
- npm: 6.14.13 ~ 8.19.2
15
+ node: 14.17.3 20.10.0 # 建议选择 LTS 版本,过高的版本 hexo 还没有进行兼容。
16
+ npm: 6.14.13 ~ 10.2.3
17
17
  ```
18
18
 
19
19
  Edit your `_config.yml`:
package/_config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  ######## Stellar info ########
2
2
  stellar:
3
- version: '1.19.0'
3
+ version: '1.21.0'
4
4
  homepage: 'https://xaoxuu.com/wiki/stellar/'
5
5
  repo: 'https://github.com/xaoxuu/hexo-theme-stellar'
6
6
  cdn_css: # Use cdn links instead of /css/main.css
@@ -38,7 +38,7 @@ sidebar:
38
38
  # 文章内页
39
39
  post: search_blog, toc, ghrepo, ghissues # for pages using 'layout:post'
40
40
  # 文档内页
41
- wiki: search, ghrepo, toc, ghissues, related # for pages using 'layout:wiki'
41
+ wiki: search, toc, ghissues, related # for pages using 'layout:wiki'
42
42
  # 其它 layout:page 的页面
43
43
  page: toc, search # for custom pages using 'layout:page'
44
44
 
@@ -182,16 +182,16 @@ comments:
182
182
  footer:
183
183
  social:
184
184
  # github:
185
- # icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/social/08a41b181ce68.svg"/>'
185
+ # icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/social/08a41b181ce68.svg"/>'
186
186
  # url: /
187
187
  # music:
188
- # icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/social/3845874.svg"/>'
188
+ # icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/social/3845874.svg"/>'
189
189
  # url: /
190
190
  # unsplash:
191
- # icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/social/3616429.svg"/>'
191
+ # icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/social/3616429.svg"/>'
192
192
  # url: /
193
193
  # comments:
194
- # icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/social/942ebbf1a4b91.svg"/>'
194
+ # icon: '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/social/942ebbf1a4b91.svg"/>'
195
195
  # url: /about/#comments
196
196
  sitemap:
197
197
  # '博客':
@@ -215,7 +215,7 @@ footer:
215
215
 
216
216
  ######## Tag Plugins ########
217
217
  tag_plugins:
218
- # {% ablock %} / {% note %}
218
+ # {% box %} / {% note %}
219
219
  note:
220
220
  default_color: '' # light, dark, red, orange, yellow, green, cyan, blue, purple, warning, error
221
221
  border: true # true / false
@@ -248,9 +248,31 @@ tag_plugins:
248
248
  # {% mark %}
249
249
  mark:
250
250
  default_color: dark # light, dark, red, orange, yellow, green, cyan, blue, purple, warning, error
251
- # {% tag %}
252
- tag:
253
- default_color: yellow # red, orange, yellow, green, cyan, blue, purple
251
+ # {% hashtag %}
252
+ hashtag:
253
+ default_color: # red, orange, yellow, green, cyan, blue, purple
254
+ # {% okr o1 percent:0.5 status:normal %}
255
+ okr:
256
+ border: true # 是否显示边框
257
+ status: # 可以自行增加
258
+ # 进行中状态
259
+ in_track:
260
+ color: blue # red, orange, yellow, green, cyan, blue, purple
261
+ label: 正常
262
+ at_risk:
263
+ color: yellow
264
+ label: 风险
265
+ off_track:
266
+ color: orange
267
+ label: 延期
268
+ # 结果状态
269
+ finished:
270
+ color: green
271
+ label: 已完成
272
+ unfinished:
273
+ color: red
274
+ label: 未完成
275
+
254
276
 
255
277
 
256
278
  ######## JS Plugins ########
@@ -268,6 +290,7 @@ plugins:
268
290
  linkcard: /js/plugins/linkcard.js
269
291
  fcircle: /js/plugins/fcircle.js
270
292
  weibo: /js/plugins/weibo.js
293
+ memos: /js/plugins/memos.js
271
294
 
272
295
  marked: https://cdn.bootcdn.net/ajax/libs/marked/4.0.18/marked.min.js
273
296
 
@@ -304,13 +327,13 @@ plugins:
304
327
  # 可以处理评论区的图片(不支持 iframe 类评论系统)例如:
305
328
  # 使用twikoo评论可以写: .tk-content img:not([class*="emo"])
306
329
  # 使用waline评论可以写: #waline_container .vcontent img
307
- selector: .swiper-slide img # 多个选择器用英文逗号隔开
330
+ selector: .swiper-slide img, .gallery img # 多个选择器用英文逗号隔开
308
331
 
309
332
  # swiper
310
333
  swiper:
311
334
  enable: true
312
- css: https://unpkg.com/swiper@8.4.5/swiper-bundle.min.css
313
- js: https://unpkg.com/swiper@8.4.5/swiper-bundle.min.js
335
+ css: https://unpkg.com/swiper@10.3/swiper-bundle.min.css
336
+ js: https://unpkg.com/swiper@10.3/swiper-bundle.min.js
314
337
 
315
338
 
316
339
  # 赫蹏 (Heti) - 专为中文网页内容设计的排版样式增强
@@ -351,8 +374,7 @@ plugins:
351
374
  # js: https://unpkg.com/mermaid@9.0.0/dist/mermaid.min.js
352
375
  js: https://cdn.jsdelivr.net/npm/mermaid@v9/dist/mermaid.min.js
353
376
  # Available themes: default | dark | forest | neutral
354
- # 推荐使用 dark 主题 在夜间模式下显示效果更好
355
- theme: dark
377
+ theme: neutral
356
378
 
357
379
  # 代码块复制按钮
358
380
  copycode:
@@ -366,11 +388,12 @@ plugins:
366
388
  tianli_gpt:
367
389
  enable: false
368
390
  field: post # all, post, wiki
369
- api: 5Q5mpqRK5DkwT1X9Gi5e
391
+ api: 5Q5mpqRK5DkwT1X9Gi5e # tianli_gpt key
392
+ typingAnimate: true # 打字机动画
370
393
 
371
394
  style:
372
395
  darkmode: auto # auto / always / false
373
- smooth_scroll: true # true / false
396
+ smooth_scroll: false # true / false 开启时如果目录过长可能无法准确定位
374
397
  font-size:
375
398
  root: 16px
376
399
  body: .9375rem # 15px
@@ -399,9 +422,11 @@ style:
399
422
  link: 'hsl(207 90% 54%)' # 超链接颜色
400
423
  button: 'hsl(192 98% 55%)' # 按钮颜色
401
424
  hover: 'hsl(14 100% 57%)' # 按钮高亮颜色
425
+ link:
426
+ underline: true # true / false
402
427
  animated_avatar:
403
428
  animate: auto # auto, always
404
- background: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/avatar/round/rainbow64@3x.webp
429
+ background: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/avatar/round/rainbow64@3x.webp
405
430
  codeblock:
406
431
  scrollbar: 4px
407
432
  highlightjs_theme: https://gcore.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/styles/atom-one-dark.min.css
@@ -413,10 +438,12 @@ style:
413
438
  search: 'linear-gradient(to right, #04F3FF, #08FFC6, #DDF730, #FFBD19, #FF1FE0, #C418FF, #04F3FF)'
414
439
 
415
440
  default:
416
- avatar: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/avatar/round/3442075.svg
417
- link: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/link/8f277b4ee0ecd.svg
418
- cover: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/cover/76b86c0226ffd.svg
419
- image: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/image/2659360.svg
441
+ avatar: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/avatar/round/3442075.svg
442
+ link: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/link/8f277b4ee0ecd.svg
443
+ cover: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/cover/76b86c0226ffd.svg
444
+ image: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/image/2659360.svg
445
+ project: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/image/2779789.png
446
+ banner: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/banner/books.jpg
420
447
 
421
448
  api_host:
422
449
  ghapi: https://api.github.com
@@ -23,7 +23,7 @@ meta:
23
23
  related_posts: 您可能感兴趣的文章
24
24
  comment_title: 快来参与讨论吧
25
25
  back_to_top: 回到顶部
26
- more: '更多%s'
26
+ more: '更多「%s'
27
27
  created: 发布于
28
28
  updated: 更新于
29
29
  license: 许可协议
@@ -23,7 +23,7 @@ meta:
23
23
  related_posts: 您可能感興趣的文章
24
24
  comment_title: 參與討論
25
25
  back_to_top: 回到頁首
26
- more: '更多%s'
26
+ more: '更多「%s'
27
27
  created: 發布於
28
28
  updated: 更新於
29
29
  license: 授權條款
package/layout/404.ejs CHANGED
@@ -6,7 +6,7 @@ page.header = 'auto';
6
6
  page.robots = 'none';
7
7
  %>
8
8
  <article class='md-text error-page'>
9
- <h1><img id='error' src='https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/404/1c830bfcd517d.svg' alt='404'></h1>
9
+ <h1><img id='error' src='https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/404/1c830bfcd517d.svg' alt='404'></h1>
10
10
  <p class='what'>
11
11
  <strong>
12
12
  <%- __('page.error.what') %>
@@ -1,41 +1,35 @@
1
1
  <%
2
2
  function layoutWikiCover() {
3
3
  var el = '';
4
- let proj = theme.wiki.projects[page.wiki];
4
+ let proj = theme.wiki.tree[page.wiki];
5
5
  if (proj == undefined) {
6
6
  return el;
7
7
  }
8
8
  if (proj.homepage.path !== page.path) {
9
9
  return;
10
10
  }
11
- if (proj.cover == undefined || proj.cover === false || proj.cover === '[]') {
11
+ if (proj.coverpage == undefined || proj.coverpage === false || proj.coverpage === '[]') {
12
12
  return el;
13
13
  }
14
- var cover = proj.cover;
15
- let logo = proj.logo;
14
+ var coverpage = proj.coverpage;
15
+ let cover = proj.cover;
16
16
  let title = proj.title || page.title;
17
17
  let desc = proj.description || page.description;
18
- if (cover === true) {
19
- cover = ['logo', 'title', 'description'];
18
+ if (coverpage === true) {
19
+ coverpage = ['cover', 'title', 'description'];
20
20
  }
21
21
  el += '<div class="l_cover wiki' + scrollreveal() + '">';
22
22
  el += '<article class="cover-wrap md-text">';
23
23
 
24
- if (logo && logo.src && cover.includes('logo')) {
25
- el += '<div class="preview">';
26
- if (logo.large) {
27
- el += '<img src="' + logo.src + '" height="' + logo.large + '">';
28
- } else {
29
- el += '<img src="' + logo.src + '">';
30
- }
31
- el += '</div>';
24
+ if (cover?.length > 0 && coverpage.includes('cover')) {
25
+ el += `<div class="preview cover"><img src="${cover}"/></div>`
32
26
  }
33
- if (title && cover.includes('title')) {
27
+ if (title && coverpage.includes('title')) {
34
28
  el += '<div class="cover-title">';
35
29
  el += '<span>' + title + '</span>';
36
30
  el += '</div>';
37
31
  }
38
- if (desc && cover.includes('description')) {
32
+ if (desc && coverpage.includes('description')) {
39
33
  el += '<div class="description">' + desc + '</div>';
40
34
  }
41
35
  el += '<div class="start-wrap">';
@@ -4,7 +4,7 @@ function generate_title() {
4
4
  return page.seo_title;
5
5
  }
6
6
  if (page.wiki) {
7
- let proj = theme.wiki.projects[page.wiki];
7
+ let proj = theme.wiki.tree[page.wiki];
8
8
  let wiki = (proj && proj.name) || page.wiki;
9
9
  if (page.title) {
10
10
  return wiki + __('symbol.colon') + page.title + ' - ' + config.title;
@@ -27,7 +27,7 @@ function generate_description() {
27
27
  return '';
28
28
  }
29
29
  if (page.layout == 'wiki' && page.wiki) {
30
- let proj = theme.wiki.projects[page.wiki];
30
+ let proj = theme.wiki.tree[page.wiki];
31
31
  if (proj && proj.description) {
32
32
  return '<meta name="description" content="' + proj.description + '">';
33
33
  }
@@ -65,7 +65,7 @@ function og_args() {
65
65
  if (page.layout == 'post' && page.cover) {
66
66
  args.twitter_card = 'summary_large_image';
67
67
  }
68
- return args;
68
+ return Object.assign(args, page.open_graph);
69
69
  }
70
70
  %>
71
71
  <head>
@@ -2,63 +2,81 @@
2
2
  function layoutDiv() {
3
3
  var el = '';
4
4
  var item = [];
5
- if (page.references && page.references.length > 0) {
5
+ if (page.references?.length > 0) {
6
6
  item.push('references');
7
7
  }
8
- if (page.layout !== 'wiki') {
9
- if (theme.article.license && theme.article.license.length > 0) {
10
- item.push('license');
11
- }
12
- if (theme.article.share && theme.article.share.length > 0) {
13
- item.push('share');
14
- }
8
+ if (theme.article.license?.length > 0) {
9
+ item.push('license');
10
+ }
11
+ if (theme.article.share?.length > 0) {
12
+ item.push('share');
15
13
  }
16
14
  if (item.length === 0) {
17
15
  return el;
18
16
  }
19
17
  el += '<div class="article-footer reveal fs14">';
20
- if (page.references && page.references.length > 0) {
21
- el += '<section id="references">';
22
- el += '<div class="header">';
23
- el += '<span>' + __('meta.references') + '</span>';
24
- el += '</div>';
25
- el += '<div class="body"><ul>';
26
- page.references.forEach((item, i) => {
27
- el += '<li class="post-title">';
28
- el += '<a href="' + item.url + '"';
29
- if (item.url.includes('://')) {
30
- el += ' target="_blank" rel="external nofollow noopener noreferrer">';
31
- } else {
32
- el += ' rel="noopener noreferrer">';
18
+ if (page.references?.length > 0) {
19
+ function refList() {
20
+ var el = '';
21
+ for (let ref of page.references) {
22
+ el += `
23
+ <li class="post-title">
24
+ ${markdown(ref)}
25
+ </li>
26
+ `
33
27
  }
34
- el += item.title || item.url;
35
- el += '</a>';
36
- el += '</li>';
37
- });
38
- el += '</ul></div>';
39
- el += '</section>';
28
+ return el;
29
+ }
30
+ el += `
31
+ <section id="references">
32
+ <div class="header"><span>${__('meta.references')}</span></div>
33
+ <div class="body">
34
+ <ul>${refList()}</ul>
35
+ </div>
36
+ </section>
37
+ `
40
38
  }
41
39
 
40
+ var license = ''
42
41
  if (page.layout == 'post') {
43
- if (theme.article.license && page.license != false) {
44
- el += '<section id="license">';
45
- el += '<div class="header">';
46
- el += '<span>' + __('meta.license') + '</span>';
47
- el += '</div>';
48
- el += '<div class="body">';
49
- el += markdown(page.license || theme.article.license);
50
- el += '</div>';
51
- el += '</section>';
42
+ if (theme.article.license && (page.license != false)) {
43
+ license = markdown(page.license || theme.article.license)
44
+ }
45
+ } else if (page.layout == 'wiki' && page.wiki) {
46
+ let proj = theme.wiki.tree[page.wiki]
47
+ if (page.license != null) {
48
+ license = markdown(page.license || theme.article.license)
49
+ } else if (proj?.license != null) {
50
+ if (proj.license == true) {
51
+ license = markdown(theme.article.license)
52
+ } else {
53
+ license = markdown(proj.license)
54
+ }
52
55
  }
56
+ }
57
+ if (license.length > 0) {
58
+ el += `
59
+ <section id="license">
60
+ <div class="header"><span>${__('meta.license')}</span></div>
61
+ <div class="body">${license}</div>
62
+ </section>
63
+ `
64
+ }
53
65
 
54
- if (theme.article.share && page.share != false) {
55
- el += '<section id="share">';
56
- el += '<div class="header">';
57
- el += '<span>' + __('meta.share') + '</span>';
58
- el += '</div>';
59
- el += '<div class="body">';
60
- el += '<div class="link"><input class="copy-area" readonly="true" id="copy-link" value="' + page.permalink + '" /></div>';
61
- el += '<div class="social-wrap dis-select">';
66
+ var showSharePlugin = false
67
+ if (page.layout == 'post') {
68
+ showSharePlugin = page.share != false
69
+ } else if (page.layout == 'wiki' && page.wiki) {
70
+ let proj = theme.wiki.tree[page.wiki]
71
+ if (page.share != null) {
72
+ showSharePlugin = page.share == true
73
+ } else if (proj != null) {
74
+ showSharePlugin = proj.share == true
75
+ }
76
+ }
77
+ if (theme.article.share && showSharePlugin) {
78
+ function socialButtons() {
79
+ var el = ''
62
80
  theme.article.share.forEach((item, i) => {
63
81
  if (['wechat', 'weibo', 'email', 'link'].includes(item)) {
64
82
  el += '<a class="social share-item ' + item + '"';
@@ -85,26 +103,40 @@ function layoutDiv() {
85
103
  }
86
104
  el += '>';
87
105
  if (item == 'wechat') {
88
- el += '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/social/b32ef3da1162a.svg"/>';
106
+ el += '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/social/b32ef3da1162a.svg"/>';
89
107
  } else if (item == 'weibo') {
90
- el += '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/social/80c07e4dbb303.svg"/>';
108
+ el += '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/social/80c07e4dbb303.svg"/>';
91
109
  } else if (item == 'email') {
92
- el += '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/social/a1b00e20f425d.svg"/>';
110
+ el += '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/social/a1b00e20f425d.svg"/>';
93
111
  } else if (item == 'link') {
94
- el += '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/social/8411ed322ced6.svg"/>';
112
+ el += '<img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.9/social/8411ed322ced6.svg"/>';
95
113
  }
96
114
  el += '</a>';
97
115
  }
98
116
  });
99
- el += '</div>';
117
+ return el;
118
+ }
119
+ function qrcode() {
100
120
  if (theme.article.share.includes('wechat')) {
101
- el += '<div class="qrcode" id="qrcode-wechat" style="visibility:hidden;height:0">';
102
- el += '<img src="https://api.qrserver.com/v1/create-qr-code/?size=256x256&data=' + page.permalink + '"/>';
103
- el += '</div>';
121
+ return `
122
+ <div class="qrcode" id="qrcode-wechat" style="visibility:hidden;height:0">
123
+ <img src="https://api.qrserver.com/v1/create-qr-code/?size=256x256&data=${page.permalink}"/>
124
+ </div>
125
+ `
126
+ } else {
127
+ return ''
104
128
  }
105
- el += '</div>';
106
- el += '</section>';
107
129
  }
130
+ el += `
131
+ <section id="share">
132
+ <div class="header"><span>${__('meta.share')}</span></div>
133
+ <div class="body">
134
+ <div class="link"><input class="copy-area" readonly="true" id="copy-link" value="${page.permalink}" /></div>
135
+ <div class="social-wrap dis-select">${socialButtons()}</div>
136
+ ${qrcode()}
137
+ </div>
138
+ </section>
139
+ `
108
140
  }
109
141
 
110
142
  el += '</div>';
@@ -10,20 +10,25 @@ function layoutDiv() {
10
10
  title_prev = __('meta.newer');
11
11
  title_next = __('meta.older');
12
12
  } else if (page.layout === 'wiki' && page.wiki && page.wiki.length > 0) {
13
- let proj = theme.wiki.projects[page.wiki];
13
+ let proj = theme.wiki.tree[page.wiki];
14
14
  if (proj) {
15
- const current = page.order || 0;
16
- proj.pages.forEach((p, i) => {
17
- if (p.order < current) {
18
- if (prev == undefined || p.order > prev.order) {
19
- prev = p;
15
+ let ps = proj.pages?.filter(p => p.path == page.path)
16
+ if (ps?.length > 0) {
17
+ const current_page_number = ps[0].page_number || 0;
18
+ proj.pages.forEach((p, i) => {
19
+ if (p.page_number < current_page_number) {
20
+ if (prev == undefined || p.page_number > prev.page_number) {
21
+ prev = p;
22
+ }
23
+ } else if (p.page_number > current_page_number) {
24
+ if (next == undefined || p.page_number < next.page_number) {
25
+ next = p;
26
+ }
20
27
  }
21
- } else if (p.order > current) {
22
- if (next == undefined || p.order < next.order) {
23
- next = p;
24
- }
25
- }
26
- });
28
+ });
29
+ } else {
30
+ console.error('未找到当前页');
31
+ }
27
32
  }
28
33
  }
29
34
  let el = '';
@@ -20,10 +20,11 @@ function layoutDiv() {
20
20
  firstCat = page.categories.data[0].name;
21
21
  }
22
22
  el += '<div class="bread-nav fs12">';
23
+ el += '<div class="left">';
23
24
  el += '<div id="breadcrumb">';
24
- el += '<a class="cap breadcrumb" href="' + config.root + '">' + home_title + '</a>';
25
+ el += '<a class="cap breadcrumb" href="' + url_for(config.root) + '">' + home_title + '</a>';
25
26
  el += '<span class="sep"></span>';
26
- el += '<a class="cap breadcrumb" href="' + config.root + '">' + __("btn.blog") + '</a>';
27
+ el += '<a class="cap breadcrumb" href="' + url_for(config.index_generator.path) + '">' + __("btn.blog") + '</a>';
27
28
  if (page.layout == "post" && page.categories && page.categories.length > 0) {
28
29
  el += '<span class="sep"></span>';
29
30
  el += list_categories(page.categories, {
@@ -36,15 +37,23 @@ function layoutDiv() {
36
37
  el += '</div>';
37
38
  // 发布日期
38
39
  el += '<div id="post-meta">';
39
- el += __("meta.created") + '&nbsp;<time datetime="' + date_xml(page.date) + '">' + date(page.date, config.date_format) + '</time>';
40
+ el += `
41
+ <span>${__("meta.created")}&nbsp;<time datetime="${date_xml(page.date)}">${date(page.date, config.date_format)}</time></span>
42
+ `;
43
+ el += `
44
+ <span>${__("meta.updated")}&nbsp;<time datetime="${date_xml(page.updated)}">${date(page.updated, config.date_format)}</time></span>
45
+ `;
46
+ el += '</div>';
47
+
40
48
  el += '</div>';
41
49
  el += '</div>';
42
50
  } else if (page.layout === "wiki" && page.wiki && page.wiki.length > 0) {
43
51
  el += '<div class="bread-nav fs12">';
52
+ el += '<div class="left">';
44
53
  el += '<div id="breadcrumb">';
45
54
  var nodes = [];
46
55
  // home
47
- el += '<a class="cap breadcrumb" id="home" href="' + config.root + '">' + home_title + '</a>';
56
+ el += '<a class="cap breadcrumb" id="home" href="' + url_for(config.root) + '">' + home_title + '</a>';
48
57
  nodes.push('/');
49
58
  // menu_id
50
59
  el += '<span class="sep"></span>';
@@ -58,26 +67,55 @@ function layoutDiv() {
58
67
  el += '<a class="cap breadcrumb" id="menu" href="' + url + '">' + __("btn.wiki") + '</a>';
59
68
  }
60
69
  // 项目名
61
- let proj = theme.wiki.projects[page.wiki];
62
- let url_proj = url_for(proj.homepage.path);
63
- if (nodes.includes(url_proj) === false) {
64
- el += '<span class="sep"></span>';
65
- el += '<a class="cap breadcrumb" id="proj" href="' + url_proj + '">' + (proj.name || proj.title) + '</a>';
70
+ let proj = theme.wiki.tree[page.wiki];
71
+ if (proj != null) {
72
+ let url_proj = url_for(proj.homepage?.path);
73
+ if (nodes.includes(url_proj) === false) {
74
+ el += '<span class="sep"></span>';
75
+ el += '<a class="cap breadcrumb" id="proj" href="' + url_proj + '">' + (proj.name || proj.title) + '</a>';
76
+ }
66
77
  }
67
78
  el += '</div>';
68
79
  // 更新日期
69
80
  el += '<div id="post-meta">';
70
- el += __("meta.updated") + '&nbsp;<time datetime="' + date_xml(page.updated) + '">' + date(page.updated, config.date_format) + '</time>';
81
+ el += `
82
+ <span>${__("meta.updated")}&nbsp;<time datetime="${date_xml(page.updated)}">${date(page.updated, config.date_format)}</time></span>
83
+ `;
71
84
  el += '</div>';
72
85
  el += '</div>';
73
- } else if (page.title || page.seo_title) {
74
- el += '<div class="bread-nav fs12">';
75
- el += '<div id="breadcrumb">';
76
- el += '<a class="cap breadcrumb" href="' + config.root + '">' + home_title + '</a>';
77
- el += '<span class="sep"></span>';
78
- el += '<a class="cap breadcrumb" href="' + url_for(page.path) + '">' + (page.title || page.seo_title) + '</a>';
79
- el += '</div>';
86
+
87
+ let repo = page.repo || proj.repo
88
+ if (repo) {
89
+ el += `
90
+ <div class="right ghrepo stellar-ghinfo-api" api="${theme.api_host.ghapi}/repos/${repo}">
91
+ <a class="repo-link bold" href="https://github.com/${repo}">
92
+ <svg aria-hidden="true" role="img" class="color-icon-primary" viewBox="0 0 16 16" width="1em" height="1em" fill="currentColor" style="user-select:none;overflow:visible"><path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path></svg>
93
+ <span type="text">${repo}</span>
94
+ </a>
95
+ <a class="repo-link" href="https://github.com/${repo}/stargazers">
96
+ <svg aria-hidden="true" role="img" class="color-icon-primary" viewBox="0 0 16 16" width="1em" height="1em" fill="currentColor" style="user-select:none;overflow:visible"><path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path></svg>
97
+ <span type="text" id="stargazers_count">0</span><span>stars</span>
98
+ </a>
99
+ <a class="repo-link" href="https://github.com/${repo}/forks">
100
+ <svg aria-hidden="true" role="img" class="color-icon-primary" viewBox="0 0 16 16" width="1em" height="1em" fill="currentColor" style="user-select:none;overflow:visible"><path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path></svg>
101
+ <span type="text" id="forks_count">0</span><span>forks</span>
102
+ </a>
103
+ </div>
104
+ `;
105
+ }
80
106
  el += '</div>';
107
+ } else if (page.title || page.seo_title) {
108
+ el += `
109
+ <div class="bread-nav fs12">
110
+ <div class="left">
111
+ <div id="breadcrumb">
112
+ <a class="cap breadcrumb" href="${url_for(config.root)}">${home_title}</a>
113
+ <span class="sep"></span>
114
+ <a class="cap breadcrumb" href="${url_for(page.path)}">${page.title || page.seo_title}</a>
115
+ </div>
116
+ </div>
117
+ </div>
118
+ `;
81
119
  }
82
120
  return el;
83
121
  }
@@ -4,9 +4,9 @@ function layoutDiv() {
4
4
  el += '<div class="nav-wrap">';
5
5
  el += '<nav class="sub post cap">';
6
6
  if (is_home()) {
7
- el += '<a class="active" href="' + url_for("/") + '">' + __("btn.recent_publish") + '</a>';
7
+ el += '<a class="active" href="' + url_for(config.index_generator.path) + '">' + __("btn.recent_publish") + '</a>';
8
8
  } else {
9
- el += '<a href="' + url_for("/") + '">' + __("btn.recent_publish") + '</a>';
9
+ el += '<a href="' + url_for(config.index_generator.path) + '">' + __("btn.recent_publish") + '</a>';
10
10
  }
11
11
 
12
12
  if (site.categories && site.categories.length > 0) {
@@ -40,7 +40,9 @@ function layoutDiv() {
40
40
  if (theme['post-index']) {
41
41
  const obj = theme['post-index'];
42
42
  for (let key of Object.keys(obj)) {
43
- if (full_url_for(page.path) == full_url_for(obj[key])) {
43
+ // page 的末尾为 index.html 或者处于该 page 的某个子页面时也应该匹配
44
+ // if (full_url_for(page.path) == full_url_for(obj[key])) {
45
+ if (full_url_for(page.path).startsWith(full_url_for(obj[key]))){
44
46
  el += '<a class="active" href="' + url_for(obj[key]) + '">' + key + '</a>';
45
47
  } else {
46
48
  el += '<a href="' + url_for(obj[key]) + '">' + key + '</a>';
@@ -54,4 +56,4 @@ function layoutDiv() {
54
56
  }
55
57
  %>
56
58
 
57
- <%- layoutDiv() %>
59
+ <%- layoutDiv() %>