hexo-theme-stellar 1.25.0 → 1.26.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 (117) hide show
  1. package/_config.yml +80 -32
  2. package/_data/icons.yml +33 -0
  3. package/_data/widgets.yml +2 -16
  4. package/languages/zh-CN.yml +1 -1
  5. package/languages/zh-TW.yml +1 -1
  6. package/layout/404.ejs +2 -2
  7. package/layout/_partial/cover/index.ejs +5 -5
  8. package/layout/_partial/cover/post_cover.ejs +1 -1
  9. package/layout/_partial/cover/wiki_cover.ejs +2 -2
  10. package/layout/_partial/head.ejs +5 -8
  11. package/layout/_partial/main/article/article_footer.ejs +7 -15
  12. package/layout/_partial/main/article/read_next.ejs +6 -6
  13. package/layout/_partial/main/article/related_posts.ejs +1 -1
  14. package/layout/_partial/main/footer.ejs +1 -1
  15. package/layout/_partial/main/navbar/article_top_area.ejs +35 -0
  16. package/layout/_partial/main/navbar/author_banner.ejs +1 -3
  17. package/layout/_partial/main/navbar/breadcrumb/blog.ejs +34 -0
  18. package/layout/_partial/main/navbar/breadcrumb/page.ejs +10 -0
  19. package/layout/_partial/main/navbar/breadcrumb/wiki.ejs +20 -0
  20. package/layout/_partial/main/navbar/dateinfo.ejs +32 -0
  21. package/layout/_partial/main/navbar/ghinfo.ejs +25 -0
  22. package/layout/_partial/main/navbar/nav_tabs_blog.ejs +3 -3
  23. package/layout/_partial/main/navbar/nav_tabs_wiki.ejs +2 -2
  24. package/layout/_partial/main/post_list/paginator.ejs +1 -1
  25. package/layout/_partial/main/post_list/post_card.ejs +3 -3
  26. package/layout/_partial/menubtn.ejs +1 -1
  27. package/layout/_partial/plugins/ai/tianli_gpt.ejs +4 -3
  28. package/layout/_partial/plugins/comments/artalk/layout.ejs +1 -1
  29. package/layout/_partial/plugins/comments/artalk/script.ejs +1 -1
  30. package/layout/_partial/plugins/comments/beaudar/layout.ejs +1 -1
  31. package/layout/_partial/plugins/comments/giscus/layout.ejs +1 -1
  32. package/layout/_partial/plugins/comments/layout.ejs +3 -3
  33. package/layout/_partial/plugins/comments/twikoo/layout.ejs +1 -1
  34. package/layout/_partial/plugins/comments/utterances/layout.ejs +1 -1
  35. package/layout/_partial/plugins/comments/waline/layout.ejs +1 -1
  36. package/layout/_partial/sidebar/index.ejs +72 -71
  37. package/layout/_partial/sidebar/logo.ejs +87 -0
  38. package/layout/_partial/sidebar/menu.ejs +23 -18
  39. package/layout/_partial/sidebar/search.ejs +42 -0
  40. package/layout/_partial/widgets/components/link.ejs +21 -0
  41. package/layout/_partial/widgets/components/linklist.ejs +27 -0
  42. package/layout/_partial/widgets/ghissues.ejs +7 -9
  43. package/layout/_partial/widgets/ghrepo.ejs +10 -12
  44. package/layout/_partial/widgets/ghuser.ejs +2 -6
  45. package/layout/_partial/widgets/linklist.ejs +17 -0
  46. package/layout/_partial/widgets/markdown.ejs +5 -2
  47. package/layout/_partial/widgets/recent.ejs +12 -8
  48. package/layout/_partial/widgets/related.ejs +13 -9
  49. package/layout/_partial/widgets/search.ejs +0 -40
  50. package/layout/_partial/widgets/tagcloud.ejs +2 -2
  51. package/layout/_partial/widgets/timeline.ejs +2 -2
  52. package/layout/_partial/widgets/toc.ejs +24 -24
  53. package/layout/archive.ejs +2 -2
  54. package/layout/categories.ejs +1 -1
  55. package/layout/index.ejs +4 -20
  56. package/layout/index_topic.ejs +1 -1
  57. package/layout/index_wiki.ejs +2 -2
  58. package/layout/layout.ejs +53 -21
  59. package/layout/page.ejs +59 -12
  60. package/layout/tags.ejs +1 -1
  61. package/package.json +2 -2
  62. package/scripts/events/lib/config.js +28 -24
  63. package/scripts/events/lib/doc_tree.js +27 -19
  64. package/scripts/events/lib/merge_posts.js +0 -1
  65. package/scripts/generators/topic.js +3 -3
  66. package/scripts/generators/wiki.js +5 -4
  67. package/scripts/helpers/category_color.js +1 -1
  68. package/scripts/helpers/icon.js +16 -0
  69. package/scripts/helpers/parse_config.js +18 -16
  70. package/scripts/helpers/scrollreveal.js +6 -6
  71. package/scripts/tags/lib/toc.js +1 -1
  72. package/source/css/_common/blur.styl +1 -8
  73. package/source/css/_common/cap.styl +1 -1
  74. package/source/css/_common/device.styl +2 -2
  75. package/source/css/_common/highlight.styl +2 -2
  76. package/source/css/_common/layout.styl +6 -0
  77. package/source/css/_common/svg.styl +3 -0
  78. package/source/css/_custom.styl +9 -2
  79. package/source/css/_defines/theme.styl +10 -0
  80. package/source/css/_layout/layout.styl +17 -4
  81. package/source/css/_layout/list.styl +5 -2
  82. package/source/css/_layout/main.styl +5 -4
  83. package/source/css/_layout/md.styl +12 -11
  84. package/source/css/_layout/partial/paginator.styl +2 -2
  85. package/source/css/_layout/sidebar/footer.styl +4 -31
  86. package/source/css/_layout/sidebar/{header.styl → logo.styl} +11 -41
  87. package/source/css/_layout/sidebar/menu.styl +53 -0
  88. package/source/css/_layout/sidebar/nav-area.styl +2 -0
  89. package/source/css/_layout/{widgets → sidebar}/search.styl +51 -50
  90. package/source/css/_layout/sidebar/sidebar.styl +21 -31
  91. package/source/css/_layout/tag-plugins/banner.styl +9 -10
  92. package/source/css/_layout/tag-plugins/okr.styl +0 -1
  93. package/source/css/_layout/tag-plugins/tabs.styl +2 -2
  94. package/source/css/_layout/tag-plugins/toc.styl +1 -1
  95. package/source/css/_layout/widgets/components.styl +49 -0
  96. package/source/css/_layout/widgets/ghrepo.styl +0 -1
  97. package/source/css/_layout/widgets/ghuser.styl +0 -23
  98. package/source/css/_layout/widgets/list.styl +28 -0
  99. package/source/css/_layout/widgets/markdown.styl +20 -0
  100. package/source/css/_layout/widgets/related.styl +36 -5
  101. package/source/css/_layout/widgets/timeline.styl +21 -2
  102. package/source/css/_layout/widgets/toc_blog.styl +1 -1
  103. package/source/css/_layout/widgets/toc_common.styl +12 -12
  104. package/source/css/_layout/widgets/toc_wiki.styl +38 -25
  105. package/source/css/_layout/widgets/widgets.styl +25 -20
  106. package/source/css/_plugins/comments/twikoo.styl +9 -9
  107. package/source/css/_plugins/scrollreveal.styl +1 -1
  108. package/source/css/_plugins/tianli_gpt.styl +12 -14
  109. package/source/js/main.js +5 -2
  110. package/source/js/plugins/copycode.js +3 -3
  111. package/layout/_partial/main/header/index.ejs +0 -3
  112. package/layout/_partial/main/navbar/breadcrumb.ejs +0 -161
  113. package/layout/_partial/sidebar/header.ejs +0 -58
  114. package/layout/post.ejs +0 -33
  115. package/layout/topic.ejs +0 -28
  116. package/layout/wiki.ejs +0 -32
  117. package/source/css/_layout/widgets/recent.styl +0 -15
