hexo-theme-stellar 1.15.0 → 1.16.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 (41) hide show
  1. package/_config.yml +8 -8
  2. package/layout/_partial/head.ejs +7 -4
  3. package/layout/_partial/main/navbar/list_wiki.ejs +1 -3
  4. package/layout/_partial/plugins/comments/beaudar/layout.ejs +10 -29
  5. package/layout/_partial/plugins/comments/giscus/layout.ejs +10 -27
  6. package/layout/_partial/plugins/comments/layout.ejs +17 -2
  7. package/layout/_partial/plugins/comments/script.ejs +2 -2
  8. package/layout/_partial/plugins/comments/utterances/layout.ejs +10 -29
  9. package/layout/_partial/sidebar/header.ejs +43 -8
  10. package/layout/_partial/sidebar/index.ejs +50 -0
  11. package/layout/_partial/sidebar/widgets/recent.ejs +8 -7
  12. package/layout/_partial/sidebar/widgets/toc.ejs +5 -1
  13. package/layout/archive.ejs +1 -1
  14. package/layout/categories.ejs +1 -1
  15. package/layout/index.ejs +1 -3
  16. package/layout/tags.ejs +1 -1
  17. package/layout/wiki.ejs +2 -2
  18. package/package.json +1 -1
  19. package/scripts/events/lib/doc_tree.js +91 -90
  20. package/scripts/helpers/related_posts.js +1 -3
  21. package/scripts/helpers/utils.js +20 -0
  22. package/scripts/tags/folders.js +4 -6
  23. package/scripts/tags/lib/tabs.js +5 -9
  24. package/scripts/tags/split.js +6 -8
  25. package/scripts/tags/timeline.js +3 -5
  26. package/source/css/_common/blockquote.styl +10 -0
  27. package/source/css/_common/device.styl +11 -10
  28. package/source/css/_layout/list.styl +2 -1
  29. package/source/css/_layout/main.styl +4 -2
  30. package/source/css/_layout/md.styl +6 -13
  31. package/source/css/_layout/partial/bread-nav.styl +1 -1
  32. package/source/css/_layout/partial/navbar.styl +8 -1
  33. package/source/css/_layout/partial/related.styl +1 -2
  34. package/source/css/_layout/sidebar/sidebar.styl +4 -4
  35. package/source/css/_layout/sidebar/toc_wiki.styl +1 -1
  36. package/source/css/_layout/sidebar/widgets.styl +6 -3
  37. package/source/css/_layout/tag-plugins/common.styl +7 -7
  38. package/source/css/_layout/tag-plugins/link.styl +7 -7
  39. package/source/css/_layout/tag-plugins/split.styl +7 -1
  40. package/source/css/_layout/tag-plugins/timeline.styl +2 -4
  41. package/layout/_partial/sidebar/logo.ejs +0 -69
package/_config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  ######## Stellar info ########
2
2
  stellar:
3
- version: '1.15.0'
3
+ version: '1.16.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
@@ -25,10 +25,10 @@ sidebar:
25
25
  # about: '[关于](/about/)'
26
26
  # Sidebar widgets
27
27
  widgets:
28
- index: [welcome, recent, timeline] # for home/wiki/categories/tags/archives/404 pages
29
- page: [welcome, toc] # for pages using 'layout:page'
30
- post: [toc, ghrepo, ghissues] # for pages using 'layout:post'
31
- wiki: [toc, ghrepo, ghissues, related] # for pages using 'layout:wiki'
28
+ index: welcome, recent, timeline # for home/wiki/categories/tags/archives/404 pages
29
+ page: welcome, toc # for pages using 'layout:page'
30
+ post: toc, ghrepo, ghissues # for pages using 'layout:post'
31
+ wiki: ghrepo, toc, ghissues, related # for pages using 'layout:wiki'
32
32
 
33
33
  ######## Index ########
34
34
  post-index: # 近期发布 分类 标签 归档 and ...
@@ -283,7 +283,7 @@ plugins:
283
283
  # 赫蹏 (Heti) - 专为中文网页内容设计的排版样式增强
284
284
  # https://github.com/sivan/heti
