hexo-theme-stellar 1.19.0 → 1.20.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 (57) hide show
  1. package/_config.yml +32 -8
  2. package/layout/_partial/cover/wiki_cover.ejs +1 -1
  3. package/layout/_partial/head.ejs +2 -2
  4. package/layout/_partial/main/article/ai_abstract.ejs +3 -2
  5. package/layout/_partial/main/article/article_footer.ejs +87 -50
  6. package/layout/_partial/main/article/read_next.ejs +17 -12
  7. package/layout/_partial/main/navbar/breadcrumb.ejs +53 -15
  8. package/layout/_partial/main/navbar/list_post.ejs +6 -4
  9. package/layout/_partial/main/navbar/list_wiki.ejs +4 -3
  10. package/layout/_partial/plugins/comments/beaudar/script.ejs +1 -1
  11. package/layout/_partial/plugins/comments/giscus/script.ejs +1 -1
  12. package/layout/_partial/plugins/comments/layout.ejs +2 -2
  13. package/layout/_partial/plugins/comments/utterances/script.ejs +1 -1
  14. package/layout/_partial/sidebar/header.ejs +1 -1
  15. package/layout/_partial/sidebar/index.ejs +3 -3
  16. package/layout/_partial/widgets/ghissues.ejs +1 -1
  17. package/layout/_partial/widgets/ghrepo.ejs +1 -1
  18. package/layout/_partial/widgets/recent.ejs +3 -3
  19. package/layout/_partial/widgets/related.ejs +9 -8
  20. package/layout/_partial/widgets/toc.ejs +15 -10
  21. package/layout/index.ejs +7 -4
  22. package/layout/mermaid.ejs +8 -4
  23. package/layout/page.ejs +3 -0
  24. package/layout/wiki.ejs +3 -0
  25. package/package.json +1 -1
  26. package/scripts/events/lib/doc_tree.js +123 -92
  27. package/scripts/filters/index.js +4 -1
  28. package/scripts/tags/index.js +2 -2
  29. package/scripts/tags/inline-labels.js +2 -2
  30. package/scripts/tags/lib/ablock.js +1 -1
  31. package/scripts/tags/lib/checkbox.js +1 -1
  32. package/scripts/tags/lib/folders.js +1 -1
  33. package/scripts/tags/lib/folding.js +1 -1
  34. package/scripts/tags/lib/hashtag.js +36 -0
  35. package/scripts/tags/lib/image.js +5 -1
  36. package/scripts/tags/lib/mark.js +1 -1
  37. package/scripts/tags/lib/note.js +1 -1
  38. package/scripts/tags/lib/okr.js +140 -0
  39. package/scripts/tags/lib/toc.js +1 -1
  40. package/source/css/_common/highlight.styl +2 -0
  41. package/source/css/_custom.styl +2 -2
  42. package/source/css/_defines/theme.styl +0 -1
  43. package/source/css/_layout/md.styl +10 -7
  44. package/source/css/_layout/partial/bread-nav.styl +32 -0
  45. package/source/css/_layout/partial/paginator.styl +7 -3
  46. package/source/css/_layout/tag-plugins/common.styl +30 -39
  47. package/source/css/_layout/tag-plugins/folding.styl +1 -1
  48. package/source/css/_layout/tag-plugins/hashtag.styl +17 -0
  49. package/source/css/_layout/tag-plugins/mark.styl +2 -5
  50. package/source/css/_layout/tag-plugins/note.styl +1 -1
  51. package/source/css/_layout/tag-plugins/okr.styl +106 -0
  52. package/source/css/_plugins/mermaid.styl +125 -10
  53. package/source/js/main.js +1 -1
  54. package/source/js/plugins/copycode.js +1 -3
  55. package/source/js/plugins/linkcard.js +1 -1
  56. package/scripts/tags/lib/tag.js +0 -35
  57. package/source/css/_layout/tag-plugins/tag.styl +0 -13
package/_config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  ######## Stellar info ########
2
2
  stellar:
3
- version: '1.19.0'
3
+ version: '1.20.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
 
@@ -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 ########
@@ -351,8 +373,7 @@ plugins:
351
373
  # js: https://unpkg.com/mermaid@9.0.0/dist/mermaid.min.js
352
374
  js: https://cdn.jsdelivr.net/npm/mermaid@v9/dist/mermaid.min.js
353
375
  # Available themes: default | dark | forest | neutral
354
- # 推荐使用 dark 主题 在夜间模式下显示效果更好
355
- theme: dark
376
+ theme: neutral
356
377
 
357
378
  # 代码块复制按钮