@@ -0,0 +1,20 @@
1
+ <%
2
+ function layoutDiv() {
3
+ const wikiObject = theme.wiki.tree[page.wiki]
4
+ var el = ''
5
+ // 文档列表页
6
+ el += `<span class="sep"></span>`
7
+ const wikiIndexPageURL = url_for(theme.site_tree.index_wiki.base_dir)
8
+ el += `<a class="cap breadcrumb" id="menu" href="${wikiIndexPageURL}">${__("btn.wiki")}</a>`
9
+ if (wikiObject) {
10
+ // 文档项目名
11
+ const wikiHomePageURL = url_for(wikiObject.homepage?.path);
12
+ if (wikiHomePageURL != wikiIndexPageURL) {
13
+ el += `<span class="sep"></span>`
14
+ el += `<a class="cap breadcrumb" id="proj" href="${wikiHomePageURL}">${wikiObject.name || wikiObject.title}</a>`
15
+ }
16
+ }
17
+ return el
18
+ }
19
+ %>
20
+ <%- layoutDiv() %>
@@ -0,0 +1,32 @@
1
+ <%
2
+ function layoutDiv() {
3
+ // 作者
4
+ const author = theme.authors ? (theme.authors[page.author] || theme.default_author) : null
5
+ var el = ''
6
+ el += `<div id="post-meta">`
7
+ if (page.wiki) {
8
+ el += `<span class="author">${__("meta.updated") + __("symbol.colon")}</span>`
9
+ el += `<time datetime="${date_xml(page.updated)}">${date(page.updated, config.date_format)}</time>`
10
+ el += `</span>`
11
+ } else {
12
+ if (author) {
13
+ const link = `<a href="${url_for(author.path)}">${author.name}</a>`
14
+ el += `<span class="author">${__("meta.created_author", link) + __("symbol.colon")}</span>`
15
+ } else {
16
+ el += `<span class="author">${__("meta.created") + __("symbol.colon")}</span>`
17
+ }
18
+ // 发布日期
19
+ el += `<span class="created">`
20
+ el += `<time datetime="${date_xml(page.date)}">${date(page.date, config.date_format)}</time>`
21
+ el += `</span>`
22
+ // 更新日期
23
+ el += `<span class="updated">`
24
+ el += `${__("symbol.comma") + __("meta.updated") + __("symbol.colon")}`
25
+ el += `<time datetime="${date_xml(page.updated)}">${date(page.updated, config.date_format)}</time>`
26
+ el += `</span>`
27
+ }
28
+ el += `</div>`
29
+ return el
30
+ }
31
+ %>
32
+ <%- layoutDiv() %>
@@ -0,0 +1,25 @@
1
+ <%
2
+ function layoutDiv() {
3
+ const repo = page.repo || theme.wiki.tree[page.wiki]?.repo
4
+ if (repo == null) {
5
+ return ''
6
+ }
7
+ return `
8
+ <div class="right ghrepo stellar-ghinfo-api" api="${theme.api_host.ghapi}/repos/${repo}">
9
+ <a class="repo-link bold" href="https://github.com/${repo}">
10
+ ${icon('github:repo')}
11
+ <span type="text">${repo}</span>
12
+ </a>
13
+ <a class="repo-link" href="https://github.com/${repo}/stargazers">
14
+ ${icon('github:star')}
15
+ <span type="text" id="stargazers_count">0</span><span>stars</span>
16
+ </a>
17
+ <a class="repo-link" href="https://github.com/${repo}/forks">
18
+ ${icon('github:fork')}
19
+ <span type="text" id="forks_count">0</span><span>forks</span>
20
+ </a>
21
+ </div>
22
+ `
23
+ }
24
+ %>
25
+ <%- layoutDiv() %>
@@ -31,9 +31,9 @@ function layoutDiv() {
31
31
 
32
32
  if (theme.topic?.publish_list?.length > 0) {
33
33
  if (page.layout == 'index_topic') {
34
- el += '<a class="active" href="' + url_for(theme.site_tree.topic.base_dir) + '">' + __("btn.topic") + '</a>';
34
+ el += '<a class="active" href="' + url_for(theme.site_tree.index_topic.base_dir) + '">' + __("btn.topic") + '</a>';
35
35
  } else {
36
- el += '<a href="' + url_for(theme.site_tree.topic.base_dir) + '">' + __("btn.topic") + '</a>';
36
+ el += '<a href="' + url_for(theme.site_tree.index_topic.base_dir) + '">' + __("btn.topic") + '</a>';
37
37
  }
38
38
  }
39
39
 
@@ -45,7 +45,7 @@ function layoutDiv() {
45
45
  }
46
46
  }