285
285
  heti:
286
- enable: false
286
+ enable: false # 此插件会和代码块冲突,仅适用于纯中文博主。
287
287
  css: https://unpkg.com/heti/umd/heti.min.css
288
288
  js: https://unpkg.com/heti/umd/heti-addon.min.js
289
289
 
@@ -321,8 +321,8 @@ style:
321
321
  button: '#1BCDFC' # 按钮颜色
322
322
  hover: '#ff5722' # 按钮高亮颜色
323
323
  light:
324
- background: '#f8f8f8' # 浅色背景颜色
325
- block: '#f2f2f2' # 块背景颜色
324
+ background: '#F8F9FA' # 浅色背景颜色
325
+ block: '#F0F1F2' # 块背景颜色
326
326
  card: white # 卡片背景颜色
327
327
  title: '#000' # 标题文本颜色
328
328
  text: '#333' # 正文文本颜色
@@ -12,17 +12,20 @@ function generate_title() {
12
12
  return wiki + ' - ' + config.title;
13
13
  }
14
14
  } else {
15
- if (page.category) {
15
+ if (page.title) {
16
+ return page.title + ' - ' + config.title;
17
+ } else if (page.category) {
16
18
  return __('btn.category') + __('symbol.colon') + page.category + ' - ' + config.title;
17
19
  } else if (page.tag) {
18
20
  return __('btn.tag') + __('symbol.colon') + page.tag + ' - ' + config.title;
19
- } else {
20
- return config.title;
21
21
  }
22
22
  }
23
- return '';
23
+ return config.title;
24
24
  }