358
379
  copycode:
@@ -366,7 +387,8 @@ plugins:
366
387
  tianli_gpt:
367
388
  enable: false
368
389
  field: post # all, post, wiki
369
- api: 5Q5mpqRK5DkwT1X9Gi5e
390
+ api: 5Q5mpqRK5DkwT1X9Gi5e # tianli_gpt key
391
+ typingAnimate: true # 打字机动画
370
392
 
371
393
  style:
372
394
  darkmode: auto # auto / always / false
@@ -399,6 +421,8 @@ style:
399
421
  link: 'hsl(207 90% 54%)' # 超链接颜色
400
422
  button: 'hsl(192 98% 55%)' # 按钮颜色
401
423
  hover: 'hsl(14 100% 57%)' # 按钮高亮颜色
424
+ link:
425
+ underline: true # true / false
402
426
  animated_avatar:
403
427
  animate: auto # auto, always
404
428
  background: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.4/avatar/round/rainbow64@3x.webp
@@ -1,7 +1,7 @@
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
  }
@@ -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
  }
@@ -1,7 +1,8 @@
1
1
  <% if (page.layout === 'post' || (page.layout === 'wiki' && page.wiki && page.wiki.length > 0)) { %>
2
2
  <script>
3
- let tianliGPT_postSelector = '.md-text.content.<%= page.layout === 'post' ? 'post' : 'wiki' %>';
3
+ let tianliGPT_postSelector = '.md-text.content.<%= page.layout === "post" ? "post" : "wiki" %>';
4
4
  let tianliGPT_key = '<%= theme.plugins.tianli_gpt.api %>';
5
+ let tianliGPT_typingAnimate = '<%= theme.plugins.tianli_gpt.typingAnimate %>';
5
6
  </script>
6
- <script defer src="https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.9/tianli_gpt.js"></script>
7
+ <script defer src="https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.13/tianli_gpt.js"></script>
7
8
  <% } %>
@@ -2,63 +2,86 @@
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">';
18
+ if (page.references?.length > 0) {
19
+ function refList() {
20
+ var el = '';
21
+ page.references.forEach((item, i) => {
22
+ el += '<li class="post-title">';
23
+ el += '<a href="' + item.url + '"';
24
+ if (item.url.includes('://')) {
25
+ el += ' target="_blank" rel="external nofollow noopener noreferrer">';
26
+ } else {
27
+ el += ' rel="noopener noreferrer">';
28
+ }
29
+ el += item.title || item.url;
30
+ el += '</a>';
31
+ el += '</li>';
32
+ });
33
+ return el;
34
+ }
35
+ el += `
36
+ <section id="references">
37
+ <div class="header"><span>${__('meta.references')}</span></div>
38
+ <div class="body">
39
+ <ul>${refList()}</ul>
40
+ </div>
41
+ </section>
42
+ `
43
+ }
44
+
45
+ var license = ''
46
+ if (page.layout == 'post') {
47
+ if (theme.article.license && (page.license != false)) {
48
+ license = markdown(page.license || theme.article.license)
49
+ }
50
+ } else if (page.layout == 'wiki' && page.wiki) {
51
+ let proj = theme.wiki.tree[page.wiki]
52
+ if (page.license != null) {
53
+ license = markdown(page.license || theme.article.license)
54
+ } else if (proj?.license != null) {
55
+ if (proj.license == true) {
56
+ license = markdown(theme.article.license)
31
57
  } else {
32
- el += ' rel="noopener noreferrer">';
58
+ license = markdown(proj.license)
33
59
  }
34
- el += item.title || item.url;
35
- el += '</a>';
36
- el += '</li>';
37
- });
38
- el += '</ul></div>';
39
- el += '</section>';
60
+ }
61
+ }
62
+ if (license.length > 0) {
63
+ el += `
64
+ <section id="license">
65
+ <div class="header"><span>${__('meta.license')}</span></div>
66
+ <div class="body">${license}</div>
67
+ </section>
68
+ `
40
69
  }
41
70
 
71
+ var showSharePlugin = false
42
72
  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>';
