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
@@ -0,0 +1,47 @@
1
+ common:
2
+ archive:
3
+ one: "ARCHIVE"
4
+ other: "ARCHIVE"
5
+ category:
6
+ one: "CATEGORY"
7
+ other: "CATEGORY"
8
+ tag:
9
+ one: "TAGS"
10
+ other: "TAGS"
11
+ post:
12
+ one: "POST"
13
+ other: "POST"
14
+ page:
15
+ one: "PAGE"
16
+ other: "PAGE"
17
+ prev: "Previous"
18
+ next: "Next"
19
+ article:
20
+ created_at: "%s"
21
+ more: "Read"
22
+ comments: "评论"
23
+ edited: "编辑于"
24
+ word_count:
25
+ one: "约%d字"
26
+ other: "约%d字"
27
+ licensing:
28
+ author: "Author"
29
+ created_at: "Posted on"
30
+ updated_at: "Updated on"
31
+ licensed_under: "License under"
32
+ plugin:
33
+ visit_count: "%sPV" # post页面显示的page view次数
34
+ visitor_count: 'PV&nbsp;<span id="busuanzi_site_pv">-</span>&nbsp;UV&nbsp;<span id="busuanzi_site_uv">-</span>&nbsp;'
35
+ cookie_consent:
36
+ message: 此网站使用 Cookie,以启用评论系统和分析功能。
37
+ dismiss: 知道了
38
+ allow: 允许使用Cookie
39
+ deny: 拒绝
40
+ link: 了解更多
41
+ policy: Cookie政策
42
+ search:
43
+ search: "搜索"
44
+ hint: "想要查找什么...(Ctrl/󰘳 + K)"
45
+ no_result: "未找到搜索结果"
46
+ untitled: "(无标题)"
47
+ empty_preview: "(无内容预览)"
@@ -0,0 +1,47 @@
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
+ edited: "編輯于"
24
+ word_count:
25
+ one: "大約%d個字"
26
+ other: "大約%d個字"
27
+ licensing:
28
+ author: "作者"
29
+ created_at: "發表於"
30
+ updated_at: "更新於"
31
+ licensed_under: "許可協議"
32
+ plugin:
33
+ visit_count: "%s次訪問"
34
+ visitor_count: "共%s個訪客"
35
+ cookie_consent:
36
+ message: 此網站使用Cookie來改善您的體驗。
37
+ dismiss: 知道了!
38
+ allow: 允許使用Cookie
39
+ deny: 拒絕
40
+ link: 了解更多
41
+ policy: Cookie政策
42
+ search:
43
+ search: "搜尋"
44
+ hint: "請輸入關鍵字..."
45
+ no_result: "未找到搜索結果"
46
+ untitled: "(無標題)"
47
+ empty_preview: "(無內容預覽)"
@@ -0,0 +1,118 @@
1
+ const moment = require("moment");
2
+ const { Component, Fragment } = require("../include/util/common");
3
+ const { toMomentLocale } = require("hexo/dist/plugins/helper/date");
4
+ const Paginator = require("./misc/paginator");
5
+ const ArticleMedia = require("./common/article_media");
6
+
7
+ module.exports = class extends Component {
8
+ render() {
9
+ const { config, page, helper } = this.props;
10
+ const { url_for, __, date_xml, date } = helper;
11
+
12
+ const language = toMomentLocale(
13
+ page.lang || page.language || config.language,
14
+ );
15
+ const timelineCss = `
16
+ span.year {
17
+ position: absolute;
18
+ top: 1.5rem;
19
+ right: 1.5rem;
20
+ z-index: 0;
21
+ font-size: 7.5rem;
22
+ font-weight: bolder;
23
+ font-family: Paris2024;
24
+ color: hsl(from var(--mauve) h s l / 0.15);
25
+ line-height: 1;
26
+ user-select: none;
27
+ }
28
+ .timeline .archive-item {
29
+ display: flex;
30
+ text-align: left;
31
+ align-items: flex-start;
32
+ }
33
+ .timeline .archive-item a {
34
+ color: var(--text);
35
+ transition: color 0.2s;
36
+ }
37
+ .timeline .archive-item a:hover {
38
+ color: var(--peach);
39
+ }
40
+ .archive-item + .archive-item {
41
+ border: none;
42
+ margin-top: 0;
43
+ padding-top: 1rem;
44
+ }
45
+ `;
46
+ function renderArticleList(posts, year, month = null) {
47
+ const time = moment(
48
+ [page.year, page.month ? page.month - 1 : null].filter(
49
+ (i) => i !== null,
50
+ ),
51
+ );
52
+ return (
53
+ <div class="card">
54
+ <div class="card-content">
55
+ <span class="year">
56
+ {month === null
57
+ ? year
58
+ : time.locale(language).format("MMMM YYYY")}
59
+ </span>
60
+ <div class="timeline">
61
+ {posts.map((post) => {
62
+ const categories = post.categories.map((category) => ({
63
+ url: url_for(category.path),
64
+ name: category.name,
65
+ }));
66
+ return (
67
+ <ArticleMedia
68
+ url={url_for(post.link || post.path)}
69
+ title={post.title}
70
+ date={date(post.date)}
71
+ dateXml={date_xml(post.date)}
72
+ categories={categories}
73
+ />
74
+ );
75
+ })}
76
+ </div>
77
+ </div>
78
+ </div>
79
+ );
80
+ }
81
+
82
+ let articleList;
83
+ if (!page.year) {
84
+ const years = {};
85
+ page.posts.each((p) => {
86
+ years[p.date.year()] = null;
87
+ });
88
+ articleList = Object.keys(years)
89
+ .sort((a, b) => b - a)
90
+ .map((year) => {
91
+ const posts = page.posts.filter(
92
+ (p) => p.date.year() === parseInt(year, 10),
93
+ );
94
+ return renderArticleList(posts, year, null);
95
+ });
96
+ } else {
97
+ articleList = renderArticleList(page.posts, page.year, page.month);
98
+ }
99
+
100
+ return (
101
+ <Fragment>
102
+ <style dangerouslySetInnerHTML={{ __html: timelineCss }}></style>
103
+ {articleList}
104
+ {page.total > 1 ? (
105
+ <Paginator
106
+ current={page.current}
107
+ total={page.total}
108
+ baseUrl={page.base}
109
+ path={config.pagination_dir}
110
+ urlFor={url_for}
111
+ prevTitle={__("common.prev")}
112
+ nextTitle={__("common.next")}
113
+ />
114
+ ) : null}
115
+ </Fragment>
116
+ );
117
+ }
118
+ };
@@ -0,0 +1,137 @@
1
+ const { Component, cacheComponent } = require("../include/util/common");
2
+
3
+ class Categories extends Component {
4
+ renderList(categories, showCount) {
5
+ return categories.map((category) => (
6
+ <li>
7
+ <a
8
+ class={`level is-mobile${category.isCurrent ? " is-active" : ""}`}
9
+ href={category.url}
10
+ >
11
+ <span class="level-start">
12
+ <span class="level-item">{category.name}</span>
13
+ </span>
14
+ {showCount ? (
15
+ <span class="level-end">
16
+ <span class="level-item" style="font-family: monospace">
17
+ {category.count}
18
+ </span>
19
+ </span>
20
+ ) : null}
21
+ </a>
22
+ {category.children.length ? (
23
+ <ul>{this.renderList(category.children, false)}</ul>
24
+ ) : null}
25
+ </li>
26
+ ));
27
+ }
28
+
29
+ render() {
30
+ const { showCount, categories } = this.props;
31
+ const categoriesListCSS = `
32
+ .card-content a {
33
+ padding: 0.5em 0.75em;
34
+ color: var(--text);
35
+ }
36
+ .card-content a.level:hover {
37
+ background-color: var(--base);
38
+ }
39
+ .card-content li ul {
40
+ border-left: 1px solid var(--surface0);
41
+ margin: 0.75em;
42
+ padding-left: 0.75em;
43
+ }`;
44
+ return (
45
+ <div class="card widget" data-type="categories">
46
+ <style>{categoriesListCSS}</style>
47
+ <div class="card-content">
48
+ <ul>{this.renderList(categories, showCount)}</ul>
49
+ </div>
50
+ </div>
51
+ );
52
+ }
53
+ }
54
+
55
+ Categories.Cacheable = cacheComponent(
56
+ Categories,
57
+ "widget.categories",
58
+ (props) => {
59
+ const { page, helper, widget = {} } = props;
60
+ const {
61
+ categories = props.site.categories,
62
+ orderBy = "name",
63
+ order = 1,
64
+ showCurrent = false,
65
+ showCount = true,
66
+ } = widget;
67
+ const { url_for, _p } = helper;
68
+
69
+ if (!categories || !categories.length) {
70
+ return null;
71
+ }
72
+
73
+ let depth = 0;
74
+ try {
75
+ depth = parseInt(props.depth, 10);
76
+ } catch (_e) {}
77
+
78
+ function prepareQuery(parent) {
79
+ const query = {};
80
+
81
+ if (parent) {
82
+ query.parent = parent;
83
+ } else {
84
+ query.parent = { $exists: false };
85
+ }
86
+
87
+ return categories
88
+ .find(query)
89
+ .sort(orderBy, order)
90
+ .filter((cat) => cat.length);
91
+ }
92
+
93
+ function hierarchicalList(level, parent) {
94
+ return prepareQuery(parent).map((cat, _) => {
95
+ let children = [];
96
+ if (!depth || level + 1 < depth) {
97
+ children = hierarchicalList(level + 1, cat._id);
98
+ }
99
+
100
+ let isCurrent = false;
101
+ if (showCurrent && page) {
102
+ for (let j = 0; j < cat.length; j++) {
103
+ const post = cat.posts.data[j];
104
+ if (post && post._id === page._id) {
105
+ isCurrent = true;
106
+ break;
107
+ }
108
+ }
109
+ // special case: category page
110
+ isCurrent = isCurrent || page.base?.startsWith(cat.path);
111
+ }
112
+
113
+ return {
114
+ children,
115
+ isCurrent,
116
+ name: cat.name,
117
+ count: cat.length,
118
+ url: url_for(cat.path),
119
+ };
120
+ });
121
+ }
122
+
123
+ return {
124
+ showCount,
125
+ categories: hierarchicalList(0),
126
+ title: _p("common.category", Infinity),
127
+ };
128
+ },
129
+ );
130
+
131
+ module.exports = class extends Component {
132
+ render() {
133
+ const { site, page, helper } = this.props;
134
+
135
+ return <Categories.Cacheable site={site} page={page} helper={helper} />;
136
+ }
137
+ };
@@ -0,0 +1,38 @@
1
+ const { Component, Fragment } = require("../include/util/common");
2
+ const Index = require("./index");
3
+
4
+ module.exports = class extends Component {
5
+ render() {
6
+ const { config, page, helper } = this.props;
7
+ const { url_for, _p } = helper;
8
+
9
+ return (
10
+ <Fragment>
11
+ <nav class="breadcrumb" aria-label="breadcrumbs">
12
+ <ul>
13
+ <li>
14
+ {" "}
15
+ <font style="color: var(--green)">$</font>&nbsp;ls&nbsp;
16
+ <a href={url_for("/categories/")}>
17
+ {_p("common.category", Infinity)}
18
+ </a>
19
+ </li>
20
+ {page.parents.map((category) => {
21
+ return (
22
+ <li>
23
+ <a href={url_for(category.path)}>{category.name}</a>
24
+ </li>
25
+ );
26
+ })}
27
+ <li class="is-active">
28
+ <a href="#" aria-current="page">
29
+ {page.category}
30
+ </a>
31
+ </li>
32
+ </ul>
33
+ </nav>
34
+ <Index config={config} page={page} helper={helper} />
35
+ </Fragment>
36
+ );
37
+ }
38
+ };
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Disqus comment JSX component.
3
+ * @module view/comment/disqus
4
+ */
5
+ const { Component, cacheComponent } = require("../../include/util/common");
6
+ /**
7
+ * Disqus comment JSX component.
8
+ *
9
+ * @see https://disqus.com/admin/install/platforms/universalcode/
10
+ * @example
11
+ * <Disqus
12
+ * shortname="******"
13
+ * disqusId="******"
14
+ * permalink="/page/permanent/path"
15
+ * path="/path/to/page" />
16
+ */
17
+ class Disqus extends Component {
18
+ render() {
19
+ const { shortname, disqusId, path, permalink } = this.props;
20
+ if (!shortname) {
21
+ return (
22
+ <div class="notification is-danger">
23
+ You forgot to set the <code>shortname</code> for Disqus. Please set it
24
+ in <code>_config.yml</code>.
25
+ </div>
26
+ );
27
+ }
28
+ const js = `var disqus_config = function () {
29
+ this.page.url = '${permalink}';
30
+ this.page.identifier = '${disqusId || path}';
31
+ };
32
+ (function() {
33
+ var d = document, s = d.createElement('script');
34
+ s.src = '//' + '${shortname}' + '.disqus.com/embed.js';
35
+ s.setAttribute('data-timestamp', +new Date());
36
+ (d.head || d.body).appendChild(s);
37
+ })();`;
38
+ return (
39
+ <>
40
+ <div id="disqus_thread">
41
+ <noscript>
42
+ Please enable JavaScript to view the{" "}
43
+ <a href="//disqus.com/?ref_noscript">comments powered by Disqus.</a>
44
+ </noscript>
45
+ </div>
46
+ <script dangerouslySetInnerHTML={{ __html: js }}></script>
47
+ </>
48
+ );
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Cacheable Disqus comment JSX component.
54
+ * <p>
55
+ * This class is supposed to be used in combination with the <code>locals</code> hexo filter
56
+ * ({@link module:hexo/filter/locals}).
57
+ *
58
+ * @see module:util/cache.cacheComponent
59
+ * @example
60
+ * <Disqus.Cacheable
61
+ * comment={{ shortname: '*******' }}
62
+ * page={{
63
+ * path: '/path/to/page',
64
+ * disqusId: '******',
65
+ * permalink: '/page/permanent/link'
66
+ * }} />
67
+ */
68
+ Disqus.Cacheable = cacheComponent(Disqus, "comment.disqus", (props) => {
69
+ const { comment, page } = props;
70
+
71
+ return {
72
+ path: page.path,
73
+ shortname: comment.shortname,
74
+ disqusId: page.disqusId,
75
+ permalink: page.permalink,
76
+ };
77
+ });
78
+
79
+ module.exports = Disqus;
@@ -0,0 +1,127 @@
1
+ /**
2
+ * DisqusJS comment JSX component.
3
+ * @module view/comment/disqusjs
4
+ */
5
+ const { Component, cacheComponent } = require("../../include/util/common");
6
+ /**
7
+ * DisqusJS comment JSX component.
8
+ *
9
+ * @see https://github.com/SukkaW/DisqusJS
10
+ * @example
11
+ * <DisqusJs
12
+ * shortname="******"
13
+ * apiKey="******"
14
+ * api="******"
15
+ * admin="******"
16
+ * adminLabel={false}
17
+ * nesting={4}
18
+ * disqusId="******"
19
+ * path="/path/to/page"
20
+ * permalink="/page/permanent/path"
21
+ * pageTitle="******"
22
+ * siteTitle="******"
23
+ * jsUrl="/path/to/disqus.js"
24
+ * cssUrl="/path/to/disqusjs.css" />
25
+ */
26
+ class DisqusJs extends Component {
27
+ render() {
28
+ const {
29
+ shortname,
30
+ apiKey,
31
+ api,
32
+ admin,
33
+ adminLabel,
34
+ nesting,
35
+ disqusId,
36
+ path,
37
+ permalink,
38
+ pageTitle,
39
+ siteTitle,
40
+ jsUrl,
41
+ cssUrl,
42
+ } = this.props;
43
+ if (!shortname) {
44
+ return (
45
+ <div class="notification is-danger">
46
+ You forgot to set the <code>shortname</code> or <code>api_key</code>{" "}
47
+ for Disqus. Please set it in <code>_config.yml</code>.
48
+ </div>
49
+ );
50
+ }
51
+ const url = permalink || path;
52
+ const identifier = disqusId || path;
53
+ const js = `new DisqusJS({
54
+ shortname: '${shortname}',
55
+ apikey: ${JSON.stringify(apiKey)},
56
+ ${siteTitle ? `siteName: ${JSON.stringify(siteTitle)},` : ""}
57
+ ${identifier ? `identifier: ${JSON.stringify(identifier)},` : ""}
58
+ ${url ? `url: ${JSON.stringify(url)},` : ""}
59
+ ${pageTitle ? `title: ${JSON.stringify(pageTitle)},` : ""}
60
+ ${api ? `api: ${JSON.stringify(api)},` : ""}
61
+ ${admin ? `admin: ${JSON.stringify(admin)},` : ""}
62
+ ${adminLabel ? `adminLabel: ${JSON.stringify(adminLabel)},` : ""}
63
+ ${nesting ? `nesting: ${JSON.stringify(nesting)},` : ""}
64
+ });`;
65
+ return (
66
+ <>
67
+ <link rel="stylesheet" href={cssUrl} />
68
+ <div id="disqus_thread">
69
+ <noscript>
70
+ Please enable JavaScript to view the{" "}
71
+ <a href="//disqus.com/?ref_noscript">comments powered by Disqus.</a>
72
+ </noscript>
73
+ </div>
74
+ <script src={jsUrl}></script>
75
+ <script dangerouslySetInnerHTML={{ __html: js }}></script>
76
+ </>
77
+ );
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Cacheable DisqusJS comment JSX component.
83
+ * <p>
84
+ * This class is supposed to be used in combination with the <code>locals</code> hexo filter
85
+ * ({@link module:hexo/filter/locals}).
86
+ *
87
+ * @see module:util/cache.cacheComponent
88
+ * @example
89
+ * <DisqusJs.Cacheable
90
+ * comment={{
91
+ * shortname: '******',
92
+ * api_key: '******',
93
+ * api: '******',
94
+ * admin: '******',
95
+ * admin_label: false,
96
+ * nesting: 4
97
+ * }}
98
+ * page={{
99
+ * path: '/path/to/page',
100
+ * disqusId: '******',
101
+ * permalink: '******'
102
+ * title: '******'
103
+ * }}
104
+ * config={{ title: '******' }}
105
+ * helper={{ cdn: function() { ... } }} />
106
+ */
107
+ DisqusJs.Cacheable = cacheComponent(DisqusJs, "comment.disqusjs", (props) => {
108
+ const { config, page, helper, comment } = props;
109
+
110
+ return {
111
+ path: page.path,
112
+ shortname: comment.shortname,
113
+ apiKey: comment.api_key,
114
+ api: comment.api,
115
+ admin: comment.admin,
116
+ adminLabel: comment.admin_label,
117
+ nesting: comment.nesting,
118
+ disqusId: page.disqusId,
119
+ permalink: page.permalink,
120
+ pageTitle: page.title,
121
+ siteTitle: config.title,
122
+ jsUrl: helper.cdn("disqusjs", "1.3.0", "dist/disqus.js"),
123
+ cssUrl: helper.cdn("disqusjs", "1.3.0", "dist/disqusjs.css"),
124
+ };
125
+ });
126
+
127
+ module.exports = DisqusJs;