25
25
  function generate_description() {
26
+ if (theme.open_graph && theme.open_graph.enable) {
27
+ return '';
28
+ }
26
29
  if (page.layout == 'wiki' && page.wiki) {
27
30
  let proj = theme.wiki.projects[page.wiki];
28
31
  if (proj && proj.description) {
@@ -13,9 +13,7 @@ function layoutDiv() {
13
13
  // 项目分类
14
14
  for (let id of Object.keys(theme.wiki.all_tags)) {
15
15
  let tag = theme.wiki.all_tags[id];
16
- let projects = tag.items.filter(function(item){
17
- return item.index !== false;
18
- })
16
+ let projects = tag.items.filter(item => item.index !== false)
19
17
  if (projects && projects.length > 0) {
20
18
  el += '<a';
21
19
  if (tag.name && tag.name.length > 0 && page.tagName === tag.name) {
@@ -1,37 +1,18 @@
1
1
  <%
2
2
  function layoutDiv() {
3
- const cmt = 'beaudar';
4
- // 合并配置参数
5
- var config = Object.assign({}, theme.comments[cmt]);
6
- if (page.layout === 'wiki' && page.wiki) {
7
- let proj = theme.wiki.projects[page.wiki];
8
- if (proj[cmt] != undefined) {
9
- Object.assign(config, proj[cmt]);
10
- }
11
- }
12
- Object.assign(config, page[cmt]);
13
- // 合并评论数据
14
- if (config['issue-number'] !== null) {
15
- config['issue-term'] = null;
16
- } else {
17
- if (page.comment_id != undefined) {
18
- config['issue-term'] = page.comment_id;
19
- } else if (page.layout === 'wiki' && page.wiki) {
20
- let proj = theme.wiki.projects[page.wiki];
21
- if (proj.comment_id != undefined) {
22
- config['issue-term'] = proj.comment_id;
23
- }
24
- }
25
- }
26
- // 布局
27
3
  var el = '';
28
- el += '<div id="' + cmt + '"';
29
- for (let key of Object.keys(config)) {
30
- if (config[key] !== null) {
31
- el += ' ' + key + '="' + config[key] + '"';
4
+ const cmt = page.cmt;
5
+ if (cmt && cmt.service && (cmt.service.length > 0)) {
6
+ const name = cmt.service;
7
+ const body = cmt[name];
8
+ el += '<div id="' + name + '"';
9
+ for (let key of Object.keys(body)) {
10
+ if (body[key] !== null) {
11
+ el += ' ' + key + '="' + body[key] + '"';
12
+ }
32
13
  }
14
+ el += '></div>';
33
15
  }
34
- el += '></div>';
35
16
  return el;
36
17
  }
37
18
  %>
@@ -1,35 +1,18 @@
1
1
  <%
2
2
  function layoutDiv() {
3
- const cmt = 'giscus';
4
- // 合并配置参数
5
- var config = Object.assign({}, theme.comments[cmt]);
6
- if (page.layout === 'wiki' && page.wiki) {
7
- let proj = theme.wiki.projects[page.wiki];
8
- if (proj[cmt] != undefined) {
9
- Object.assign(config, proj[cmt]);
10
- }
11
- }
12
- Object.assign(config, page[cmt]);
13
- // 合并评论数据
14
- if (page.comment_id != undefined) {
15
- config['data-mapping'] = 'specific';
16
- config['data-term'] = page.comment_id;
17
- } else if (page.layout === 'wiki' && page.wiki) {
18
- let proj = theme.wiki.projects[page.wiki];
19
- if (proj.comment_id != undefined) {
20
- config['data-mapping'] = 'specific';
21
- config['data-term'] = proj.comment_id;
22
- }
23
- }
24
- // 布局
25
3
  var el = '';
26
- el += '<div id="' + cmt + '"';
27
- for (let key of Object.keys(config)) {
28
- if (config[key] !== null) {
29
- el += ' ' + key + '="' + config[key] + '"';
4
+ const cmt = page.cmt;
5
+ if (cmt && cmt.service && (cmt.service.length > 0)) {
6
+ const name = cmt.service;
7
+ const body = cmt[name];
8
+ el += '<div id="' + name + '"';
9
+ for (let key of Object.keys(body)) {
10
+ if (body[key] !== null) {
11
+ el += ' ' + key + '="' + body[key] + '"';
12
+ }
30
13
  }
14
+ el += '></div>';
31
15
  }
32
- el += '></div>';
33
16
  return el;
34
17
  }
35
18
  %>
@@ -1,4 +1,10 @@
1
1
  <%
2
+ var cmt = {
3
+ service: theme.comments.service
4
+ };
5
+ if (cmt.service) {
6
+ cmt[cmt.service] = Object.assign({}, theme.comments[cmt.service]);
7
+ }
2
8
  var loadComment = false;
3
9
  if (theme.comments.service && theme.comments.service.length > 0) {
4
10
  if (page.comments == undefined || page.comments != false) {
@@ -13,15 +19,24 @@ if (loadComment && page.layout == 'wiki' && page.wiki) {
13
19
  page.comment_title = proj.comment_title;
14
20
  }
15
21
  }
22
+ if (proj.comments && proj.comments.service) {
23
+ cmt = proj.comments;
24
+ let s = proj.comments.service;
25
+ cmt[s] = Object.assign({}, theme.comments[s], proj.comments[s]);
26
+ }
27
+ }
28
+ if (cmt.service && page[cmt.service]) {
29
+ Object.assign(cmt[cmt.service], page[cmt.service]);
16
30
  }
31
+ page.cmt = cmt;
17
32
  %>
18
33
  <% if (loadComment) { %>
19
34
  <div class='related-wrap md reveal' id="comments">
20
35
  <div class='cmt-title cap theme'>
21
36
  <%- page.comment_title != undefined ? markdown(page.comment_title) : __('meta.comment_title') %>
22
37
  </div>
23
- <div class='cmt-body <%- theme.comments.service %>'>
24
- <%- partial(theme.comments.service + '/layout') %>
38
+ <div class='cmt-body <%- cmt.service %>'>
39
+ <%- partial(cmt.service + '/layout') %>
25
40
  </div>
26
41
  </div>
27
42
  <% } %>
@@ -1,3 +1,3 @@
1
- <% if (theme.comments.service && theme.comments.service.length > 0) { %>
2
- <%- partial(theme.comments.service + '/script') %>
1
+ <% if (page.cmt && page.cmt.service && page.cmt.service.length > 0) { %>
2
+ <%- partial(page.cmt.service + '/script') %>
3
3
  <% } %>
@@ -1,37 +1,18 @@
1
1
  <%
2
2
  function layoutDiv() {
3
- const cmt = 'utterances';
4
- // 合并配置参数
5
- var config = Object.assign({}, theme.comments[cmt]);
6
- if (page.layout === 'wiki' && page.wiki) {
7
- let proj = theme.wiki.projects[page.wiki];
8
- if (proj[cmt] != undefined) {
9
- Object.assign(config, proj[cmt]);
10
- }
11
- }
12
- Object.assign(config, page[cmt]);
13
- // 合并评论数据
14
- if (config['issue-number'] !== null) {
15
- config['issue-term'] = null;
16
- } else {
17
- if (page.comment_id != undefined) {
18
- config['issue-term'] = page.comment_id;
19
- } else if (page.layout === 'wiki' && page.wiki) {
20
- let proj = theme.wiki.projects[page.wiki];
21
- if (proj.comment_id != undefined) {
22
- config['issue-term'] = proj.comment_id;
23
- }
24
- }
25
- }
26
- // 布局
27
3
  var el = '';
28
- el += '<div id="' + cmt + '"';
29
- for (let key of Object.keys(config)) {
30
- if (config[key] !== null) {
31
- el += ' ' + key + '="' + config[key] + '"';
4
+ const cmt = page.cmt;
5
+ if (cmt && cmt.service && (cmt.service.length > 0)) {
6
+ const name = cmt.service;
7
+ const body = cmt[name];
8
+ el += '<div id="' + name + '"';
9
+ for (let key of Object.keys(body)) {
10
+ if (body[key] !== null) {
11
+ el += ' ' + key + '="' + body[key] + '"';
12
+ }
32
13
  }
14
+ el += '></div>';
33
15
  }
34
- el += '></div>';
35
16
  return el;
36
17
  }
37
18
  %>
@@ -1,20 +1,55 @@
1
1
  <%
2
+ var proj;
3
+ if (page.layout === 'wiki' && page.wiki) {
4
+ proj = theme.wiki.projects[page.wiki];
5
+ }
6
+ function layoutTitle(main, url, sub) {
7
+ var el = '';
8
+ el += '<a class="title" href="' + url_for(url || "/") + '">';
9
+ el += '<div class="main" ff="title">' + main + '</div>';
10
+ if (sub) {
11
+ let arr = sub.split('|');
12
+ if (arr.length > 1) {
13
+ el += '<div class="sub normal cap">' + arr[0].trim() + '</div>';
14
+ el += '<div class="sub hover cap" style="opacity:0">' + arr[1].trim() + '</div>';
15
+ } else if (arr.length > 0) {
16
+ el += '<div class="sub cap">' + arr[0] + '</div>';
17
+ }
18
+ }
19
+ el += '</a>';
20
+ return el;
21
+ }
22
+
2
23
  function layoutDiv() {
3
24
  var el = '';
25
+ if (page.layout == 'wiki' && page.menu_id == 'wiki') {
26
+ return el;
27
+ }
4
28
  el += '<header class="header';
5
29
  if (where == 'main') {
6
30
  el += ' mobile-only';
7
31
  }
8
32
  el += '">';
9
- el += partial('logo');
10
- if (where != 'main') {
11
- if (page.layout === 'wiki' && page.wiki) {
12
- if (page.menu_id !== 'wiki') {
13
- el += partial('menu', {where: where});
14
- }
15
- } else {
16
- el += partial('menu', {where: where});
33
+
34
+ el += '<div class="logo-wrap">';
35
+ if (md_text(theme.sidebar.logo.avatar)) {
36
+ el += '<a class="avatar" href="' + url_for(md_link(theme.sidebar.logo.avatar) || "/") + '">';
37
+ if (theme.style.animated_avatar.animate) {
38
+ el += '<div class="bg" style="opacity:0;background-image:url(' + theme.style.animated_avatar.background + ');"></div>';
17
39
  }
40
+ el += '<img no-lazy class="avatar" src="' + md_text(theme.sidebar.logo.avatar) + '">';
41
+ el += '</a>';
42
+ }
43
+ let main = md_text(theme.sidebar.logo.title);
44
+ if (main) {
45
+ let url = md_link(theme.sidebar.logo.title);
46
+ let sub = config.subtitle;
47
+ el += layoutTitle(main, url, sub);
48
+ }
49
+ el += '</div>';
50
+
51
+ if (where != 'main') {
52
+ el += partial('menu', {where: where});
18
53
  }
19
54
  el += '</header>';
20
55
  return el;
@@ -1,4 +1,8 @@
1
1
  <%
2
+ var proj;
3
+ if (page.layout === 'wiki' && page.wiki) {
4
+ proj = theme.wiki.projects[page.wiki];
5
+ }
2
6
  // 默认组件
3
7
  if (page.sidebar == undefined) {
4
8
  if (page.layout == 'post' && page.content) {
@@ -18,9 +22,55 @@ if (page.sidebar == undefined) {
18
22
  page.sidebar = [];
19
23
  }
20
24
  }
25
+
26
+ // parse array string
27
+ if (typeof page.sidebar == 'string') {
28
+ page.sidebar = page.sidebar.replace(/ /g, '').split(',');
29
+ }
30
+ function layoutTitle(main, url, sub) {
31
+ var el = '';
32
+ el += '<a class="title" href="' + url_for(url || "/") + '">';
33
+ el += '<div class="main" ff="title">' + main + '</div>';
34
+ if (sub) {
35
+ let arr = sub.split('|');
36
+ if (arr.length > 1) {
37
+ el += '<div class="sub normal cap">' + arr[0].trim() + '</div>';
38
+ el += '<div class="sub hover cap" style="opacity:0">' + arr[1].trim() + '</div>';
39
+ } else if (arr.length > 0) {
40
+ el += '<div class="sub cap">' + arr[0] + '</div>';
41
+ }
42
+ }
43
+ el += '</a>';
44
+ return el;
45
+ }
21
46
  function layoutWidgets() {
22
47
  var el = '';
23
48
  el += '<div class="widgets">';
49
+ if (page.layout == 'wiki' && proj && page.menu_id == 'wiki') {
50
+ el += '<div class="widget-wrap logo-wrap wiki"><div class="widget-body">';
51
+ // all products
52
+ el += '<a style="filter: grayscale(100%)" class="wiki-home cap" href="' + url_for(config.wiki_dir) + '">';
53
+ el += '<svg aria-hidden="true" viewBox="0 0 16 16" width="1rem" height="1rem" 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>';
54
+ el += __('btn.all_wiki');
55
+ el += '</a>';
56
+ // this product
57
+ if (proj == undefined) {
58
+ // 如果没有项目名,则使用menu中显示的名字
59
+ if (page.menu_id && theme.sidebar.menu[page.menu_id] && md_link(theme.sidebar.menu[page.menu_id])) {
60
+ proj = {
61
+ path: md_link(theme.sidebar.menu[page.menu_id]),
62
+ wiki: __(md_text(theme.sidebar.menu[page.menu_id]))
63
+ };
64
+ }
65
+ }
66
+ if (proj != undefined) {
67
+ let main = proj.name || proj.title || page.wiki || page.title;
68
+ let url = proj.homepage.path;
69
+ let sub = proj.subtitle;
70
+ el += layoutTitle(main, url, sub);
71
+ }
72
+ el += '</div></div>';
73
+ }
24
74
  if (page.sidebar) {
25
75
  page.sidebar.forEach((w, i) => {
26
76
  if (w in theme.data.widgets) {
@@ -13,20 +13,21 @@ function layoutDiv() {
13
13
  // body
14
14
  var arr = [];
15
15
  if (page.menu_id == 'wiki') {
16
- arr = theme.wiki.all_pages.filter(function(p){
16
+ arr = theme.wiki.all_pages.filter( p => {
17
17
  if (p.wiki) {
18
18
  let proj = theme.wiki.projects[p.wiki];
19
19
  return proj.index != false;
20
20
  }
21
- return false;
22
- });
21
+ return false
22
+ })
23
+ arr = arr.sort((p1, p2) => p1.updated > p2.updated ? -1 : 1)
23
24
  } else {
24
- arr = site.posts.filter(function(p){
25
- return p.title && p.title.length > 0;
26
- });
25
+ arr = site.posts.filter( p => p.title && p.title.length > 0)
26
+ arr = arr.sort("updated", -1)
27
27
  }
28
28
  el += '<div class="widget-body related-posts fs14">';
29
- arr.sort("updated", -1).limit(item.limit).each(function(post) {
29
+ arr.length = item.limit
30
+ arr.forEach(post => {
30
31
  el += '<a class="item title" href="' + url_for(post.link || post.path) + '">';
31
32
  el += '<span class="title">'
32
33
  if (post.layout == 'wiki') {
@@ -29,7 +29,11 @@ function layoutDocTree(pages) {
29
29
  }
30
30
  el += '<div class="doc-tree' + isActive + '">';
31
31
  if (proj.pages.length > 1) {
32
- el += '<a class="doc-tree-link' + isActive + '" href="' + url_for(p.path) + '">';
32
+ let href = url_for(p.path);
33
+ if (p.is_homepage) {
34
+ href += '#start'
35
+ }
36
+ el += '<a class="doc-tree-link' + isActive + '" href="' + href + '">';
33
37
  el += '<span class="toc-text">' + (p.title || p.seo_title) + '</span>';
34
38
  el += '</a>';
35
39
  }
@@ -7,7 +7,7 @@ if (page.menu_id == undefined) {
7
7
  <% if (page.posts && (is_category() || is_tag())) { %>
8
8
  <%- partial('index') %>
9
9
  <% } else { %>
10
- <% page.title = __('btn.archives'); %>
10
+ <% page.title = __('btn.archives') + ' - ' + config.title; %>
11
11
  <%- partial('_partial/main/navbar/list_post') %>
12
12
  <div class='post-list'>
13
13
  <% var years = []; %>
@@ -5,7 +5,7 @@ if (page.menu_id == undefined) {
5
5
  }
6
6
  %>
7
7
  <% if (site.categories.length) { %>
8
- <% page.title = __('btn.categories'); %>
8
+ <% page.title = __('btn.categories') + ' - ' + config.title; %>
9
9
  <% page.layout = 'categories'; %>
10
10
  <%- partial('_partial/main/navbar/list_post') %>
11
11
  <div class='post-list'>
package/layout/index.ejs CHANGED
@@ -28,9 +28,7 @@ function layout_posts(partial) {
28
28
  if (is_home()) {
29
29
  // pinned posts
30
30
  if (page.current == 1) {
31
- var pinned = site.posts.filter(function(post){
32
- return post.pin != undefined;
33
- }).sort((config.index_generator && config.index_generator.order_by) || '-date');
31
+ var pinned = site.posts.filter(post => post.pin != undefined).sort((config.index_generator && config.index_generator.order_by) || '-date');
34
32
  pinned.forEach((post, i) => {
35
33
  el += layout_post_card('post', post, partial(post));
36
34
  });
package/layout/tags.ejs CHANGED
@@ -5,7 +5,7 @@ if (page.menu_id == undefined) {
5
5
  }
6
6
  %>
7
7
  <% if (site.tags.length) { %>
8
- <% page.title = __('btn.tags'); %>
8
+ <% page.title = __('btn.tags') + ' - ' + config.title; %>
9
9
  <% page.layout = 'tags'; %>
10
10
  <%- partial('_partial/main/navbar/list_post') %>
11
11
  <div class='post-list'>
package/layout/wiki.ejs CHANGED
@@ -7,9 +7,9 @@ if (page.layout == undefined) {
7
7
  }
8
8
  if (page.title == undefined) {
9
9
  if (page.tagName) {
10
- page.title = page.tagName;
10
+ page.title = page.tagName + ' - ' + config.title;
11
11
  } else {
12
- page.title = __('btn.wiki');
12
+ page.title = __('btn.wiki') + ' - ' + config.title;
13
13
  }
14
14
  }
15
15
  function layoutTitle() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-stellar",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "description": "Elegant and powerful theme for Hexo.",
5
5
  "main": "package.json",
6
6
  "scripts": {