hexo-theme-gnix 1.1.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 (143) hide show
  1. package/README.md +106 -0
  2. package/include/hexo/filter/locals.js +109 -0
  3. package/include/hexo/generator/categories.js +12 -0
  4. package/include/hexo/generator/category.js +52 -0
  5. package/include/hexo/generator/insight.js +50 -0
  6. package/include/hexo/generator/manifest.js +23 -0
  7. package/include/hexo/generator/tags.js +12 -0
  8. package/include/hexo/helper/cdn.js +21 -0
  9. package/include/hexo/helper/page.js +27 -0
  10. package/include/hexo/view.js +40 -0
  11. package/include/register.js +11 -0
  12. package/include/util/common.js +33 -0
  13. package/languages/en.yml +47 -0
  14. package/languages/fr.yml +46 -0
  15. package/languages/ja.yml +46 -0
  16. package/languages/zh-CN.yml +47 -0
  17. package/languages/zh-TW.yml +47 -0
  18. package/layout/archive.jsx +118 -0
  19. package/layout/categories.jsx +137 -0
  20. package/layout/category.jsx +38 -0
  21. package/layout/comment/disqus.jsx +79 -0
  22. package/layout/comment/disqusjs.jsx +127 -0
  23. package/layout/comment/giscus.jsx +193 -0
  24. package/layout/comment/gitalk.jsx +141 -0
  25. package/layout/comment/twikoo.jsx +63 -0
  26. package/layout/comment/utterances.jsx +86 -0
  27. package/layout/comment/valine.jsx +143 -0
  28. package/layout/comment/waline.jsx +156 -0
  29. package/layout/common/article.jsx +131 -0
  30. package/layout/common/article_cover.jsx +33 -0
  31. package/layout/common/article_media.jsx +34 -0
  32. package/layout/common/comment.jsx +38 -0
  33. package/layout/common/footer.jsx +228 -0
  34. package/layout/common/head.jsx +242 -0
  35. package/layout/common/navbar.jsx +219 -0
  36. package/layout/common/plugins.jsx +39 -0
  37. package/layout/common/scripts.jsx +49 -0
  38. package/layout/common/search.jsx +22 -0
  39. package/layout/common/theme_selector.jsx +79 -0
  40. package/layout/common/toc.jsx +53 -0
  41. package/layout/index.jsx +29 -0
  42. package/layout/layout.jsx +34 -0
  43. package/layout/misc/article_licensing.jsx +114 -0
  44. package/layout/misc/meta.jsx +61 -0
  45. package/layout/misc/open_graph.jsx +164 -0
  46. package/layout/misc/paginator.jsx +90 -0
  47. package/layout/misc/structured_data.jsx +110 -0
  48. package/layout/misc/web_app.jsx +106 -0
  49. package/layout/page.jsx +12 -0
  50. package/layout/plugin/bing_webmaster.jsx +47 -0
  51. package/layout/plugin/busuanzi.jsx +40 -0
  52. package/layout/plugin/clarity.jsx +22 -0
  53. package/layout/plugin/cookie_consent.jsx +136 -0
  54. package/layout/plugin/google_analytics.jsx +66 -0
  55. package/layout/plugin/google_tag_mamager.jsx +41 -0
  56. package/layout/plugin/netlify.jsx +39 -0
  57. package/layout/plugin/pjax.jsx +20 -0
  58. package/layout/plugin/statcounter.jsx +69 -0
  59. package/layout/plugin/twitter_conversion_tracking.jsx +51 -0
  60. package/layout/post.jsx +16 -0
  61. package/layout/search/insight.jsx +53 -0
  62. package/layout/tag.jsx +29 -0
  63. package/layout/tags.jsx +55 -0
  64. package/package.json +42 -0
  65. package/scripts/index.js +1 -0
  66. package/source/css/callout_blocks.css +204 -0
  67. package/source/css/default.css +1590 -0
  68. package/source/css/font/woff2/Futura-Book.woff2 +0 -0
  69. package/source/css/font/woff2/Paris2024-Variable.woff2 +0 -0
  70. package/source/css/font/woff2/doto.woff2 +0 -0
  71. package/source/css/optional/chinese.css +17 -0
  72. package/source/css/responsive/desktop.css +164 -0
  73. package/source/css/responsive/mobile.css +46 -0
  74. package/source/css/responsive/tablet.css +46 -0
  75. package/source/css/responsive/touch.css +254 -0
  76. package/source/css/shiki/shiki.min.css +1 -0
  77. package/source/css/twikoo.css +2143 -0
  78. package/source/img/avatar.webp +0 -0
  79. package/source/img/background.webp +0 -0
  80. package/source/img/favicon.svg +6 -0
  81. package/source/img/logo.svg +9 -0
  82. package/source/img/og_image.png +0 -0
  83. package/source/js/busuanzi.js +46 -0
  84. package/source/js/host/cookieconsent/3.1.1/build/cookieconsent.min.css +6 -0
  85. package/source/js/host/cookieconsent/3.1.1/build/cookieconsent.min.js +1 -0
  86. package/source/js/host/iconify-icon/3.0.2/iconify-icon.min.js +12 -0
  87. package/source/js/host/medium-zoom/dist/medium-zoom.min.js +2 -0
  88. package/source/js/host/mermaid/mermaid.min.js +2811 -0
  89. package/source/js/host/pjax/0.2.8/pjax.min.js +1 -0
  90. package/source/js/host/twikoo/1.6.41/dist/twikoo.all.min.js +2 -0
  91. package/source/js/insight.js +330 -0
  92. package/source/js/instant-page.min.js +1 -0
  93. package/source/js/live2d_Asoul/Model/Ava/Ava.4096/texture_00.webp +0 -0
  94. package/source/js/live2d_Asoul/Model/Ava/Ava.moc3 +0 -0
  95. package/source/js/live2d_Asoul/Model/Ava/Ava.model3.json +323 -0
  96. package/source/js/live2d_Asoul/Model/Ava/Ava.physics3.json +1225 -0
  97. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_idle.motion3.json +1 -0
  98. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_shake01.motion3.json +1 -0
  99. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_shake02.motion3.json +1 -0
  100. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap01.motion3.json +1 -0
  101. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap02.motion3.json +1 -0
  102. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap03.motion3.json +1 -0
  103. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap04.motion3.json +1 -0
  104. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap05.motion3.json +1 -0
  105. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap06.motion3.json +1 -0
  106. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap07.motion3.json +1 -0
  107. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap08.motion3.json +1 -0
  108. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap09.motion3.json +1 -0
  109. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap10.motion3.json +1 -0
  110. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap11.motion3.json +1 -0
  111. package/source/js/live2d_Asoul/Model/Ava/raw.ex.json +16 -0
  112. package/source/js/live2d_Asoul/Model/Ava/raw.model3.json +321 -0
  113. package/source/js/live2d_Asoul/Model/Diana/Diana.4096/texture_00.webp +0 -0
  114. package/source/js/live2d_Asoul/Model/Diana/Diana.moc3 +0 -0
  115. package/source/js/live2d_Asoul/Model/Diana/Diana.model3.json +212 -0
  116. package/source/js/live2d_Asoul/Model/Diana/Diana.physics3.json +764 -0
  117. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_idle.motion3.json +1 -0
  118. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap01.motion3.json +1 -0
  119. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap02.motion3.json +1 -0
  120. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap03.motion3.json +1 -0
  121. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap04.motion3.json +1 -0
  122. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap05.motion3.json +1 -0
  123. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap06.motion3.json +1 -0
  124. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap07.motion3.json +1 -0
  125. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap08.motion3.json +1 -0
  126. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap09.motion3.json +1 -0
  127. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap10.motion3.json +1 -0
  128. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap11.motion3.json +1 -0
  129. package/source/js/live2d_Asoul/Model/Diana/raw.ex.json +16 -0
  130. package/source/js/live2d_Asoul/Model/Diana/raw.model3.json +210 -0
  131. package/source/js/live2d_Asoul/TweenLite.js +12 -0
  132. package/source/js/live2d_Asoul/cubism4.min.js +2 -0
  133. package/source/js/live2d_Asoul/live2dcubismcore.min.js +9 -0
  134. package/source/js/live2d_Asoul/load.js +231 -0
  135. package/source/js/live2d_Asoul/pio.css +161 -0
  136. package/source/js/live2d_Asoul/pio.js +296 -0
  137. package/source/js/live2d_Asoul/pio_sdk4.js +149 -0
  138. package/source/js/live2d_Asoul/pixi.min.js +9 -0
  139. package/source/js/main.js +218 -0
  140. package/source/js/pjax.js +29 -0
  141. package/source/js/shiki/shiki.js +191 -0
  142. package/source/js/theme-selector.js +206 -0
  143. package/util/cache.js +47 -0
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # Hexo Theme Icarus
2
+
3
+ ## Demo & Preview
4
+
5
+ [vluv's space](https://vluv.space/)
6
+
7
+ ### Multiple Theme Support
8
+
9
+ Support multiple light and dark themes:
10
+
11
+ - **System Theme**: Follow system theme automatically, use `Nord` for light mode and `Mocha` for dark mode by default
12
+ - **Light Themes**: `Nord`, `Cattpuccin Latte`
13
+ - **Dark Themes**: `Catppuccin Mocha`, `Catppuccin Macchiato`, `Tokyo Night`
14
+
15
+ | ![](assets/README/nord.png) | ![](assets/README/mocha.png) |
16
+ | --------------------------- | ---------------------------- |
17
+
18
+ ### Mermaid Filter [^2]
19
+
20
+ [^2]:
21
+ Require [Efterklang/hexo-mermaid-diagram](https://github.com/Efterklang/hexo-mermaid-diagram)
22
+ 🚧 Dark mode WIP...
23
+
24
+ ![image](https://github.com/user-attachments/assets/3bd2d897-721d-4505-8194-6a592bbceb31)
25
+
26
+ ### Components
27
+
28
+ #### Table
29
+
30
+ | ![1763371106238](assets/README/table_nord.png) | ![1763371131768](assets/README/table_tokyo.png) |
31
+ | ---------------------------------------------- | ----------------------------------------------- |
32
+
33
+ #### Quote
34
+
35
+ | ![1763371059037](assets/README/quote_light.png) |
36
+ | ----------------------------------------------- |
37
+ | ![1763371021736](assets/README/quote_dark.png) |
38
+
39
+ #### Footer
40
+
41
+ | ![1763371250167](assets/README/footer_nord.png) |
42
+ | ----------------------------------------------- |
43
+ | ![1763371215054](assets/README/footer_dark.png) |
44
+
45
+ ## Installation
46
+
47
+ ### Using git submodule(Recommended)
48
+
49
+ Using git submodule instead of bun add is recommended if you want to make any customizations to the theme
50
+
51
+ ```shell
52
+ $ git submodule add https://github.com/Efterklang/hexo-theme-icarus themes/icarus
53
+ $ hexo config theme icarus
54
+ ```
55
+
56
+ ```diff package.json
57
+ {
58
+ "dependencies": {
59
+ + "hexo": "^7.2.0",
60
+ + "hexo-cli": "^4.3.2",
61
+ + "hexo-generator-archive": "^2.0.0",
62
+ + "hexo-generator-category": "^2.0.0",
63
+ + "hexo-generator-tag": "^2.0.0",
64
+ + "hexo-pagination": "^3.0.0",
65
+ + "hexo-renderer-inferno": "^1.0.2",
66
+ + "hexo-server": "^3.0.0",
67
+ + "hexo-util": "^3.3.0",
68
+ + "inferno": "^9.0.3",
69
+ + "inferno-create-element": "^9.0.3",
70
+ + "moment": "^2.30.1"
71
+ }
72
+ }
73
+ ```
74
+
75
+ ### Using Bun
76
+
77
+ ```shell
78
+ $ bun add git+https://github.com/Efterklang/hexo-theme-icarus
79
+ $ hexo config theme icarus
80
+ ```
81
+
82
+ ## Setup
83
+
84
+ <details>
85
+ <summary>Math Rendering Setup</summary>
86
+
87
+ To enable math rendering with optimized performance, use [markdown-it-mathjax3-pro](https://github.com/NeoNexusX/markdown-it-mathjax3-pro), which supports both SSR and CSR modes
88
+
89
+ </details>
90
+
91
+ <details>
92
+ <summary>Code Highlight Setup</summary>
93
+
94
+ Use [hexo-shiki-highlight](https://github.com/Efterklang/hexo-shiki-highlight) plugin for code block highlighting, support multiple themes as well;
95
+
96
+ Set `syntax_highlighter` to `shiki` in your hexo `_config.yml`:
97
+
98
+ ```yaml _config.yml
99
+ # Syntax Highlighter
100
+ syntax_highlighter: shiki
101
+ ```
102
+
103
+ | <img width="1386" height="720" alt="image" src="https://github.com/user-attachments/assets/f0435c12-5140-4ca4-86bb-e5237039cc2d" /> | <img width="1394" height="736" alt="image" src="https://github.com/user-attachments/assets/406a656f-9e99-4fb7-bb34-a2e1078451e4" /> |
104
+ | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
105
+
106
+ </details>
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Register the Hexo filter for merging theme and site config, and add all helper functions to a
3
+ * dedicated property (<code>helper</code>) in the locals.
4
+ * @module hexo/filter/locals
5
+ */
6
+ const fs = require("node:fs");
7
+ const path = require("node:path");
8
+ const yaml = require("js-yaml");
9
+
10
+ /**
11
+ * Register the Hexo filter for merging theme and site config, and add all helper functions to a
12
+ * dedicated property (<code>helper</code>) in the locals.
13
+ * <p>
14
+ * This filter will try to merge
15
+ * <ul>
16
+ * <li>the post/page config defined in the Markdown file's front-matter,</li>
17
+ * <li>post/page config defined in <code>themes/[theme_name]/_config.post.yml</code> or
18
+ * <code>themes/[theme_name]/_config.page.yml</code>,</li>
19
+ * <li>post/page layout config defined in <code>[site_root]/_config.post.yml</code> or
20
+ * <code>[site_root]/_config.page.yml</code>,</li>
21
+ * <li>theme config defined in <code>themes/[theme_name]/_config.yml</code> or
22
+ * <code>node_modules/hexo-theme-[theme_name]/_config.yml</code> if it is installed as an NPM package,
23
+ * </li>
24
+ * <li>and the site config defined in <code>_config.yml</code>,</li>
25
+ * </ul>
26
+ * in the above order (the former config will overwrite later ones).
27
+ * This allow the user to customize the theme for each post/page, as well as for all post or pages.
28
+ * <br>
29
+ * It also adds a new variable named <code>helper</code>, containing all Hexo helper functions, to the page
30
+ * locals so that you can them through it instead.
31
+ * It is useful for passing helper functions to the cacheable view components.
32
+ * <p>
33
+ * <b>NOTE: This filter must be registered before any other Hexo extensions or views in order to take effect.</b>
34
+ *
35
+ * @param {Hexo} hexo The Hexo instance.
36
+ */
37
+ module.exports = (hexo) => {
38
+ const RESERVED_KEYS = {
39
+ post: Object.keys(require("hexo/dist/models/post")(hexo).paths),
40
+ page: Object.keys(require("hexo/dist/models/page")(hexo).paths),
41
+ };
42
+
43
+ function loadLayoutConfig(layout) {
44
+ let config = {};
45
+ const configInSiteDir = path.join(hexo.base_dir, `_config.${layout}.yml`);
46
+ const configInThemeDir = path.join(hexo.theme_dir, `_config.${layout}.yml`);
47
+ [configInSiteDir, configInThemeDir].forEach((configPath) => {
48
+ if (fs.existsSync(configPath)) {
49
+ config = Object.assign(config, yaml.load(fs.readFileSync(configPath)));
50
+ }
51
+ });
52
+ return config;
53
+ }
54
+
55
+ const ALTERNATIVE_CONFIG = {
56
+ post: loadLayoutConfig("post"),
57
+ page: loadLayoutConfig("page"),
58
+ };
59
+
60
+ function stripConfig(source, reservedKeys) {
61
+ const result = {};
62
+ Object.keys(source)
63
+ .filter(
64
+ (key) =>
65
+ !key.startsWith("_") &&
66
+ !reservedKeys.includes(key) &&
67
+ typeof source[key] !== "function",
68
+ )
69
+ .forEach((key) => {
70
+ result[key] = source[key];
71
+ });
72
+ return result;
73
+ }
74
+
75
+ hexo.extend.filter.register("template_locals", (locals) => {
76
+ // inject helper functions
77
+ locals.helper = {};
78
+ const helpers = hexo.extend.helper.list();
79
+ for (const name in helpers) {
80
+ locals.helper[name] = helpers[name].bind(locals);
81
+ }
82
+ if (typeof locals.__ === "function") {
83
+ locals.helper.__ = locals.__;
84
+ }
85
+ if (typeof locals._p === "function") {
86
+ locals.helper._p = locals._p;
87
+ }
88
+
89
+ const page = locals.page;
90
+ if (page) {
91
+ locals.config = Object.assign({}, locals.config, locals.theme);
92
+ if (page.layout in ALTERNATIVE_CONFIG) {
93
+ // load alternative config if exists
94
+ locals.config = Object.assign(
95
+ locals.config,
96
+ ALTERNATIVE_CONFIG[page.layout],
97
+ );
98
+ }
99
+ // merge page configs
100
+ if (page.__post === true) {
101
+ Object.assign(locals.config, stripConfig(page, RESERVED_KEYS.post));
102
+ } else if (page.__page === true) {
103
+ Object.assign(locals.config, stripConfig(page, RESERVED_KEYS.page));
104
+ }
105
+ }
106
+
107
+ return locals;
108
+ });
109
+ };
@@ -0,0 +1,12 @@
1
+ // Generates the <root>/categories page
2
+ module.exports = (hexo) => {
3
+ hexo.extend.generator.register("categories", (locals) => {
4
+ return {
5
+ path: "categories/",
6
+ layout: ["categories"],
7
+ data: Object.assign({}, locals, {
8
+ __categories: true,
9
+ }),
10
+ };
11
+ });
12
+ };
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Register the Hexo generator for generating <code>/category/</code> pages.
3
+ * @module hexo/generator/category
4
+ */
5
+ const pagination = require("hexo-pagination");
6
+
7
+ /**
8
+ * Register the Hexo generator for generating <code>/category/</code> pages.
9
+ * <p>
10
+ * An array of parent categories will be attached to the page local
11
+ * variables.
12
+ *
13
+ * @param {Hexo} hexo The Hexo instance.
14
+ */
15
+ module.exports = (hexo) => {
16
+ hexo.extend.generator.register("category", function (locals) {
17
+ const config = this.config;
18
+ const paginationDir = config.pagination_dir || "page";
19
+ const perPage =
20
+ (config.category_generator ? config.category_generator.per_page : null) ||
21
+ 0;
22
+ const orderBy =
23
+ (config.category_generator ? config.category_generator.order_by : null) ||
24
+ "-date";
25
+
26
+ function findParent(category) {
27
+ let parents = [];
28
+ if (typeof category === "object" && "parent" in category) {
29
+ const parent = locals.categories
30
+ .filter((cat) => cat._id === category.parent)
31
+ .first();
32
+ parents = findParent(parent).concat([parent]);
33
+ }
34
+ return parents;
35
+ }
36
+
37
+ return locals.categories.reduce((result, category) => {
38
+ const posts = category.posts.sort(orderBy);
39
+ const data = pagination(category.path, posts, {
40
+ perPage: perPage,
41
+ layout: ["category", "archive", "index"],
42
+ format: `${paginationDir}/%d/`,
43
+ data: {
44
+ category: category.name,
45
+ parents: findParent(category),
46
+ },
47
+ });
48
+
49
+ return result.concat(data);
50
+ }, []);
51
+ });
52
+ };
@@ -0,0 +1,50 @@
1
+ const util = require("hexo-util");
2
+
3
+ module.exports = (hexo) => {
4
+ hexo.extend.generator.register("insight", function (locals) {
5
+ const url_for = hexo.extend.helper.get("url_for").bind(this);
6
+ function minify(str) {
7
+ return util
8
+ .stripHTML(str)
9
+ .trim()
10
+ .replace(/\n/g, " ")
11
+ .replace(/\s+/g, " ")
12
+ .replace(/&#x([\da-fA-F]+);/g, (_, hex) => {
13
+ return String.fromCharCode(parseInt(hex, 16));
14
+ })
15
+ .replace(/&#([\d]+);/g, (_, dec) => {
16
+ return String.fromCharCode(dec);
17
+ });
18
+ }
19
+ function mapPost(post) {
20
+ return {
21
+ title: util.escapeHTML(post.title).trim(),
22
+ text: minify(post.content),
23
+ link: url_for(post.path),
24
+ };
25
+ }
26
+ function mapTag(tag) {
27
+ return {
28
+ name: util.escapeHTML(tag.name).trim(),
29
+ slug: minify(tag.slug),
30
+ link: url_for(tag.path),
31
+ };
32
+ }
33
+ const site = {
34
+ posts: locals.posts.map(mapPost),
35
+ tags: locals.tags.map(mapTag),
36
+ categories: locals.categories.map(mapTag),
37
+ };
38
+ const index_pages = this.theme.config?.search?.index_pages;
39
+ if (index_pages === false) {
40
+ site.pages = [];
41
+ } else {
42
+ site.pages = locals.pages.map(mapPost);
43
+ }
44
+
45
+ return {
46
+ path: "/content.json",
47
+ data: JSON.stringify(site),
48
+ };
49
+ });
50
+ };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Web app manifest.json generator.
3
+ */
4
+
5
+ module.exports = (hexo) => {
6
+ hexo.extend.generator.register("manifest", function (_locals) {
7
+ const url_for = hexo.extend.helper.get("url_for").bind(this);
8
+ let { manifest = {} } = this.theme?.config?.head || {};
9
+
10
+ manifest = Object.assign({}, manifest);
11
+ if (!manifest.name) {
12
+ manifest.name = this.config.title;
13
+ }
14
+ if (!manifest.start_url) {
15
+ manifest.start_url = url_for("/index.html");
16
+ }
17
+
18
+ return {
19
+ path: "/manifest.json",
20
+ data: JSON.stringify(manifest),
21
+ };
22
+ });
23
+ };
@@ -0,0 +1,12 @@
1
+ // Generate "<root>/tags/" page
2
+ module.exports = (hexo) => {
3
+ hexo.extend.generator.register("tags", (locals) => {
4
+ return {
5
+ path: "tags/",
6
+ layout: ["tags"],
7
+ data: Object.assign({}, locals, {
8
+ __tags: true,
9
+ }),
10
+ };
11
+ });
12
+ };
@@ -0,0 +1,21 @@
1
+ function getCDN(cdn, pkg, version, filename) {
2
+ switch (cdn) {
3
+ case "host":
4
+ return `/js/host/${pkg}/${version}/${filename}`;
5
+ case "loli":
6
+ return `https://cdnjs.loli.net/ajax/libs/${pkg}/${version}/${filename}`;
7
+ case "jsdelivr":
8
+ return `https://cdn.jsdelivr.net/npm/${pkg}@${version}/${filename}`;
9
+ case "bootcdn":
10
+ return `https://cdn.bootcdn.net/ajax/libs/${pkg}/${version}/${filename}`;
11
+ default:
12
+ throw new Error(`Unknown CDN provider: ${cdn}`);
13
+ }
14
+ }
15
+
16
+ module.exports = (hexo) => {
17
+ hexo.extend.helper.register("cdn", function (_package, version, filename) {
18
+ cdn = this.config.providers?.cdn ? this.config.providers.cdn : "jsdelivr";
19
+ return getCDN(cdn, _package, version, filename);
20
+ });
21
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Register the Hexo helper functions for a Hexo page/post.
3
+ * @module hexo/helper/page
4
+ */
5
+
6
+ /**
7
+ * Register the Hexo helper functions for a Hexo page/post.
8
+ *
9
+ * @param {Hexo} hexo The Hexo instance.
10
+ * @example
11
+ * // Use the function below to test if the given page is the /categories page
12
+ * // Need to be combined with lib/hexo/generator/categories
13
+ * is_categories(page);
14
+ *
15
+ * // Use the function below to test if the given page is the /tags page
16
+ * // Need to be combined with lib/hexo/generator/tags
17
+ * is_tags(page);
18
+ */
19
+ module.exports = (hexo) => {
20
+ hexo.extend.helper.register("is_categories", function (page = null) {
21
+ return (page === null ? this.page : page).__categories === true;
22
+ });
23
+
24
+ hexo.extend.helper.register("is_tags", function (page = null) {
25
+ return (page === null ? this.page : page).__tags === true;
26
+ });
27
+ };
@@ -0,0 +1,40 @@
1
+ const path = require("node:path");
2
+
3
+ let themeDir = null;
4
+
5
+ function _resolve(filename) {
6
+ if (path.isAbsolute(filename)) {
7
+ return require.resolve(filename);
8
+ }
9
+ const resolved = [path.join(themeDir, "/layout/", filename)].find(
10
+ (filepath) => {
11
+ try {
12
+ require.resolve(filepath);
13
+ return true;
14
+ } catch (_e) {
15
+ return false;
16
+ }
17
+ },
18
+ );
19
+
20
+ return require.resolve(resolved ? resolved : filename);
21
+ }
22
+
23
+ function _require(filename) {
24
+ return require(_resolve(filename));
25
+ }
26
+
27
+ _require.resolve = _resolve;
28
+
29
+ /**
30
+ * Initialize module global variables, including the theme directory variable.
31
+ * Must be used before {@link module:core/view.require} or {@link module:core/view.resolve}.
32
+ */
33
+ function init(hexo) {
34
+ themeDir = hexo.theme_dir;
35
+ }
36
+
37
+ module.exports = {
38
+ init,
39
+ require: _require,
40
+ };
@@ -0,0 +1,11 @@
1
+ module.exports = (hexo) => {
2
+ require("./hexo/filter/locals")(hexo);
3
+ require("./hexo/generator/insight")(hexo);
4
+ require("./hexo/generator/categories")(hexo);
5
+ require("./hexo/generator/category")(hexo);
6
+ require("./hexo/generator/manifest")(hexo);
7
+ require("./hexo/generator/tags")(hexo);
8
+ require("./hexo/helper/cdn")(hexo);
9
+ require("./hexo/helper/page")(hexo);
10
+ require("./hexo/view").init(hexo);
11
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 共享的工具函数和常量
3
+ */
4
+ const { Component, Fragment } = require("inferno");
5
+ const view = require("../hexo/view");
6
+ const { cacheComponent } = require("../../util/cache");
7
+
8
+ function lazy_load_css(href) {
9
+ script_str = `var link = document.createElement('link');
10
+ link.rel = 'stylesheet';
11
+ link.href = '${href}';
12
+ document.getElementsByTagName('head')[0].appendChild(link);`;
13
+ return script_str;
14
+ }
15
+
16
+ module.exports = {
17
+ // 导出常用的依赖
18
+ Component,
19
+ Fragment,
20
+ view,
21
+ lazy_load_css,
22
+ cacheComponent,
23
+
24
+ // 通用的组件加载函数
25
+ loadComponent: (componentPath, fallback = null) => {
26
+ try {
27
+ const Widget = view.require(componentPath);
28
+ return Widget.Cacheable ? Widget.Cacheable : Widget;
29
+ } catch (_) {
30
+ return fallback;
31
+ }
32
+ },
33
+ };
@@ -0,0 +1,47 @@
1
+ common:
2
+ archive:
3
+ one: "Archive"
4
+ other: "Archives"
5
+ category:
6
+ one: "Category"
7
+ other: "Categories"
8
+ tag:
9
+ one: "Tag"
10
+ other: "Tags"
11
+ post:
12
+ one: "Post"
13
+ other: "Posts"
14
+ page:
15
+ one: "Page"
16
+ other: "Pages"
17
+ prev: "Previous"
18
+ next: "Next"
19
+ article:
20
+ created_at: "Posted&nbsp;%s"
21
+ more: "Read more"
22
+ comments: "Comments"
23
+ edited: "edited"
24
+ word_count:
25
+ one: "About %d word"
26
+ other: "About %d words"
27
+ licensing:
28
+ author: "Author"
29
+ created_at: "Posted on"
30
+ updated_at: "Updated on"
31
+ licensed_under: "Licensed under"
32
+ plugin:
33
+ visit_count: "%s&nbsp;visits"
34
+ visitor_count: "Visited by %s users"
35
+ cookie_consent:
36
+ message: This website uses cookies to improve your experience.
37
+ dismiss: Got it!
38
+ allow: Allow cookies
39
+ deny: Decline
40
+ link: Learn more
41
+ policy: Cookie Policy
42
+ search:
43
+ search: "Search"
44
+ hint: "Search(Ctrl/󰘳 + K)"
45
+ no_result: "No results for"
46
+ untitled: "(Untitled)"
47
+ empty_preview: "(No preview)"
@@ -0,0 +1,46 @@
1
+ common:
2
+ archive:
3
+ one: "Archive"
4
+ other: "Archives"
5
+ category:
6
+ one: "Catégorie"
7
+ other: "Catégories"
8
+ tag:
9
+ one: "Tag"
10
+ other: "Tags"
11
+ post:
12
+ one: "Article"
13
+ other: "Articles"
14
+ page:
15
+ one: "Page"
16
+ other: "Pages"
17
+ prev: "Préc"
18
+ next: "Suiv"
19
+ article:
20
+ created_at: "Publié il y a&nbsp;%s"
21
+ more: "Lire la suite"
22
+ comments: "Commentaires"
23
+ word_count:
24
+ one: "Environ %d mot"
25
+ other: "Environ %d mots"
26
+ licensing:
27
+ author: "Auteur"
28
+ created_at: "Posté le"
29
+ updated_at: "Mis à jour le"
30
+ licensed_under: "Licencié sous"
31
+ plugin:
32
+ visit_count: "%s&nbsp;visites"
33
+ visitor_count: "Visité par %s utilisateurs"
34
+ cookie_consent:
35
+ message: "Ce site Web utilise des cookies pour améliorer votre expérience."
36
+ dismiss: "C'est bon"
37
+ allow: "Autoriser les cookies"
38
+ deny: "Refuser"
39
+ link: "En savoir plus"
40
+ policy: "Politique relative aux cookies"
41
+ search:
42
+ search: "Rechercher"
43
+ hint: "Ecrivez quelque chose..."
44
+ no_result: "Aucun résultat pour"
45
+ untitled: "(Sans titre)"
46
+ empty_preview: "(Pas de prévisualisation)"
@@ -0,0 +1,46 @@
1
+ common:
2
+ archive:
3
+ one: "アーカイブ"
4
+ other: "アーカイブ"
5
+ category:
6
+ one: "カテゴリ"
7
+ other: "カテゴリ"
8
+ tag:
9
+ one: "タグ"
10
+ other: "タグ"
11
+ post:
12
+ one: "投稿"
13
+ other: "投稿"
14
+ page:
15
+ one: "ページ"
16
+ other: "ページ"
17
+ prev: "前"
18
+ next: "次"
19
+ article:
20
+ created_at: "%sに投稿"
21
+ more: "続きを読む"
22
+ comments: "コメント"
23
+ word_count:
24
+ one: "約%d語"
25
+ other: "約%d語"
26
+ licensing:
27
+ author: "Author"
28
+ created_at: "Posted on"
29
+ updated_at: "Updated on"
30
+ licensed_under: "Licensed under"
31
+ plugin:
32
+ visit_count: "%s回の訪問"
33
+ visitor_count: "%s人のユーザーがアクセス"
34
+ cookie_consent:
35
+ message: このウェブサイトはあなたの経験を改善するためにCookieを使用しています。
36
+ dismiss: 了解しました
37
+ allow: Cookiesを許可する
38
+ deny: 拒否する
39
+ link: もっと詳しく知る
40
+ policy: Cookieポリシー
41
+ search:
42
+ search: "検索"
43
+ hint: "何かを入力してください..."
44
+ no_result: "の結果はありません"
45
+ untitled: "(無題)"
46
+ empty_preview: "(プレビューなし)"