73
+ showSharePlugin = page.share != false
74
+ } else if (page.layout == 'wiki' && page.wiki) {
75
+ let proj = theme.wiki.tree[page.wiki]
76
+ if (page.share != null) {
77
+ showSharePlugin = page.share == true
78
+ } else if (proj != null) {
79
+ showSharePlugin = proj.share == true
52
80
  }
53
-
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">';
81
+ }
82
+ if (theme.article.share && showSharePlugin) {
83
+ function socialButtons() {
84
+ var el = ''
62
85
  theme.article.share.forEach((item, i) => {
63
86
  if (['wechat', 'weibo', 'email', 'link'].includes(item)) {
64
87
  el += '<a class="social share-item ' + item + '"';
@@ -96,15 +119,29 @@ function layoutDiv() {
96
119
  el += '</a>';
97
120
  }
98
121
  });
99
- el += '</div>';
122
+ return el;
123
+ }
124
+ function qrcode() {
100
125
  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>';
126
+ return `
127
+ <div class="qrcode" id="qrcode-wechat" style="visibility:hidden;height:0">
128
+ <img src="https://api.qrserver.com/v1/create-qr-code/?size=256x256&data=${page.permalink}"/>
129
+ </div>
130
+ `
131
+ } else {
132
+ return ''
104
133
  }
105
- el += '</div>';
106
- el += '</section>';
107
134
  }
135
+ el += `
136
+ <section id="share">
137
+ <div class="header"><span>${__('meta.share')}</span></div>
138
+ <div class="body">
139
+ <div class="link"><input class="copy-area" readonly="true" id="copy-link" value="${page.permalink}" /></div>
140
+ <div class="social-wrap dis-select">${socialButtons()}</div>
141
+ ${qrcode()}
142
+ </div>
143
+ </section>
144
+ `
108
145
  }
109
146
 
110
147
  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
25
  el += '<a class="cap breadcrumb" href="' + 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="' + 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,11 +37,19 @@ 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
@@ -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>';
71
- el += '</div>';
81
+ el += `
82
+ <span>${__("meta.updated")}&nbsp;<time datetime="${date_xml(page.updated)}">${date(page.updated, config.date_format)}</time></span>
83
+ `;
72
84
  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
85
  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="${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() %>
