hexo-theme-shokax 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,11 +24,10 @@ shokaX的社区资源导航和插件仓库为[awesome-shokaX](https://github.com
24
24
  | 自定义字体 | ✅* | 自定义样式 | ✅* |
25
25
  | 多种评论系统支持 | ✅ | 用户行为分析支持 | ✅ |
26
26
  | 底部备案号 | ✅ | 自定义页尾 | ✅* |
27
- | CSS渐变封面 | ✅ | typescript支持 | ✅^ |
27
+ | CSS渐变封面 | ✅ | typescript支持 | |
28
28
 
29
29
  备注:
30
30
  - *: 需要使用注入API实现
31
- - ^: 仅page js部分,hexo script未实现
32
31
 
33
32
 
34
33
  ## 🔧 如何安装?
package/_config.yml CHANGED
@@ -30,6 +30,7 @@ experiments:
30
30
  usingRelative: false # _image.yml 使用相对路径
31
31
  optimizeLongPosts: false # 优化长文章,这能让长文章的FPS提升70%-150%并解决假死问题,但存在一些副作用
32
32
  # 具体见https://docs.kaitaku.xyz/guide/theme.html#%E9%95%BF%E6%96%87%E7%AB%A0%E4%BC%98%E5%8C%96
33
+ mobileWidth: 820px # 移动版和桌面版导航栏最短切换长度
33
34
 
34
35
  # 优化性能区
35
36
  performance:
@@ -371,7 +372,7 @@ vendorsList:
371
372
  js:
372
373
  - pace
373
374
  - pjax
374
- - fetch
375
+ # - fetch # polyfill已暂时禁用
375
376
  - anime
376
377
  - algolia
377
378
  - instantsearch
package/_images.yml CHANGED
@@ -6,95 +6,4 @@
6
6
  - 6833939bly1gicit31ffoj20zk0m8naf.jpg
7
7
  - 6833939bly1gicit4jrvuj20zk0m8785.jpg
8
8
  - 6833939bly1gicitcxhpij20zk0m8hdt.jpg
9
- - 6833939bly1gicitf0kl1j20zk0m87fe.jpg
10
- - 6833939bly1gicitht3xtj20zk0m8k5v.jpg
11
- - 6833939bly1gicitspjpbj20zk0m81ky.jpg
12
- - 6833939bly1gicitzannuj20zk0m8b29.jpg
13
- - 6833939bly1giciub8ja1j20zk0m81ky.jpg
14
- - 6833939bly1giciuja1j1j20zk0m8kjl.jpg
15
- - 6833939bly1giciukx8a7j20zk0m8aio.jpg
16
- - 6833939bly1giciundwu5j20zk0m8n9e.jpg
17
- - 6833939bly1giciusoyjnj219g0u0x56.jpg
18
- - 6833939bly1giciuv0socj20zk0m8qes.jpg
19
- - 6833939bly1gicivghyooj20zk0m8dir.jpg
20
- - 6833939bly1giclfb3vzhj20zk0m8wny.jpg
21
- - 6833939bly1giclfdu6exj20zk0m87hw.jpg
22
- - 6833939bly1giclffsa1cj20zk0m811l.jpg
23
- - 6833939bly1giclflwv2aj20zk0m84qp.jpg
24
- - 6833939bly1giclfw2t96j20zk0m8x6p.jpg
25
- - 6833939bly1giclg5ms2rj20zk0m8u0x.jpg
26
- - 6833939bly1giclga70tsj20zk0m84mr.jpg
27
- - 6833939bly1giclgi503lj20zk0m8hdt.jpg
28
- - 6833939bly1giclgrvbd6j20zk0m8qv5.jpg
29
- - 6833939bly1giclh0m9pdj20zk0m8hdt.jpg
30
- - 6833939bly1giclh3brzpj20zk0m8ann.jpg
31
- - 6833939bly1giclh5u05ej20zk0m87df.jpg
32
- - 6833939bly1giclhfehz7j20zk0m8u0x.jpg
33
- - 6833939bly1giclhnx9glj20zk0m8npd.jpg
34
- - 6833939bly1giclhpw3lwj20zk0m8gvw.jpg
35
- - 6833939bly1giclhtuo6nj20zk0m8ttm.jpg
36
- - 6833939bly1gicli3sbvtj20zk0m8x6p.jpg
37
- - 6833939bly1gicli9lfebj20zk0m84qp.jpg
38
- - 6833939bly1gicliierfjj20zk0m8npd.jpg
39
- - 6833939bly1giclil3m4ej20zk0m8tn8.jpg
40
- - 6833939bly1giclimtf7dj20zk0m8qav.jpg
41
- - 6833939bly1giclip4jbpj20zk0m87cv.jpg
42
- - 6833939bly1gicliwyw55j20zk0m8hdt.jpg
43
- - 6833939bly1giclize41wj20zk0m87gk.jpg
44
- - 6833939bly1giclj61ylzj20zk0m8b29.jpg
45
- - 6833939bly1giclj9410cj20zk0m8h12.jpg
46
- - 6833939bly1gicljgocqbj20zk0m8e81.jpg
47
- - 6833939bly1gicljitigmj20zk0m87fp.jpg
48
- - 6833939bly1giclwrdwyaj20zk0m8are.jpg
49
- - 6833939bly1giclwuom7cj20zk0m8dvn.jpg
50
- - 6833939bly1giclx29mstj20zk0m8hdt.jpg
51
- - 6833939bly1giclx6phq6j20zk0m8e36.jpg
52
- - 6833939bly1giclxfdlttj20zk0m8npd.jpg
53
- - 6833939bly1giclxp31goj20zk0m8qv5.jpg
54
- - 6833939bly1giclxxcb6rj20zk0m8b29.jpg
55
- - 6833939bly1gicm07ih54j20zk0m84qp.jpg
56
- - 6833939bly1gicm0fdw5cj20zk0m8hdt.jpg
57
- - 6833939bly1gicm0n457cj20zk0m8e81.jpg
58
- - 6833939bly1gicmnywqgpj20zk0m8dwx.jpg
59
- - 6833939bly1gipesng5oej20zk0m87d4.jpg
60
- - 6833939bly1gipesrnqv3j20zk0m8ava.jpg
61
- - 6833939bly1gipesx5fdwj20zk0m81kx.jpg
62
- - 6833939bly1gipet4bz0yj20zk0m8e81.jpg
63
- - 6833939bly1gipet8c1a2j20zk0m8kct.jpg
64
- - 6833939bly1gipetfk5zwj20zk0m8e81.jpg
65
- - 6833939bly1gipetlbztpj20zk0m84qp.jpg
66
- - 6833939bly1gipetv6p75j20zk0m8x6p.jpg
67
- - 6833939bly1gipeu1usa7j20zk0m8b29.jpg
68
- - 6833939bly1gipeu7txpzj20zk0m81kx.jpg
69
- - 6833939bly1gipeubcbajj20zk0m8h1h.jpg
70
- - 6833939bly1gipeudstjqj20zk0m8k3r.jpg
71
- - 6833939bly1gipeuibk9fj20zk0m8ay2.jpg
72
- - 6833939bly1gipeun65urj20zk0m81ii.jpg
73
- - 6833939bly1gipeuv80yoj20zk0m8kjl.jpg
74
- - 6833939bly1gipev1x5e4j20zk0m8b29.jpg
75
- - 6833939bly1gipevarprfj20zk0m8npd.jpg
76
- - 6833939bly1gipevgoki5j20zk0m84qp.jpg
77
- - 6833939bly1gipevo9j1jj20zk0m8e81.jpg
78
- - 6833939bly1gipevuctzzj20zk0m84qp.jpg
79
- - 6833939bly1gipew28b65j20zk0m8hdt.jpg
80
- - 6833939bly1gipew8gmvyj20zk0m87wh.jpg
81
- - 6833939bly1gipewf5l51j20zk0m8b29.jpg
82
- - 6833939bly1gipewkhf1zj20zk0m81kx.jpg
83
- - 6833939bly1gipewr8iypj20zk0m8b29.jpg
84
- - 6833939bly1gipex2cdtbj20zk0m8x6p.jpg
85
- - 6833939bly1gipexbei4hj20zk0m8npd.jpg
86
- - 6833939bly1gipexe4oykj20zk0m87ji.jpg
87
- - 6833939bly1gipexj2jgzj20zk0m8b09.jpg
88
- - 6833939bly1gipexoj0moj20zk0m8kgu.jpg
89
- - 6833939bly1gipexw3o58j20zk0m8e81.jpg
90
- - 6833939bly1gipey0a334j20zk0m8qpt.jpg
91
- - 6833939bly1gipey84bjtj20zk0m8hdt.jpg
92
- - 6833939bly1gipeybxm1pj20zk0m8niv.jpg
93
- - 6833939bly1gipeyhsblkj20zk0m81kx.jpg
94
- - 6833939bly1gipeyonbf9j20zk0m8e81.jpg
95
- - 6833939bly1gipeyvx1d4j20zk0m8hdt.jpg
96
- - 6833939bly1giph47e9vtj20zk0m8x6l.jpg
97
- - 6833939bly1giph4baakhj20zk0m8h5q.jpg
98
- - 6833939bly1giph4fomxoj20zk0m8axp.jpg
99
- - 6833939bly1giph4lm9i7j20zk0m84qp.jpg
100
- - 6833939bly1giph4wqtg4j20zk0m8x6p.jpg
9
+
@@ -2,12 +2,17 @@ mixin sidebarRender(display_toc)
2
2
  - var related = _category_posts(page)
3
3
  if page && page.prev
4
4
  - var prevlink = page?.prev_link
5
+ if !prevlink && is_home()
6
+ if page.prev === 1
7
+ - prevlink = '/'
8
+ else
9
+ - prevlink = `/page/${page.prev}/`
5
10
  if is_page() || is_post()
6
- - prevlink = page?.next?.path
11
+ - prevlink = page.prev.path
7
12
  if page && page.next
8
13
  - var nextlink = page?.next_link
9
14
  if is_page() || is_post()
10
- - nextlink = page?.prev?.path
15
+ - nextlink = page.next.path
11
16
  div(class="inner")
12
17
  div(class="panels")
13
18
  div(class="inner")
@@ -23,9 +28,8 @@ mixin sidebarRender(display_toc)
23
28
  != partial('_partials/sidebar/overview.pug', {}, {cache: true})
24
29
  ul(id="quick")
25
30
  li(class="prev pjax")
26
- if page && page.prev
27
- if prevlink
28
- != _url(prevlink, '<i class="ic i-chevron-left"></i>', {rel: 'prev', title: __('post.prev')})
31
+ if prevlink
32
+ != _url(prevlink, '<i class="ic i-chevron-left"></i>', {rel: 'prev', title: __('post.prev')})
29
33
  li(class="up")
30
34
  i(class="ic i-arrow-up")
31
35
  li(class="down")
@@ -24,7 +24,7 @@ div(class="status")
24
24
  //- span(id="times")
25
25
  if theme.footer.powered
26
26
  div(class="powered-by")
27
- != __('footer.powered', _url('https://hexo.io', 'Hexo') + ' & Theme.' + _url('https://github.com/zkz098/hexo-theme-shokaX/', 'ShokaX'))
27
+ != __('footer.powered', _url('https://hexo.io', 'Hexo') + ' & Theme.' + _url('https://github.com/theme-shoka-x/hexo-theme-shokaX/', 'ShokaX'))
28
28
  if theme.footer.icp.enable
29
29
  br
30
30
  span(style="display:inline;height:20px;line-height:20px;margin: 0px 0px 0px 5px; color:#939393;")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-shokax",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "a hexo theme based on shoka",
5
5
  "main": "index.js",
6
6
  "repository": "https://github.com/zkz098/hexo-theme-shokaX",
@@ -8,36 +8,40 @@
8
8
  "license": "GPL-3.0-or-later",
9
9
  "scripts": {
10
10
  "test": "cd ./source/js && tsc",
11
+ "build": "pnpm install && tsc",
11
12
  "docs:dev": "vuepress dev docs",
12
13
  "docs:build": "vuepress build docs"
13
14
  },
14
15
  "devDependencies": {
15
- "@algolia/client-search": "^4.14.3",
16
+ "@algolia/client-search": "^4",
16
17
  "@types/animejs": "^3.1.7",
17
18
  "@types/fancybox": "^3.5.3",
18
19
  "@types/hexo": "^3.8.8",
19
20
  "@types/jquery": "^3.5.16",
20
21
  "@types/js-yaml": "^4.0.5",
21
22
  "@types/lozad": "^1.16.1",
22
- "@types/node": "^18.13.0",
23
+ "@types/node": "^18.15.6",
23
24
  "@types/shelljs": "^0.8.11",
24
- "@typescript-eslint/eslint-plugin": "^5.51.0",
25
- "@typescript-eslint/parser": "^5.51.0",
26
- "@vuepress/client": "2.0.0-beta.60",
27
- "@vuepress/plugin-docsearch": "2.0.0-beta.60",
28
- "eslint": "^8.34.0",
25
+ "@typescript-eslint/eslint-plugin": "^5.56.0",
26
+ "@typescript-eslint/parser": "^5.56.0",
27
+ "@vuepress/client": "2.0.0-beta.61",
28
+ "@vuepress/plugin-docsearch": "2.0.0-beta.61",
29
+ "algoliasearch": "^4.16.0",
30
+ "eslint": "^8.36.0",
29
31
  "eslint-config-standard": "^17.0.0",
30
32
  "eslint-plugin-import": "^2.27.5",
31
33
  "eslint-plugin-n": "^15.6.1",
32
34
  "eslint-plugin-promise": "^6.1.1",
33
- "eslint-plugin-vue": "^9.9.0",
34
- "typescript": "^4.9.5",
35
+ "eslint-plugin-vue": "^9.10.0",
36
+ "instantsearch.js": "^4.53.0",
37
+ "pjax": "^0.2.8",
38
+ "typescript": "^5.0.2",
35
39
  "vue": "^3.2.47",
36
- "vuepress": "2.0.0-beta.60",
37
- "vuepress-plugin-sitemap2": "2.0.0-beta.180"
40
+ "vuepress": "2.0.0-beta.61",
41
+ "vuepress-plugin-sitemap2": "2.0.0-beta.197"
38
42
  },
39
43
  "dependencies": {
40
44
  "js-yaml": "^4.1.0",
41
- "sass": "^1.58.3"
45
+ "sass": "^1.60.0"
42
46
  }
43
47
  }