47
47
 
48
- const { nav_tabs } = theme.site_tree.blog
48
+ const { nav_tabs } = theme.site_tree.index_blog
49
49
  if (nav_tabs) {
50
50
  for (let key of Object.keys(nav_tabs)) {
51
51
  // 当 page 的末尾为 index.html 或者处于该 page 的某个子页面时也应该匹配
@@ -8,7 +8,7 @@ function layoutDiv() {
8
8
  if (page.filter === false) {
9
9
  el += ' class="active"';
10
10
  }
11
- el += ' href="' + url_for(theme.site_tree.wiki.base_dir) + '">' + __("btn.all_wiki") + '</a>';
11
+ el += ' href="' + url_for(theme.site_tree.index_wiki.base_dir) + '">' + __("btn.all_wiki") + '</a>';
12
12
  el += '</a>';
13
13
  // 项目分类
14
14
  const { shelf, all_tags } = theme.wiki;
@@ -25,7 +25,7 @@ function layoutDiv() {
25
25
  }
26
26
  }
27
27
 
28
- const { nav_tabs } = theme.site_tree.wiki
28
+ const { nav_tabs } = theme.site_tree.index_wiki
29
29
  if (nav_tabs) {
30
30
  for (let key of Object.keys(nav_tabs)) {
31
31
  // 当 page 的末尾为 index.html 或者处于该 page 的某个子页面时也应该匹配
@@ -1,5 +1,5 @@
1
1
  <% if ((is_home() || is_category() || is_tag()) && page.total > 1) { %>
2
- <div class='paginator-wrap dis-select'>
2
+ <div class='paginator-wrap dis-select<%- scrollreveal(' ') %>'>
3
3
  <%- paginator({
4
4
  prev_text: '',
5
5
  next_text: '',
@@ -46,7 +46,7 @@ function div_default() {
46
46
 
47
47
  // 标题
48
48
  el += '<h2 class="post-title">';
49
- el += (post.title || post.seo_title) ? (post.title || post.seo_title) : date(post.date, config.date_format);
49
+ el += post.title ? post.title : date(post.date, config.date_format);
50
50
  el += '</h2>';
51
51
 
52
52
  // 摘要
@@ -90,8 +90,8 @@ function div_default() {
90
90
  }
91
91
  }
92
92
  }
93
- if (post.pin) {
94
- el += '<span class="pin"><img src="https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/badge/3279dd441df8b.svg"/></span>';
93
+ if (post.sticky) {
94
+ el += `<span class="pin">${icon('default:pin')}</span>`
95
95
  }
96
96
  el += '</div>';
97
97
  el += '</article>';
@@ -1,5 +1,5 @@
1
1
  <div class='float-panel mobile-only blur' style='display:none'>
2
2
  <button type='button' class='sidebar-toggle mobile' onclick='sidebar.toggle()'>
3
- <svg class="icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15301"><path d="M566.407 808.3c26.9-0.1 49.3-20.8 51.6-47.6-1.9-27.7-23.9-49.7-51.6-51.6h-412.6c-28.2-1.4-52.6 19.5-55.5 47.6 2.3 26.8 24.6 47.5 51.6 47.6h416.5v4z m309.3-249.9c26.9-0.1 49.3-20.8 51.6-47.6-2.2-26.8-24.6-47.5-51.6-47.6h-721.9c-27.7-2.8-52.5 17.4-55.3 45.1-0.1 0.8-0.1 1.7-0.2 2.5 0.9 27.2 23.6 48.5 50.7 47.6H875.707z m-103.1-245.9c26.9-0.1 49.3-20.8 51.6-47.6-0.4-28.3-23.2-51.1-51.5-51.6h-618.9c-29.5-1.1-54.3 21.9-55.5 51.4v0.2c1.4 27.8 25.2 49.2 53 47.8 0.8 0 1.7-0.1 2.5-0.2h618.8z" p-id="15302"></path><path d="M566.407 808.3c26.9-0.1 49.3-20.8 51.6-47.6-1.9-27.7-23.9-49.7-51.6-51.6h-412.6c-28.2-1.4-52.6 19.5-55.5 47.6 1.9 27.7 23.9 49.7 51.6 51.6h416.5z m309.3-249.9c26.9-0.1 49.3-20.8 51.6-47.6-2.2-26.8-24.6-47.5-51.6-47.6h-721.9c-27.7-2.8-52.5 17.4-55.3 45.1-0.1 0.8-0.1 1.7-0.2 2.5 0.9 27.2 23.6 48.5 50.7 47.6H875.707z m-103.1-245.9c26.9-0.1 49.3-20.8 51.6-47.6-0.4-28.3-23.2-51.1-51.5-51.6h-618.9c-29.5-1.1-54.3 21.9-55.5 51.4v0.2c1.4 27.8 25.2 49.2 53 47.8 0.8 0 1.7-0.1 2.5-0.2h618.8z" p-id="15303"></path></svg>
3
+ <%- icon('default:sidebar') %>
4
4
  </button>
5
5
  </div>
@@ -1,8 +1,9 @@
1
- <% if (page.layout === 'post' || (page.layout === 'wiki' && page.wiki && page.wiki.length > 0)) { %>
1
+ <% if (page.layout === 'post' || (page.wiki?.length > 0)) { %>
2
2
  <script>
3
- let tianliGPT_postSelector = '.md-text.content.<%= page.layout === "post" ? "post" : "wiki" %>';
3
+ let tianliGPT_postSelector = 'article.content';
4
4
  let tianliGPT_key = '<%= theme.plugins.tianli_gpt.api %>';
5
5
  let tianliGPT_typingAnimate = '<%= theme.plugins.tianli_gpt.typingAnimate %>';
6
+ let tianliGPT_wordLimit = <%= theme.plugins.tianli_gpt.limit %>;
6
7
  </script>
7
- <script defer src="https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.13/tianli_gpt.js"></script>
8
+ <script defer src="https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.15.2/tianli_gpt.min.js"></script>
8
9
  <% } %>
@@ -11,7 +11,7 @@ function layoutDiv() {
11
11
  el += ' ' + key + '="' + cfg[key] + '"';
12
12
  }
13
13
  }
14
- el += '><svg class="loading" style="vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2709"><path d="M832 512c0-176-144-320-320-320V128c211.2 0 384 172.8 384 384h-64zM192 512c0 176 144 320 320 320v64C300.8 896 128 723.2 128 512h64z" p-id="2710"></path></svg></div>';
14
+ el += `>${icon('default:loading')}</div>`
15
15
  return el;
16
16
  }
17
17
  %>
@@ -11,7 +11,7 @@
11
11
  var artalk = Artalk.init({
12
12
  el: '#artalk_container',
13
13
  pageKey: path,
14
- pageTitle: '<%= page.title || page.seo_title %>',
14
+ pageTitle: '<%= page.title %>',
15
15
  server: '<%= theme.comments.artalk.server %>',
16
16
  placeholder: '<%= theme.comments.artalk.placeholder %>',
17
17
  site: '<%= config.title %>',
@@ -17,6 +17,6 @@ function layoutDiv() {
17
17
  }
18
18
  %>
19
19
 
20
- <svg class="loading" style="vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2709"><path d="M832 512c0-176-144-320-320-320V128c211.2 0 384 172.8 384 384h-64zM192 512c0 176 144 320 320 320v64C300.8 896 128 723.2 128 512h64z" p-id="2710"></path></svg>
20
+ <%- icon('default:loading') %>
21
21
 
22
22
  <%- layoutDiv() %>
@@ -17,6 +17,6 @@ function layoutDiv() {
17
17
  }
18
18
  %>
19
19
 
20
- <svg class="loading" style="vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2709"><path d="M832 512c0-176-144-320-320-320V128c211.2 0 384 172.8 384 384h-64zM192 512c0 176 144 320 320 320v64C300.8 896 128 723.2 128 512h64z" p-id="2710"></path></svg>
20
+ <%- icon('default:loading') %>
21
21
 
22
22
  <%- layoutDiv() %>
@@ -12,8 +12,8 @@ if (theme.comments.service && theme.comments.service.length > 0) {
12
12
  }
13
13
  }
14
14
  // 合并项目评论
15
- let proj = theme.wiki.tree[page.wiki];
16
- if (loadComment && page.layout == 'wiki' && page.wiki && (proj != null)) {
15
+ const proj = theme.wiki.tree[page.wiki]
16
+ if (loadComment && (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;
@@ -31,7 +31,7 @@ if (cmt.service && page[cmt.service]) {
31
31
  page.cmt = cmt;
32
32
  %>
33
33
  <% if (loadComment) { %>
34
- <div class='related-wrap md-text reveal' id="comments">
34
+ <div class="related-wrap md-text<%- scrollreveal(' ') %>" id="comments">
35
35
  <section class='header cmt-title cap theme'>
36
36
  <%- page.comment_title != undefined ? markdown(page.comment_title) : __('meta.comment_title') %>
37
37
  </section>
@@ -11,7 +11,7 @@ function layoutDiv() {
11
11
  el += ' ' + key + '="' + cfg[key] + '"';
12
12
  }
13
13
  }
14
- el += '><svg class="loading" style="vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2709"><path d="M832 512c0-176-144-320-320-320V128c211.2 0 384 172.8 384 384h-64zM192 512c0 176 144 320 320 320v64C300.8 896 128 723.2 128 512h64z" p-id="2710"></path></svg></div>';
14
+ el += `>${icon('default:loading')}</div>`
15
15
  return el;
16
16
  }
17
17
  %>
@@ -17,6 +17,6 @@ function layoutDiv() {
17
17
  }
18
18
  %>
19
19
 
20
- <svg class="loading" style="vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2709"><path d="M832 512c0-176-144-320-320-320V128c211.2 0 384 172.8 384 384h-64zM192 512c0 176 144 320 320 320v64C300.8 896 128 723.2 128 512h64z" p-id="2710"></path></svg>
20
+ <%- icon('default:loading') %>
21
21
 
22
22
  <%- layoutDiv() %>
@@ -11,7 +11,7 @@ function layoutDiv() {
11
11
  el += ' ' + key + '="' + cfg[key] + '"';
12
12
  }
13
13
  }
14
- el += '><svg class="loading" style="vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2709"><path d="M832 512c0-176-144-320-320-320V128c211.2 0 384 172.8 384 384h-64zM192 512c0 176 144 320 320 320v64C300.8 896 128 723.2 128 512h64z" p-id="2710"></path></svg></div>';
14
+ el += `>${icon('default:loading')}</div>`
15
15
  return el;
16
16
  }
17
17
  %>
@@ -1,14 +1,24 @@
1
1
  <%
2
+
3
+ const wiki = theme.wiki.tree[page.wiki]
4
+ const topic = theme.topic.tree[page.topic]
5
+
2
6
  if (page.sidebar == null) {
3
7
  const { site_tree } = theme
4
8
  var sidebar
5
9
  if (is_home()) {
6
10
  sidebar = site_tree.home.sidebar
7
11
  } else if (is_category() || is_tag() || is_archive() || ['categories', 'tags', 'archives'].includes(page.layout)) {
8
- sidebar = site_tree.blog.sidebar
9
- } else if (page.layout === 'index_topic' || page.layout === 'topic') {
10
- sidebar = site_tree.topic.sidebar
11
- } else if (page.layout === 'index_wiki' || page.layout === 'wiki') {
12
+ sidebar = site_tree.index_blog.sidebar
13
+ } else if (page.layout === 'index_topic') {
14
+ // 专栏列表页等同于博客列表页
15
+ sidebar = site_tree.index_blog.sidebar
16
+ } else if (page.topic?.length > 0) {
17
+ // 专栏文章内页等同于普通文章内页
18
+ sidebar = site_tree.post.sidebar
19
+ } else if (page.layout === 'index_wiki') {
20
+ sidebar = site_tree.index_wiki.sidebar
21
+ } else if (page.wiki?.length > 0) {
12
22
  sidebar = site_tree.wiki.sidebar
13
23
  } else if (page.layout === '404') {
14
24
  sidebar = site_tree.error_page.sidebar
@@ -22,16 +32,17 @@ if (page.sidebar == null) {
22
32
  sidebar = []
23
33
  }
24
34
 
25
- if (page.layout === 'topic' && page.topic && theme.topic?.tree[page.topic]?.sidebar) {
26
- sidebar = theme.topic.tree[page.topic].sidebar
35
+ if (topic?.sidebar) {
36
+ sidebar = topic.sidebar
27
37
  }
28
- if (page.layout == 'wiki' && page.wiki && theme.wiki?.tree[page.wiki]?.sidebar) {
29
- sidebar = theme.wiki.tree[page.wiki].sidebar
38
+ if (wiki?.sidebar) {
39
+ sidebar = wiki.sidebar
30
40
  }
31
-
41
+
32
42
  page.sidebar = sidebar
33
43
  }
34
44
 
45
+
35
46
  // parse array string
36
47
  if (typeof page.sidebar == 'string') {
37
48
  page.sidebar = page.sidebar.replace(/ /g, '').split(',');
@@ -54,36 +65,7 @@ function layoutTitle(main, url, sub) {
54
65
  }
55
66
  function layoutWidgets() {
56
67
  var el = '';
57
- var proj;
58
- if (page.layout === 'wiki' && page.wiki) {
59
- proj = theme.wiki.tree[page.wiki];
60
- }
61
68
  el += '<div class="widgets">';
62
- if (page.layout == 'wiki' && proj && page.menu_id == 'wiki') {
63
- el += '<widget class="widget-wrapper logo-wrap wiki"><div class="widget-body">';
64
- // all products
65
- el += '<a style="filter: grayscale(100%)" class="wiki-home cap" href="' + url_for(theme.site_tree.wiki.base_dir) + '">';
66
- el += '<svg aria-hidden="true" viewBox="0 0 16 16" width="1.2em" height="1.2em" fill="currentColor"><path fill-rule="evenodd" d="M7.78 12.53a.75.75 0 01-1.06 0L2.47 8.28a.75.75 0 010-1.06l4.25-4.25a.75.75 0 011.06 1.06L4.81 7h7.44a.75.75 0 010 1.5H4.81l2.97 2.97a.75.75 0 010 1.06z"></path></svg>';
67
- el += __('btn.all_wiki');
68
- el += '</a>';
69
- // this product
70
- if (proj == undefined) {
71
- // 如果没有项目名,则使用menu中显示的名字
72
- if (page.menu_id && theme.menu[page.menu_id] && md_link(theme.menu[page.menu_id])) {
73
- proj = {
74
- path: md_link(theme.menu[page.menu_id]),
75
- wiki: __(md_text(theme.menu[page.menu_id]))
76
- };
77
- }
78
- }
79
- if (proj != undefined) {
80
- let main = proj.name || proj.title || page.wiki || page.title;
81
- let url = proj.homepage.path;
82
- let sub = proj.subtitle;
83
- el += layoutTitle(main, url, sub);
84
- }
85
- el += '</div></widget>';
86
- }
87
69
  if (page.sidebar) {
88
70
  page.sidebar.forEach((w, i) => {
89
71
  let name = ''
@@ -93,8 +75,8 @@ function layoutWidgets() {
93
75
  } else if (typeof w == 'object' && w.override) {
94
76
  name = w.override
95
77
  }
96
- if (name in theme.data.widgets) {
97
- Object.assign(widget, theme.data.widgets[name])
78
+ if (name in theme.widgets) {
79
+ Object.assign(widget, theme.widgets[name])
98
80
  }
99
81
  if (typeof w == 'object' && (w.override || w.layout)) {
100
82
  Object.assign(widget, w)
@@ -108,43 +90,62 @@ function layoutWidgets() {
108
90
  return el;
109
91
  }
110
92
  function layoutFooterDiv() {
111
- if (page.layout !== 'wiki' && theme.footer.social) {
112
- var el = '<footer class="footer dis-select">';
113
- el += '<div class="social-wrap">';
114
- for (let id of Object.keys(theme.footer.social)) {
115
- let item = theme.footer.social[id];
116
- if (item.icon && (item.url || item.onclick)) {
117
- el += '<a class="social"';
118
- if (item.title) {
119
- el += ' title="' + item.title + '"';
120
- }
121
- if (item.url) {
122
- el += ' href="' + url_for(item.url) + '"';
123
- if (item.url.includes('://')) {
124
- el += ' target="_blank" rel="external nofollow noopener noreferrer"';
125
- } else {
126
- el += ' rel="noopener noreferrer"';
127
- }
128
- } else if (item.onclick) {
129
- item.onclick = item.onclick.replace(/"|\'/g, '&quot;');
130
- el += ' onclick="' + item.onclick + '"';
93
+ const { social } = theme.footer
94
+ if (social == null) {
95
+ return ''
96
+ }
97
+ var el = '<footer class="footer dis-select">';
98
+ el += '<div class="social-wrap">';
99
+ for (let id of Object.keys(social)) {
100
+ let item = social[id];
101
+ if (item.icon && (item.url || item.onclick)) {
102
+ el += '<a class="social"';
103
+ if (item.title) {
104
+ el += ' title="' + item.title + '"';
105
+ }
106
+ if (item.url) {
107
+ el += ' href="' + url_for(item.url) + '"';
108
+ if (item.url.includes('://')) {
109
+ el += ' target="_blank" rel="external nofollow noopener noreferrer"';
110
+ } else {
111
+ el += ' rel="noopener noreferrer"';
131
112
  }
132
- el += '>';
133
- el += item.icon;
134
- el += '</a>';
113
+ } else if (item.onclick) {
114
+ item.onclick = item.onclick.replace(/"|\'/g, '&quot;');
115
+ el += ' onclick="' + item.onclick + '"';
135
116
  }
117
+ el += '>';
118
+ el += item.icon;
119
+ el += '</a>';
136
120
  }
137
- el += '</div>';
138
- el += '</footer>';
139
- return el;
140
- } else {
141
- return '';
142
121
  }
122
+ el += '</div>';
123
+ el += '</footer>';
124
+ return el;
125
+ }
126
+
127
+ function layoutLogo() {
128
+ return partial('logo', {where: 'sidebar'})
143
129
  }
144
130
 
131
+ function layoutNavArea() {
132
+ var search = {}
133
+ if (page.search) {
134
+ search = page.search
135
+ } else if (wiki?.search) {
136
+ search = wiki.search
137
+ } else if (topic?.search) {
138
+ search = topic.search
139
+ }
140
+ var el = ''
141
+ el += `<div class="nav-area">`
142
+ el += partial('search', {item: search})
143
+ el += partial('menu', {where: 'sidebar'})
144
+ el += `</div>`
145
+ return el
146
+ }
145
147
  %>
146
- <% if (page.header == undefined || page.header == 'left' || page.header == 'auto') { %>
147
- <%- partial('header', {where: 'sidebar'}) %>
148
- <% } %>
148
+ <%- layoutLogo() %>
149
+ <%- layoutNavArea() %>
149
150
  <%- layoutWidgets() %>
150
151
  <%- layoutFooterDiv() %>
@@ -0,0 +1,87 @@
1
+ <%
2
+ var logo = theme.logo
3
+ if (page.logo) {
4
+ logo = Object.assign({}, logo, page.logo)
5
+ } else if (theme.wiki.tree[page.wiki]) {
6
+ const proj = theme.wiki.tree[page.wiki]
7
+ var l = proj.logo
8
+ if (l) {
9
+ logo = l
10
+ } else if (proj.name || proj.icon) {
11
+ logo = {
12
+ icon: proj.icon || theme.default.project,
13
+ title: `[${proj.name || proj.title}](${url_for(proj.homepage?.path || '')})`,
14
+ subtitle: proj.subtitle
15
+ }
16
+ }
17
+ } else if (theme.topic.tree[page.topic]) {
18
+ const topic = theme.topic.tree[page.topic]
19
+ var l = topic.logo
20
+ if (l) {
21
+ logo = l
22
+ } else if (topic.name || topic.icon) {
23
+ logo = {
24
+ icon: topic.icon || theme.default.topic,
25
+ title: `[${topic.name || topic.title}](${url_for(topic.homepage?.path || '')})`,
26
+ subtitle: topic.subtitle
27
+ }
28
+ }
29
+ }
30
+
31
+ // logo.icon, logo.title, logo.subtitle, logo.url
32
+ function layoutTitle(main, url, sub) {
33
+ var el = ''
34
+ el += `<a class="title" href="${url_for(url || "/")}">`
35
+ el += `<div class="main" ff="title">${main}</div>`
36
+ if (sub) {
37
+ const arr = sub.split('|')
38
+ if (arr.length > 1) {
39
+ el += `<div class="sub normal cap">${arr.shift().trim()}</div>`
40
+ el += `<div class="sub hover cap" style="opacity:0">${arr.join('|')}</div>`
41
+ } else {
42
+ el += `<div class="sub cap">${sub}</div>`
43
+ }
44
+ }
45
+ el += `</a>`
46
+ return el
47
+ }
48
+
49
+ function layoutDiv() {
50
+ if (where == 'main') {
51
+ if (page.header == false) {
52
+ return ''
53
+ }
54
+ // 内容页如果未设置 header 则不显示
55
+ if (page.header == null) {
56
+ if (!page.nav_tabs) { // 如果有 nav_tabs 就代表是列表页
57
+ if (page.layout === 'post' || page.layout === 'page' || page.wiki) {
58
+ return ''
59
+ }
60
+ }
61
+ }
62
+ }
63
+ var el = ''
64
+ el += `<header class="header${where == 'main' ? ' mobile-only' : ''}">`
65
+ el += `<div class="logo-wrap">`
66
+ if (logo.icon) {
67
+ el += `<div class="icon"><img no-lazy class="icon" src="${md_text(logo.icon)}"></div>`
68
+ } else if (md_text(logo.avatar)) {
69
+ el += `<a class="avatar" href="${url_for(md_link(logo.avatar) || '/')}">`
70
+ if (theme.style.animated_avatar.animate) {
71
+ el += `<div class="bg" style="opacity:0;background-image:url(${theme.style.animated_avatar.background});"></div>`
72
+ }
73
+ el += `<img no-lazy class="avatar" src="${md_text(logo.avatar)}">`
74
+ el += `</a>`
75
+ }
76
+ const main = md_text(logo.title)
77
+ if (main) {
78
+ let url = md_link(logo.title)
79
+ el += layoutTitle(main, url, logo.subtitle)
80
+ }
81
+ el += `</div>`
82
+ el += '</header>'
83
+ return el
84
+ }
85
+ %>
86
+
87
+ <%- layoutDiv() %>
@@ -1,26 +1,31 @@
1
1
  <%
2
2
  function layoutDiv() {
3
- var el = '';
4
- el += '<nav class="menu dis-select';
5
- if (where == 'main') {
6
- el += ' mobile-hidden';
7
- }
8
- el += '">';
9
- for (let id of Object.keys(theme.menu)) {
10
- let item = theme.menu[id];
11
- if (item == undefined || item.length == 0) {
12
- continue;
3
+ var el = ''
4
+ el += `<nav class="menu dis-select${where == 'main' ? ' mobile-hidden' : ''}">`
5
+ for (let item of theme.menubar.items) {
6
+ if (item == undefined || item.id == null || item.url == null) {
7
+ continue
8
+ }
9
+ el += `<a class="nav-item${item.id == page.menu_id ? ' active' : ''}" title="${item.title}" href="${url_for(item.url)}"`
10
+ if (item.theme?.length > 0) {
11
+ el += ` style="color:${item.theme}"`
13
12
  }
14
- el += '<a class="nav-item';
15
- if (id == page.menu_id) {
16
- el += ' active';
13
+ el += `>`
14
+ if (item.icon?.length > 0) {
15
+ if (item.icon.startsWith('<')) {
16
+ el += item.icon
17
+ } else if (theme.icons[item.icon]) {
18
+ el += theme.icons[item.icon]
19
+ } else {
20
+ el += `<img no-lazy src="${item.icon}">`
21
+ }
22
+ } else {
23
+ el += `<span>${__(item.title)}</span>`
17
24
  }
18
- el += '" href="' + url_for(md_link(item)) + '">';
19
- el += __(md_text(item));
20
- el += '</a>';
25
+ el += `</a>`
21
26
  }
22
- el += '</nav>';
23
- return el;
27
+ el += `</nav>`
28
+ return el
24
29
  }
25
30
  %>
26
31
 
@@ -0,0 +1,42 @@
1
+ <%
2
+ if (item.filter == null) {
3
+ item.filter = 'auto'
4
+ }
5
+ function layoutDiv() {
6
+ var el = ''
7
+ el += `<div class="search-wrapper" id="search-wrapper">`
8
+ el += `<form class="search-form">`
9
+ var filter = ''
10
+ if (item.filter == 'auto') {
11
+ if (page.wiki) {
12
+ let matches = page.path.match(/(.*?)\/(.*?)\//i)
13
+ if (matches?.length > 0) {
14
+ filter = matches[0]
15
+ }
16
+ }
17
+ } else {
18
+ if (item.filter?.length > 0) {
19
+ filter = item.filter
20
+ }
21
+ }
22
+ el += `<a class="search-button" onclick="document.getElementById(&quot;search-input&quot;).focus();">`
23
+ el += icon('default:search')
24
+ el += `</a>`
25
+ el += `<input type="text" class="search-input" id="search-input"`
26
+ if (filter.length > 0) {
27
+ if (!filter.startsWith('/')) {
28
+ filter = '/' + filter
29
+ }
30
+ el += ` data-filter="${filter}"`
31
+ el += ` placeholder="${item.placeholder || __('search.search_in', filter)}">`
32
+ } else {
33
+ el += ` placeholder="${item.placeholder || __('search.search')}">`
34
+ }
35
+ el += `</form>`
36
+ el += `<div id="search-result"></div>`
37
+ el += `<div class="search-no-result">${__('search.no_results')}</div>`
38
+ el += `</div>`
39
+ return el
40
+ }
41
+ %>
42
+ <%- layoutDiv() %>