@@ -11,9 +11,10 @@ function layoutDiv() {
11
11
  el += ' href="' + url_for(config.wiki_dir || "/wiki/") + '">' + __("btn.all_wiki") + '</a>';
12
12
  el += '</a>';
13
13
  // 项目分类
14
- for (let id of Object.keys(theme.wiki.all_tags)) {
15
- let tag = theme.wiki.all_tags[id];
16
- let projects = tag.items.filter(item => item.index !== false)
14
+ const { shelf, all_tags } = theme.wiki;
15
+ for (let id of Object.keys(all_tags)) {
16
+ let tag = all_tags[id];
17
+ let projects = tag.items.filter(item => shelf.includes(item))
17
18
  if (projects && projects.length > 0) {
18
19
  el += '<a';
19
20
  if (tag.name && tag.name.length > 0 && page.tagName === tag.name) {
@@ -6,7 +6,7 @@
6
6
  try {
7
7
  el.innerHTML = '';
8
8
  } catch (error) {
9
- console.log(error);
9
+ console.error(error);
10
10
  }
11
11
  var script = document.createElement('script');
12
12
  script.src = 'https://beaudar.lipk.org/client.js';
@@ -6,7 +6,7 @@
6
6
  try {
7
7
  el.innerHTML = '';
8
8
  } catch (error) {
9
- console.log(error);
9
+ console.error(error);
10
10
  }
11
11
  var script = document.createElement('script');
12
12
  script.src = 'https://giscus.app/client.js';
@@ -12,8 +12,8 @@ if (theme.comments.service && theme.comments.service.length > 0) {
12
12
  }
13
13
  }
14
14
  // 合并项目评论
15
- if (loadComment && page.layout == 'wiki' && page.wiki) {
16
- let proj = theme.wiki.projects[page.wiki];
15
+ let proj = theme.wiki.tree[page.wiki];
16
+ if (loadComment && page.layout == 'wiki' && page.wiki && (proj != null)) {
17
17
  if (proj.comment_title != undefined && page.comment_title == undefined) {
18
18
  if (['utterances', 'beaudar', 'giscus'].includes(theme.comments.service)) {
19
19
  page.comment_title = proj.comment_title;
@@ -6,7 +6,7 @@
6
6
  try {
7
7
  el.innerHTML = '';
8
8
  } catch (error) {
9
- console.log(error);
9
+ console.error(error);
10
10
  }
11
11
  var script = document.createElement('script');
12
12
  script.src = 'https://utteranc.es/client.js';
@@ -1,7 +1,7 @@
1
1
  <%
2
2
  var proj;
3
3
  if (page.layout === 'wiki' && page.wiki) {
4
- proj = theme.wiki.projects[page.wiki];
4
+ proj = theme.wiki.tree[page.wiki];
5
5
  }
6
6
  function layoutTitle(main, url, sub) {
7
7
  var el = '';
@@ -1,15 +1,15 @@
1
1
  <%
2
2
  var proj;
3
3
  if (page.layout === 'wiki' && page.wiki) {
4
- proj = theme.wiki.projects[page.wiki];
4
+ proj = theme.wiki.tree[page.wiki];
5
5
  }
6
6
  // 默认组件
7
7
  if (page.sidebar == undefined) {
8
8
  if (page.layout == 'post' && page.content) {
9
9
  page.sidebar = theme.sidebar.widgets.post;
10
10
  } else if (page.layout == 'wiki' && page.content && page.wiki) {
11
- let proj = theme.wiki.projects[page.wiki];
12
- if (proj.sidebar) {
11
+ let proj = theme.wiki.tree[page.wiki];
12
+ if (proj?.sidebar) {
13
13
  page.sidebar = proj.sidebar;
14
14
  } else {
15
15
  page.sidebar = theme.sidebar.widgets.wiki;
@@ -6,7 +6,7 @@ function layoutDiv() {
6
6
  if (page.repo) {
7
7
  repo = page.repo
8
8
  } else if (page.layout === 'wiki' && page.wiki) {
9
- let proj = theme.wiki.projects[page.wiki];
9
+ let proj = theme.wiki.tree[page.wiki];
10
10
  if (proj && proj.repo) {
11
11
  repo = proj.repo;
12
12
  if (proj.branch != undefined) {
@@ -6,7 +6,7 @@ function layoutDiv() {
6
6
  if (page.repo) {
7
7
  repo = page.repo
8
8
  } else if (page.layout === 'wiki' && page.wiki) {
9
- let proj = theme.wiki.projects[page.wiki];
9
+ let proj = theme.wiki.tree[page.wiki];
10
10
  if (proj && proj.repo) {
11
11
  repo = proj.repo;
12
12
  if (proj.branch != undefined) {
@@ -15,8 +15,8 @@ function layoutDiv() {
15
15
  if (page.menu_id == 'wiki') {
16
16
  arr = theme.wiki.all_pages.filter( p => {
17
17
  if (p.wiki) {
18
- let proj = theme.wiki.projects[p.wiki];
19
- return proj.index != false;
18
+ let proj = theme.wiki.tree[p.wiki];
19
+ return proj?.index != false;
20
20
  }
21
21
  return false
22
22
  })
@@ -32,7 +32,7 @@ function layoutDiv() {
32
32
  el += '<a class="item title" href="' + url_for(post.link || post.path) + '">';
33
33
  el += '<span class="title">'
34
34
  if (post.layout == 'wiki') {
35
- let proj = theme.wiki.projects[post.wiki];
35
+ let proj = theme.wiki.tree[post.wiki];
36
36
  let name = proj?.name || post?.wiki;
37
37
  if (name) {
38
38
  el += '<strong>' + name + '</strong>' + '<span class="dot"></span>';
@@ -4,11 +4,12 @@ function layoutDiv() {
4
4
  return '';
5
5
  }
6
6
  var related = [];
7
- let proj = theme.wiki.projects[page.wiki];
8
- if (proj.related && proj.related.length > 0) {
9
- proj.related.forEach((pid, i) => {
10
- let p = theme.wiki.projects[pid];
11
- if (p && p.title !== proj.title && p.index !== false) {
7
+ const { shelf, tree } = theme.wiki;
8
+ let proj = tree[page.wiki];
9
+ if (proj?.related?.length > 0) {
10
+ proj.related.filter(pid => shelf.includes(pid)).forEach((pid, i) => {
11
+ let p = tree[pid];
12
+ if (p && p.title !== proj?.title && p.homepage) {
12
13
  related.push(p);
13
14
  }
14
15
  });
@@ -24,15 +25,15 @@ function layoutDiv() {
24
25
  el += '<span class="name">' + __('meta.more', title) + '</span>';
25
26
  el += '</div>';
26
27
  el += '<div class="widget-body related-posts">';
27
- related.forEach((p, i) => {
28
+ for (let p of related) {
28
29
  // 同一个分组中的其它项目
29
- el += '<a class="item wiki" href="' + url_for(p.homepage.path) + '">';
30
+ el += '<a class="item wiki" href="' + url_for(p.homepage?.path) + '">';
30
31
  el += '<span class="title">' + p.title + '</span>';
31
32
  if (p.description && p.description.length > 0) {
32
33
  el += '<span class="excerpt">' + p.description + '</span>';
33
34
  }
34
35
  el += '</a>';
35
- });
36
+ }
36
37
  el += '</div>';
37
38
  el += '</widget>';
38
39
  }