@@ -1,59 +1,48 @@
1
- 'use strict'
2
- /* global hexo */
3
-
4
- const fmtNum = num => {
5
- return num < 10 ? '0' + num : num
6
- }
7
-
8
- hexo.extend.filter.register('template_locals', locals => {
9
- const { config } = hexo
10
- const { __, theme } = locals
11
- const { i18n } = hexo.theme
12
-
13
- const pangu = theme.pangu
14
- ? require('pangu')
15
- : {
16
- spacing: (data) => {
17
- return data
18
- }
19
- }
20
-
21
- // Language & Config
22
- locals.alternate = theme.alternate
23
- locals.title = pangu.spacing(__('title') !== 'title' ? __('title') : config.title)
24
- locals.subtitle = pangu.spacing(__('subtitle') !== 'subtitle' ? __('subtitle') : config.subtitle)
25
- locals.author = __('author') !== 'author' ? __('author') : config.author
26
- locals.description = pangu.spacing(__('description') !== 'description' ? __('description') : config.description)
27
- locals.languages = [...i18n.languages]
28
- locals.languages.splice(locals.languages.indexOf('default'), 1)
29
- locals.page.lang = locals.page.lang || locals.page.language
30
- locals.hostname = new URL(config.url).hostname || config.url
31
-
32
- // Creative Commons
33
- if (theme.creative_commons.license === 'zero') {
34
- locals.ccURL = 'https://creativecommons.org/' + 'publicdomain/zero/1.0/' + (theme.creative_commons.language || '')
35
- } else {
36
- locals.ccURL = 'https://creativecommons.org/' + 'licenses/' + theme.creative_commons.license + '/4.0/' + (theme.creative_commons.language || '')
37
- }
38
-
39
- if (locals.page.title) {
40
- locals.page.title = pangu.spacing(locals.page.title)
41
- }
42
- locals.page.lastcat = ''
43
- if (locals.page.categories) {
44
- locals.page.categories.map((cat) => {
45
- if (cat.name) {
46
- cat.name = locals.page.lastcat = pangu.spacing(cat.name)
47
- }
48
- return cat
49
- })
50
- }
51
-
52
- if (locals.page.category) {
53
- locals.page.title = pangu.spacing(locals.page.category)
54
- }
55
-
56
- if (locals.page.month) {
57
- locals.page.month = fmtNum(locals.page.month)
58
- }
59
- })
1
+ const fmtNum = (num) => {
2
+ return num < 10 ? '0' + num : num;
3
+ };
4
+ hexo.extend.filter.register('template_locals', (locals) => {
5
+ const { config } = hexo;
6
+ const { __, theme } = locals;
7
+ const { i18n } = hexo.theme;
8
+ const pangu = theme.pangu
9
+ ? require('pangu')
10
+ : {
11
+ spacing: (data) => {
12
+ return data;
13
+ }
14
+ };
15
+ locals.alternate = theme.alternate;
16
+ locals.title = pangu.spacing(__('title') !== 'title' ? __('title') : config.title);
17
+ locals.subtitle = pangu.spacing(__('subtitle') !== 'subtitle' ? __('subtitle') : config.subtitle);
18
+ locals.author = __('author') !== 'author' ? __('author') : config.author;
19
+ locals.description = pangu.spacing(__('description') !== 'description' ? __('description') : config.description);
20
+ locals.languages = [...i18n.languages];
21
+ locals.languages.splice(locals.languages.indexOf('default'), 1);
22
+ locals.page.lang = locals.page.lang || locals.page.language;
23
+ locals.hostname = new URL(config.url).hostname || config.url;
24
+ if (theme.creative_commons.license === 'zero') {
25
+ locals.ccURL = 'https://creativecommons.org/' + 'publicdomain/zero/1.0/' + (theme.creative_commons.language || '');
26
+ }
27
+ else {
28
+ locals.ccURL = 'https://creativecommons.org/' + 'licenses/' + theme.creative_commons.license + '/4.0/' + (theme.creative_commons.language || '');
29
+ }
30
+ if (locals.page.title) {
31
+ locals.page.title = pangu.spacing(locals.page.title);
32
+ }
33
+ locals.page.lastcat = '';
34
+ if (locals.page.categories) {
35
+ locals.page.categories.map((cat) => {
36
+ if (cat.name) {
37
+ cat.name = locals.page.lastcat = pangu.spacing(cat.name);
38
+ }
39
+ return cat;
40
+ });
41
+ }
42
+ if (locals.page.category) {
43
+ locals.page.title = pangu.spacing(locals.page.category);
44
+ }
45
+ if (locals.page.month) {
46
+ locals.page.month = fmtNum(locals.page.month);
47
+ }
48
+ });
@@ -1,19 +1,13 @@
1
- /* global hexo */
2
- 'use strict'
3
-
4
- hexo.extend.filter.register('after_post_render', data => {
5
- const { config } = hexo
6
-
7
- data.content = data.content.replace(/(<img[^>]*) src=/img, '$1 data-src=')
8
-
9
- const siteHost = new URL(config.url).hostname || config.url
10
- data.content = data.content.replace(/<a[^>]* href="([^"]+)"[^>]*>([^<]*)<\/a>/img, (match, href, html) => {
11
- if (!href) return match
12
-
13
- // Exit if the url has same host with `config.url`, which means it's an internal link.
14
- const link = new URL(href, config.url)
15
- if (!link.protocol || link.hostname === siteHost) return match
16
-
17
- return `<span class="exturl" data-url="${Buffer.from(href).toString('base64')}">${html}</span>`
18
- })
19
- }, 0)
1
+ hexo.extend.filter.register('after_post_render', (data) => {
2
+ const { config } = hexo;
3
+ data.content = data.content.replace(/(<img[^>]*) src=/img, '$1 data-src=');
4
+ const siteHost = new URL(config.url).hostname || config.url;
5
+ data.content = data.content.replace(/<a[^>]* href="([^"]+)"[^>]*>([^<]*)<\/a>/img, (match, href, html) => {
6
+ if (!href)
7
+ return match;
8
+ const link = new URL(href, config.url);
9
+ if (!link.protocol || link.hostname === siteHost)
10
+ return match;
11
+ return `<span class="exturl" data-url="${Buffer.from(href).toString('base64')}">${html}</span>`;
12
+ });
13
+ }, 0);
@@ -1,141 +1,117 @@
1
- /* global hexo */
2
- 'use strict'
3
-
4
- const pagination = require('hexo-pagination')
5
-
1
+ 'use strict';
2
+ const pagination = require('hexo-pagination');
6
3
  const fmtNum = num => {
7
- return num < 10 ? '0' + num : num
8
- }
9
-
4
+ return num < 10 ? '0' + num : num;
5
+ };
10
6
  if (!(hexo.config.archive && hexo.config.archive.enabled === false)) {
11
- // when archive disabled pagination, per_page should be 0.
12
- let per_page
13
-
14
- if (hexo.config.archive === 1) {
15
- per_page = 0
16
- } else if (typeof hexo.config.per_page === 'undefined') {
17
- per_page = 10
18
- } else {
19
- per_page = hexo.config.per_page
20
- }
21
-
22
- hexo.config.archive_generator = Object.assign({
23
- per_page,
24
- yearly: true,
25
- monthly: true,
26
- daily: false
27
- }, hexo.config.archive_generator)
28
-
29
- hexo.extend.generator.register('archive', function (locals) {
30
- const config = hexo.config
31
- let archiveDir = config.archive_dir
32
- const paginationDir = config.pagination_dir || 'page'
33
- const allPosts = locals.posts.sort(config.archive_generator.order_by || '-date')
34
- const perPage = config.archive_generator.per_page
35
- let result = []
36
-
37
- if (!allPosts.length) return
38
-
39
- if (archiveDir[archiveDir.length - 1] !== '/') archiveDir += '/'
40
-
41
- function generate (path, posts, options) {
42
- options = options || {}
43
- options.archive = true
44
-
45
- result = result.concat(pagination(path, posts, {
46
- perPage: path === archiveDir ? 0 : perPage,
47
- layout: ['archive', 'index'],
48
- format: paginationDir + '/%d/',
49
- data: options
50
- }))
7
+ let per_page;
8
+ if (hexo.config.archive === 1) {
9
+ per_page = 0;
51
10
  }
52
-
53
- generate(archiveDir, allPosts)
54
-
55
- if (!config.archive_generator.yearly) return result
56
-
57
- const posts = {}
58
-
59
- // Organize posts by date
60
- allPosts.forEach(post => {
61
- const date = post.date
62
- const year = date.year()
63
- const month = date.month() + 1 // month is started from 0
64
-
65
- if (!Object.prototype.hasOwnProperty.call(posts, year)) {
66
- // 13个数组. 第一个数组是给这一年的文章准备的
67
- // 其他则是各个月份的文章
68
- posts[year] = [
69
- [],
70
- [],
71
- [],
72
- [],
73
- [],
74
- [],
75
- [],
76
- [],
77
- [],
78
- [],
79
- [],
80
- [],
81
- []
82
- ]
83
- }
84
-
85
- posts[year][0].push(post)
86
- posts[year][month].push(post)
87
- // Daily
88
- if (config.archive_generator.daily) {
89
- const day = date.date()
90
- if (!Object.prototype.hasOwnProperty.call(posts[year][month], 'day')) {
91
- posts[year][month].day = {}
92
- }
93
-
94
- (posts[year][month].day[day] || (posts[year][month].day[day] = [])).push(post)
95
- }
96
- })
97
-
98
- const Query = this.model('Post').Query
99
- const years = Object.keys(posts)
100
- let year, data, month, monthData, url
101
-
102
- // Yearly
103
- for (let i = 0, len = years.length; i < len; i++) {
104
- year = +years[i]
105
- data = posts[year]
106
- url = archiveDir + year + '/'
107
- if (!data[0].length) continue
108
-
109
- generate(url, new Query(data[0]), { year })
110
-
111
- if (!config.archive_generator.monthly && !config.archive_generator.daily) continue
112
-
113
- // Monthly
114
- for (month = 1; month <= 12; month++) {
115
- monthData = data[month]
116
- if (!monthData.length) continue
117
- if (config.archive_generator.monthly) {
118
- generate(url + fmtNum(month) + '/', new Query(monthData), {
119
- year,
120
- month
121
- })
11
+ else if (typeof hexo.config.per_page === 'undefined') {
12
+ per_page = 10;
13
+ }
14
+ else {
15
+ per_page = hexo.config.per_page;
16
+ }
17
+ hexo.config.archive_generator = Object.assign({
18
+ per_page,
19
+ yearly: true,
20
+ monthly: true,
21
+ daily: false
22
+ }, hexo.config.archive_generator);
23
+ hexo.extend.generator.register('archive', function (locals) {
24
+ const config = hexo.config;
25
+ let archiveDir = config.archive_dir;
26
+ const paginationDir = config.pagination_dir || 'page';
27
+ const allPosts = locals.posts.sort(config.archive_generator.order_by || '-date');
28
+ const perPage = config.archive_generator.per_page;
29
+ let result = [];
30
+ if (!allPosts.length)
31
+ return;
32
+ if (archiveDir[archiveDir.length - 1] !== '/')
33
+ archiveDir += '/';
34
+ function generate(path, posts, options) {
35
+ options = options || {};
36
+ options.archive = true;
37
+ result = result.concat(pagination(path, posts, {
38
+ perPage: path === archiveDir ? 0 : perPage,
39
+ layout: ['archive', 'index'],
40
+ format: paginationDir + '/%d/',
41
+ data: options
42
+ }));
122
43
  }
123
-
124
- if (!config.archive_generator.daily) continue
125
-
126
- // Daily
127
- for (let day = 1; day <= 31; day++) {
128
- const dayData = monthData.day[day]
129
- if (!dayData || !dayData.length) continue
130
- generate(url + fmtNum(month) + '/' + fmtNum(day) + '/', new Query(dayData), {
131
- year,
132
- month,
133
- day
134
- })
44
+ generate(archiveDir, allPosts);
45
+ if (!config.archive_generator.yearly)
46
+ return result;
47
+ const posts = {};
48
+ allPosts.forEach(post => {
49
+ const date = post.date;
50
+ const year = date.year();
51
+ const month = date.month() + 1;
52
+ if (!Object.prototype.hasOwnProperty.call(posts, year)) {
53
+ posts[year] = [
54
+ [],
55
+ [],
56
+ [],
57
+ [],
58
+ [],
59
+ [],
60
+ [],
61
+ [],
62
+ [],
63
+ [],
64
+ [],
65
+ [],
66
+ []
67
+ ];
68
+ }
69
+ posts[year][0].push(post);
70
+ posts[year][month].push(post);
71
+ if (config.archive_generator.daily) {
72
+ const day = date.date();
73
+ if (!Object.prototype.hasOwnProperty.call(posts[year][month], 'day')) {
74
+ posts[year][month].day = {};
75
+ }
76
+ (posts[year][month].day[day] || (posts[year][month].day[day] = [])).push(post);
77
+ }
78
+ });
79
+ const Query = this.model('Post').Query;
80
+ const years = Object.keys(posts);
81
+ let year, data, month, monthData, url;
82
+ for (let i = 0, len = years.length; i < len; i++) {
83
+ year = +years[i];
84
+ data = posts[year];
85
+ url = archiveDir + year + '/';
86
+ if (!data[0].length)
87
+ continue;
88
+ generate(url, new Query(data[0]), { year });
89
+ if (!config.archive_generator.monthly && !config.archive_generator.daily)
90
+ continue;
91
+ for (month = 1; month <= 12; month++) {
92
+ monthData = data[month];
93
+ if (!monthData.length)
94
+ continue;
95
+ if (config.archive_generator.monthly) {
96
+ generate(url + fmtNum(month) + '/', new Query(monthData), {
97
+ year,
98
+ month
99
+ });
100
+ }
101
+ if (!config.archive_generator.daily)
102
+ continue;
103
+ for (let day = 1; day <= 31; day++) {
104
+ const dayData = monthData.day[day];
105
+ if (!dayData || !dayData.length)
106
+ continue;
107
+ generate(url + fmtNum(month) + '/' + fmtNum(day) + '/', new Query(dayData), {
108
+ year,
109
+ month,
110
+ day
111
+ });
112
+ }
113
+ }
135
114
  }
136
- }
137
- }
138
-
139
- return result
140
- })
115
+ return result;
116
+ });
141
117
  }