hexo-theme-particlex 2.5.7 → 2.5.9

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -8,15 +8,15 @@
8
8
 
9
9
  > 目前有 Full、Night 和 Maiden **两个**主题样式
10
10
 
11
- 虽然更改后只有一种了,如果你想改颜色就在 `particlex.css` 里 `Ctrl+F` 替换吧
11
+ 虽然更改后只有一种了,如果你想改颜色就在 `main.css` 里替换吧
12
12
 
13
- ## 演示
13
+ # 1. 演示
14
14
 
15
15
  - [GitHub Pages](https://argvchs.github.io)
16
16
  - [Netlify](https://argvchs.netlify.app)
17
17
  - [Vercel](https://argvchs.vercel.app)
18
18
 
19
- ## 安装
19
+ # 2. 安装
20
20
 
21
21
  ```bash
22
22
  cd themes
@@ -29,319 +29,325 @@ git clone https://github.com/argvchs/hexo-theme-particlex.git particlex --depth=
29
29
  theme: particlex
30
30
  ```
31
31
 
32
- - 关闭自带 Highlight
32
+ ## 2.1. 关闭自带代码高亮
33
33
 
34
- Hexo 有自带的 Highlight,但是和 ParticleX 的 Highlight 不兼容
34
+ Hexo 有自带的代码高亮,但是和 ParticleX 的不兼容
35
35
 
36
- ```yaml
37
- highlight:
38
- enable: false
39
- prismjs:
40
- enable: false
41
- ```
36
+ ```yaml
37
+ highlight:
38
+ enable: false
39
+ prismjs:
40
+ enable: false
41
+ ```
42
42
 
43
- 如果使用 Pandoc 还需要设置一下
43
+ 如果使用 Pandoc 还需要设置一下
44
44
 
45
- ```yaml
46
- pandoc:
47
- extra:
48
- - no-highlight:
49
- ```
45
+ ```yaml
46
+ pandoc:
47
+ extra:
48
+ - no-highlight:
49
+ ```
50
50
 
51
- - 禁用年度月度归档
51
+ ## 2.2. 禁用年度月度归档
52
52
 
53
- Hexo 会自动生成年度月度归档,可是 ParticleX 主题没有这个功能 ~~我太懒了~~
53
+ Hexo 会自动生成年度月度归档,可是 ParticleX 主题没有这个功能 ~~我太懒了~~
54
54
 
55
- ```yaml
56
- archive_generator:
57
- enabled: true
58
- per_page: 0
59
- yearly: false
60
- monthly: false
61
- daily: false
62
- ```
55
+ ```yaml
56
+ archive_generator:
57
+ enabled: true
58
+ per_page: 0
59
+ yearly: false
60
+ monthly: false
61
+ daily: false
62
+ ```
63
63
 
64
64
  修改完请 `hexo cl` 清除缓存
65
65
 
66
- ## 配置
66
+ # 3. 配置
67
+
68
+ ## 3.1. 基本配置
67
69
 
68
70
  ```yaml
69
71
  # Avatar image
70
72
  avatar: /images/avatar.jpg
71
73
 
72
- # Home page info block
73
- headBlockEnable: true
74
-
75
74
  # Home page background image
76
- background: /images/background.jpg
75
+ background:
76
+ - /images/background.jpg
77
77
  ```
78
78
 
79
- 其中 Background 可以是一个列表,打开时会随机加载一个背景
80
-
81
- - 导航栏
82
-
83
- 为了方便,主题使用的图标是 Font Awesome 6 图标
84
-
85
- ```yaml
86
- # ParticleX theme icon is adopts the Font Awesome 6
87
- # https://fontawesome.com
88
-
89
- # Main menu navigation
90
- menu:
91
- Home:
92
- name: house
93
- theme: solid
94
- link: /
95
- About:
96
- name: id-card
97
- theme: solid
98
- link: /about
99
- Archives:
100
- name: box-archive
101
- theme: solid
102
- link: /archives
103
- Categories:
104
- name: bookmark
105
- theme: solid
106
- link: /categories
107
- Tags:
108
- name: tags
109
- theme: solid
110
- link: /tags
111
- ```
112
-
113
- - 主页信息卡片
114
-
115
- `description` 支持 Markdown 格式
116
-
117
- 图标链接配置和导航栏配置相同
118
-
119
- **如果图标链接或友链为空,请在 `iconLinks:` 或 `friendLinks:` 后添加一个 `{}`**
120
-
121
- ```yaml
122
- # Side info card
123
- card:
124
- enable: true
125
- description: |
126
- Description
127
- ...
128
- iconLinks:
129
- {}
130
- friendLinks:
131
- Argvchs: https://argvchs.netlify.app
132
- ```
133
-
134
- - 页脚
135
-
136
- 考虑到博客部署在服务器并使用自己域名的情况,按规定需要在网站下边添加备案消息
137
-
138
- 如没有需要显示备案消息的可以关闭
139
-
140
- ```yaml
141
- # Footer info
142
- footer:
143
- since: 2022
144
- # Customize the server domain name ICP
145
- ICP:
146
- enable: false
147
- code:
148
- link:
149
- ```
150
-
151
- - Polyfill
152
-
153
- 使用 [Polyfill.io](https://polyfill.io) 自动根据 UA 处理新的 JS API 兼容
154
-
155
- 可以配合 [Hexo-Babel](https://github.com/argvchs/hexo-babel) 插件处理 JS 语法兼容
156
-
157
- ```yaml
158
- # Polyfill
159
- # https://polyfill.io
160
- polyfill:
161
- enable: true
162
- features:
163
- - default
164
- ```
165
-
166
- - 代码高亮
167
-
168
- 使用 Highlight.js 代码高亮
169
-
170
- 样式可以在[这里](https://highlightjs.org/static/demo)选择,默认为 GitHub
171
-
172
- ```yaml
173
- # Highlight.js
174
- # https://highlightjs.org
175
- highlight:
176
- enable: true
177
- style: github
178
- ```
179
-
180
- - 数学渲染
181
-
182
- 使用 KaTeX 渲染数学公式
183
-
184
- ```yaml
185
- # Rendering math with KaTeX
186
- math:
187
- enable: false
188
- ```
79
+ 其中 Background 是一个列表,打开时会随机加载一个背景
189
80
 
190
- - 图片预览
81
+ ## 3.2. 内容配置
191
82
 
192
- 简单的点击图片放大缩小的预览
83
+ ### 3.2.1. 导航栏
193
84
 
194
- ```yaml
195
- # Image Preview
196
- preview:
197
- enable: true
198
- ```
85
+ 为了方便,主题使用的图标是 Font Awesome 6 图标
199
86
 
200
- - 文章缩略
87
+ ```yaml
88
+ # ParticleX theme icon is adopts the Font Awesome 6
89
+ # https://fontawesome.com
90
+
91
+ # Main menu navigation
92
+ menu:
93
+ Home:
94
+ name: house
95
+ theme: solid
96
+ link: /
97
+ About:
98
+ name: id-card
99
+ theme: solid
100
+ link: /about
101
+ Archives:
102
+ name: box-archive
103
+ theme: solid
104
+ link: /archives
105
+ Categories:
106
+ name: bookmark
107
+ theme: solid
108
+ link: /categories
109
+ Tags:
110
+ name: tags
111
+ theme: solid
112
+ link: /tags
113
+ ```
201
114
 
202
- 一般来说,缩略展示文档只需要在文档中添加 `<!-- more -->` 即可,缩略内容在显示全文中也会出现
115
+ ### 3.2.2. 主页信息卡片
203
116
 
204
- 但考虑到不想把缩略内容放在正文里,就添加了此参数,在 [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置
117
+ `description` 支持 Markdown 格式
205
118
 
206
- 支持 Markdown 格式
119
+ 图标链接配置和导航栏配置相同
207
120
 
208
- ```yaml
209
- description: |
210
- Normal _Italic_ **Strong**
211
- ```
121
+ **如果图标链接或友链为空,请在 `iconLinks:` 或 `friendLinks:` 后添加一个 `{}`**
212
122
 
213
- - 文章置顶
123
+ ```yaml
124
+ # Side info card
125
+ card:
126
+ enable: true
127
+ description: |
128
+ Description
129
+ ...
130
+ iconLinks:
131
+ {}
132
+ friendLinks:
133
+ Argvchs: https://argvchs.netlify.app
134
+ ```
214
135
 
215
- [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置 `pinned` 作为置顶参数,越大越靠前,默认为 0
136
+ ### 3.2.3. 页脚
216
137
 
217
- - 文章加密
138
+ 考虑到博客部署在服务器并使用自己域名的情况,按规定需要在网站下边添加备案消息
218
139
 
219
- 使用 AES 加密算法,在 [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置 `secret` 作为密码,**使用请安装插件 [Hexo-Helper-Crypto](https://github.com/argvchs/hexo-helper-crypto)**
140
+ 如没有需要显示备案消息的可以关闭
220
141
 
221
- ```yaml
222
- # Article encryption
223
- crypto:
142
+ ```yaml
143
+ # Footer info
144
+ footer:
145
+ since: 2022
146
+ # Customize the server domain name ICP
147
+ ICP:
224
148
  enable: false
225
- ```
149
+ code:
150
+ link:
151
+ ```
226
152
 
227
- - 搜索
153
+ ## 3.3. 功能配置
228
154
 
229
- 嵌入到 Archives 中的搜索
155
+ ### 3.3.1. Polyfill
230
156
 
231
- 目前只支持搜索文档标题(我太弱了)
157
+ 使用 [Polyfill.io](https://polyfill.io) 自动根据 UA 处理新的 JS API 兼容
232
158
 
233
- ```yaml
234
- # Search
235
- search:
236
- enable: false
237
- ```
159
+ 可以配合 [Hexo-Babel](https://github.com/argvchs/hexo-babel) 插件处理 JS 语法兼容
238
160
 
239
- - Giscus
161
+ ```yaml
162
+ # Polyfill
163
+ # https://polyfill.io
164
+ polyfill:
165
+ enable: true
166
+ features:
167
+ - default
168
+ ```
240
169
 
241
- Giscus 是一个由 GitHub Discussions 支持的评论系统
170
+ ### 3.3.2. 代码高亮
242
171
 
243
- [Giscus.app](https://giscus.app) 设置好各项后,会在下面生成一个 `<script>` 标签,在主题内填入即可
172
+ 使用 Highlight.js 代码高亮
244
173
 
245
- ```yaml
246
- # Giscus
247
- # https://github.com/giscus/giscus
248
- giscus:
249
- enable: false
250
- src: https://giscus.app/client.js
251
- repo:
252
- repoID:
253
- category:
254
- categoryID:
255
- mapping: pathname
256
- strict: 0
257
- reactionsEnabled: 1
258
- emitMetadata: 0
259
- inputPosition: bottom
260
- theme: preferred_color_scheme
261
- lang: zh-CN
262
- ```
263
-
264
- - Gitalk
265
-
266
- Gitalk 是一个基于 GitHub Issue 和 Preact 的评论系统
267
-
268
- 考虑到博客可能部署到多个网站同步评论,但 OAuth APP 只能有一个回调 URL,所以添加了 `sites` 参数用于多个网站的评论
269
-
270
- **同样如果没有其他网站,请在 `sites:` 后添加一个 `{}`**
271
-
272
- 由于 Gitalk 官方 CORS 代理用的是 Cloudflare,速度过慢,添加了 `proxy` 参数,搭建 CORS 代理可以看[这篇文章](https://argvchs.github.io/2022/07/04/build-cors-anywhere)
273
-
274
- ```yaml
275
- # Gitalk
276
- # https://github.com/gitalk/gitalk
277
- gitalk:
278
- enable: false
279
- clientID: # Default ClientID
280
- clientSecret: # Default ClientSecret
281
- repo: # The name of repository of store comments
282
- owner: # GitHub repo owner
283
- admin: # GitHub repo owner and collaborators, only these guys can initialize github issues
284
- language: zh-CN # en, zh-CN, zh-TW, es-ES, fr, ru, de, pl and ko are currently available
285
- proxy: # CORS proxy
286
- sites: # Sites
287
- {}
288
- # www.example.com:
289
- # clientID:
290
- # clientSecret:
291
- ```
292
-
293
- - Waline
294
-
295
- Waline 是一个简单、安全的评论系统
296
-
297
- 详见:[在 ParticleX 上使用 Waline | Yuzi's Blog](https://blog.yuzi.dev/posts/bcb4ff00.html)
298
-
299
- **注意如果不需要 `locale` 参数,请在 `locale:` 后添加一个 `{}`**
300
-
301
- ```yaml
302
- # Waline
303
- # https://github.com/walinejs/waline
304
- waline:
305
- enable: false
306
- serverURL: # Waline server address url, you should set this to your own link
307
- locale: # Locale: https://waline.js.org/guide/client/i18n.html#locale-option
308
- {}
309
- commentCount: true # If false, comment count will only be displayed in post page, not in home page
310
- pageview: false # Pageviews count, Note: You should not enable both `waline.pageview` and `leancloud_visitors`
311
- emoji: # Custom emoji
312
- - https://unpkg.com/@waline/emojis@1.2.0/weibo
313
- - https://unpkg.com/@waline/emojis@1.2.0/alus
314
- - https://unpkg.com/@waline/emojis@1.2.0/bilibili
315
- - https://unpkg.com/@waline/emojis@1.2.0/qq
316
- - https://unpkg.com/@waline/emojis@1.2.0/tieba
317
- - https://unpkg.com/@waline/emojis@1.2.0/tw-emoji
318
- meta: # Comment information, valid meta are nick, mail and link
319
- - nick
320
- - mail
321
- - link
322
- requiredMeta: # Set required meta field, e.g.: [nick] | [nick, mail]
323
- - nick
324
- lang: zh-CN # Language, available values: en-US, zh-CN, zh-TW, pt-BR, ru-RU, jp-JP
325
- wordLimit: 0 # Word limit, no limit when setting to 0
326
- login: enable # Whether enable login, can choose from 'enable', 'disable' and 'force'
327
- pageSize: 10 # Comment per page
328
- ```
329
-
330
- - Twikoo
331
-
332
- Twikoo 是一个一个简洁、安全、免费的静态网站评论系统
333
-
334
- ```yaml
335
- # Twikoo
336
- # https://github.com/imaegoo/twikoo
337
- twikoo:
338
- enable: false
339
- envID:
340
- region:
341
- path: location.pathname
342
- lang: zh-CN
343
- ```
174
+ 样式可以在[这里](https://highlightjs.org/static/demo)选择,默认为 GitHub
175
+
176
+ ```yaml
177
+ # Highlight.js
178
+ # https://highlightjs.org
179
+ highlight:
180
+ enable: true
181
+ style: github
182
+ ```
183
+
184
+ ### 3.3.3. 数学渲染
185
+
186
+ 使用 KaTeX 渲染数学公式
187
+
188
+ ```yaml
189
+ # KaTeX math rendering
190
+ math:
191
+ enable: false
192
+ ```
193
+
194
+ ### 3.3.4. 图片预览
195
+
196
+ 简单的点击图片放大缩小的预览
197
+
198
+ ```yaml
199
+ # Image preview
200
+ preview:
201
+ enable: true
202
+ ```
203
+
204
+ ### 3.3.5. 文章缩略
205
+
206
+ 一般来说,缩略展示文档只需要在文档中添加 `<!-- more -->` 即可,缩略内容在显示全文中也会出现
207
+
208
+ 但考虑到不想把缩略内容放在正文里,就添加了此参数,在 [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置
209
+
210
+ 支持 Markdown 格式
211
+
212
+ ```yaml
213
+ description: |
214
+ Normal _Italic_ **Strong**
215
+ ```
216
+
217
+ ### 3.3.6. 文章置顶
218
+
219
+ 在 [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置 `pinned` 作为置顶参数,越大越靠前,默认为 0
220
+
221
+ ### 3.3.7. 文章加密
222
+
223
+ 使用 AES 加密算法,在 [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置 `secret` 作为密码,**使用请安装插件 [Hexo-Helper-Crypto](https://github.com/argvchs/hexo-helper-crypto)**
224
+
225
+ ```yaml
226
+ # Article encryption
227
+ crypto:
228
+ enable: false
229
+ ```
230
+
231
+ ### 3.3.8. 搜索
232
+
233
+ 嵌入到 Archives 中的搜索
234
+
235
+ 目前只支持搜索文档标题
236
+
237
+ ```yaml
238
+ # Search
239
+ search:
240
+ enable: false
241
+ ```
242
+
243
+ ## 3.4. 评论配置
244
+
245
+ ### 3.4.1. Giscus
246
+
247
+ Giscus 是一个由 GitHub Discussions 支持的评论系统
248
+
249
+ [Giscus.app](https://giscus.app) 设置好各项后,会在下面生成一个 `<script>` 标签,在主题内填入即可
250
+
251
+ ```yaml
252
+ # Giscus
253
+ # https://github.com/giscus/giscus
254
+ giscus:
255
+ enable: false
256
+ src: https://giscus.app/client.js
257
+ repo:
258
+ repoID:
259
+ category:
260
+ categoryID:
261
+ mapping: pathname
262
+ strict: 0
263
+ reactionsEnabled: 1
264
+ emitMetadata: 0
265
+ inputPosition: bottom
266
+ theme: preferred_color_scheme
267
+ lang: zh-CN
268
+ ```
269
+
270
+ ### 3.4.2. Gitalk
271
+
272
+ Gitalk 是一个基于 GitHub Issue 和 Preact 的评论系统
273
+
274
+ 考虑到博客可能部署到多个网站同步评论,但 OAuth APP 只能有一个回调 URL,所以添加了 `sites` 参数用于多个网站的评论
275
+
276
+ **同样如果没有其他网站,请在 `sites:` 后添加一个 `{}`**
277
+
278
+ 由于 Gitalk 官方 CORS 代理用的是 Cloudflare,速度过慢,添加了 `proxy` 参数,搭建 CORS 代理可以看[这篇文章](https://argvchs.netlify.app/2022/07/04/build-cors-anywhere)
279
+
280
+ ```yaml
281
+ # Gitalk
282
+ # https://github.com/gitalk/gitalk
283
+ gitalk:
284
+ enable: false
285
+ clientID: # Default ClientID
286
+ clientSecret: # Default ClientSecret
287
+ repo: # The name of repository of store comments
288
+ owner: # GitHub repo owner
289
+ admin: # GitHub repo owner and collaborators, only these guys can initialize github issues
290
+ language: zh-CN # en, zh-CN, zh-TW, es-ES, fr, ru, de, pl and ko are currently available
291
+ proxy: # CORS proxy
292
+ sites: # Sites
293
+ {}
294
+ # www.example.com:
295
+ # clientID:
296
+ # clientSecret:
297
+ ```
298
+
299
+ ### 3.4.3. Waline
300
+
301
+ Waline 是一个简单、安全的评论系统
302
+
303
+ 详见:[在 ParticleX 上使用 Waline | Yuzi's Blog](https://blog.yuzi.dev/posts/bcb4ff00.html)
304
+
305
+ **注意如果不需要 `locale` 参数,请在 `locale:` 后添加一个 `{}`**
306
+
307
+ ```yaml
308
+ # Waline
309
+ # https://github.com/walinejs/waline
310
+ waline:
311
+ enable: false
312
+ serverURL: # Waline server address url, you should set this to your own link
313
+ locale: # Locale: https://waline.js.org/guide/client/i18n.html#locale-option
314
+ {}
315
+ commentCount: true # If false, comment count will only be displayed in post page, not in home page
316
+ pageview: false # Pageviews count, Note: You should not enable both `waline.pageview` and `leancloud_visitors`
317
+ emoji: # Custom emoji
318
+ - https://unpkg.com/@waline/emojis@1.2.0/weibo
319
+ - https://unpkg.com/@waline/emojis@1.2.0/alus
320
+ - https://unpkg.com/@waline/emojis@1.2.0/bilibili
321
+ - https://unpkg.com/@waline/emojis@1.2.0/qq
322
+ - https://unpkg.com/@waline/emojis@1.2.0/tieba
323
+ - https://unpkg.com/@waline/emojis@1.2.0/tw-emoji
324
+ meta: # Comment information, valid meta are nick, mail and link
325
+ - nick
326
+ - mail
327
+ - link
328
+ requiredMeta: # Set required meta field, e.g.: [nick] | [nick, mail]
329
+ - nick
330
+ lang: zh-CN # Language, available values: en-US, zh-CN, zh-TW, pt-BR, ru-RU, jp-JP
331
+ wordLimit: 0 # Word limit, no limit when setting to 0
332
+ login: enable # Whether enable login, can choose from 'enable', 'disable' and 'force'
333
+ pageSize: 10 # Comment per page
334
+ ```
335
+
336
+ ### 3.4.4. Twikoo
337
+
338
+ Twikoo 是一个一个简洁、安全、免费的静态网站评论系统
339
+
340
+ ```yaml
341
+ # Twikoo
342
+ # https://github.com/imaegoo/twikoo
343
+ twikoo:
344
+ enable: false
345
+ envID:
346
+ region:
347
+ path: location.pathname
348
+ lang: zh-CN
349
+ ```
344
350
 
345
- ## 写在最后
351
+ # 4. 写在最后
346
352
 
347
353
  本项目采用 MIT 开源许可证,欢迎大家贡献,你可以随意打开一个 Issue 来进行提问,有任何改进想法都可以进行 Fork,期待您的 Pull Request!
package/_config.yml CHANGED
@@ -4,11 +4,9 @@
4
4
  # Avatar image
5
5
  avatar: /images/avatar.jpg
6
6
 
7
- # Home page info block
8
- headBlockEnable: true
9
-
10
7
  # Home page background image
11
- background: /images/background.jpg
8
+ background:
9
+ - /images/background.jpg
12
10
 
13
11
  # ParticleX theme icon is adopts the Font Awesome 6
14
12
  # https://fontawesome.com
@@ -69,11 +67,11 @@ highlight:
69
67
  enable: true
70
68
  style: github
71
69
 
72
- # Rendering math with KaTeX
70
+ # KaTeX math rendering
73
71
  math:
74
72
  enable: false
75
73
 
76
- # Image Preview
74
+ # Image preview
77
75
  preview:
78
76
  enable: true
79
77
 
package/layout/card.ejs CHANGED
@@ -1,5 +1,5 @@
1
1
  <div id="card-div">
2
- <div class="card-style" style="width: 300px">
2
+ <div class="card-style">
3
3
  <div class="avatar">
4
4
  <img src="<%- url_for(theme.avatar) %>" alt="avatar" />
5
5
  </div>
@@ -18,7 +18,7 @@
18
18
  <% } %>
19
19
  <% if (theme.gitalk.enable) { %>
20
20
  <script>
21
- (function () {
21
+ (() => {
22
22
  let clientID = "<%- theme.gitalk.clientID %>",
23
23
  clientSecret = "<%- theme.gitalk.clientSecret %>";
24
24
  <% Object.keys(theme.gitalk.sites).forEach(key => { %>
package/layout/index.ejs CHANGED
@@ -1,6 +1,9 @@
1
1
  <div id="home-head">
2
- <div id="home-background" ref="homeBackground" data-image="<%- url_for(theme.background) %>"></div>
3
- <% if (theme.headBlockEnable) { %>
2
+ <div
3
+ id="home-background"
4
+ ref="homeBackground"
5
+ data-images="<%- theme.background.map(i => url_for(i)) %>"
6
+ ></div>
4
7
  <div id="home-info" @click="homeClick">
5
8
  <span class="loop"></span>
6
9
  <span class="loop"></span>
@@ -14,14 +17,11 @@
14
17
  </div>
15
18
  </span>
16
19
  </div>
17
- <% } %>
18
20
  </div>
19
21
  <div id="home-posts-wrap" <%- theme.card.enable ? "" : 'class="home-posts-wrap-no-card"' %> ref="homePostsWrap">
20
22
  <div id="home-posts">
21
- <div id="posts">
22
- <%- partial("posts") %>
23
- <%- partial("current") %>
24
- </div>
23
+ <%- partial("posts") %>
24
+ <%- partial("current") %>
25
25
  </div>
26
26
  <% if (theme.card.enable) { %>
27
27
  <div id="home-card">
package/layout/layout.ejs CHANGED
@@ -1,25 +1,16 @@
1
1
  <%
2
- let type = "post";
3
- if (is_home())
4
- type = "index";
5
- else if (is_post())
6
- type = "post";
7
- else if (is_category() || page.type === "categories")
8
- type = "categories";
9
- else if (is_tag() || page.type === "tags")
10
- type = "tags";
11
- else if (is_archive())
12
- type = "archives";
13
- let title = "";
14
- if (page.title)
15
- title = page.title + " | ";
16
- else if (is_category())
17
- title = "Categories: " + page.category + " | ";
18
- else if (is_tag())
19
- title = "Tags: " + page.tag + " | ";
20
- else if (is_archive())
21
- title = "Archives | ";
22
- title += config.title;
2
+ let type;
3
+ if (is_home()) type = "index";
4
+ if (is_post() || is_page()) type = "post";
5
+ if (is_category() || page.type === "categories") type = "categories";
6
+ if (is_tag() || page.type === "tags") type = "tags";
7
+ if (is_archive()) type = "archives";
8
+ let title;
9
+ if (is_home()) title = config.title;
10
+ if (is_post() || is_page()) title = page.title + " | " + config.title;
11
+ if (is_category()) title = "Categories: " + page.category + " | " + config.title;
12
+ if (is_tag()) title = "Tags: " + page.tag + " | " + config.title;
13
+ if (is_archive()) title = "Archives | " + config.title;
23
14
  %>
24
15
  <!DOCTYPE html>
25
16
  <html lang="<%- config.language %>">
@@ -39,14 +30,14 @@
39
30
  <div id="loading" v-show="loading">
40
31
  <div id="loading-circle">
41
32
  <h2>LOADING</h2>
42
- <p>加载过慢请开启缓存&ensp;浏览器默认开启</p>
33
+ <p>加载过慢请开启缓存 浏览器默认开启</p>
43
34
  <img src="<%- url_for("/images/loading.gif") %>" />
44
35
  </div>
45
36
  </div>
46
37
  </transition>
38
+ <%- partial("menu") %>
47
39
  <transition name="into">
48
40
  <div id="main" v-show="!loading">
49
- <%- partial("menu") %>
50
41
  <%- partial(type) %>
51
42
  <%- partial("footer") %>
52
43
  </div>
package/layout/menu.ejs CHANGED
@@ -1,4 +1,4 @@
1
- <nav id="menu" ref="menu">
1
+ <nav id="menu" :class="{ hidden: hiddenMenu, 'menu-color': menuColor}">
2
2
  <div class="desktop-menu">
3
3
  <a class="title" href="<%- config.root %>">
4
4
  <span><%= config.title.toUpperCase() %></span>
@@ -11,13 +11,13 @@
11
11
  <% }); %>
12
12
  </div>
13
13
  <div id="mobile-menu">
14
- <div class="curtain" v-show="showMenu" @click="showMenu = !showMenu"></div>
15
- <div class="title" @click="showMenu = !showMenu">
14
+ <div class="curtain" @click="shouMenuItems = !shouMenuItems" v-show="shouMenuItems"></div>
15
+ <div class="title" @click="shouMenuItems = !shouMenuItems">
16
16
  <i class="fa-solid fa-bars fa-fw"></i>
17
17
  <span>&emsp;<%= config.title.toUpperCase() %></span>
18
18
  </div>
19
19
  <transition name="slide">
20
- <div class="items" v-show="showMenu">
20
+ <div class="items" v-show="shouMenuItems">
21
21
  <% Object.keys(theme.menu).forEach(key => { %>
22
22
  <a href="<%- url_for(theme.menu[key].link) %>">
23
23
  <div class="item">
package/layout/post.ejs CHANGED
@@ -43,26 +43,19 @@
43
43
  <% } %>
44
44
  </div>
45
45
  <% if (theme.crypto.enable && typeof page.secret !== "undefined") { %>
46
- <%
47
- const CryptoJS = crypto();
48
- function SHA(word) {
49
- return CryptoJS.SHA256(word).toString();
50
- }
51
- function encrypt(word, secret) {
52
- return CryptoJS.AES.encrypt(word, secret).toString();
53
- }
54
- %>
46
+ <% const CryptoJS = crypto(); %>
55
47
  <input
56
48
  id="crypto"
57
- class="input"
49
+ :class="['input', cryptoClass]"
50
+ :disabled="check"
58
51
  ref="crypto"
59
52
  placeholder="文章被加密,请输入密码"
60
- data-encrypted="<%- encrypt(page.content, page.secret) %>"
61
- data-shasum="<%- SHA(page.content) %>"
53
+ data-encrypted="<%- CryptoJS.AES.encrypt(page.content, page.secret).toString() %>"
54
+ data-shasum="<%- CryptoJS.SHA256(page.content).toString() %>"
62
55
  v-model="crypto"
63
56
  />
64
57
  <transition name="fade">
65
- <div class="content" ref="content" v-show="check"></div>
58
+ <div class="content" ref="content" v-html="decrypted" v-show="check"></div>
66
59
  </transition>
67
60
  <% } else { %>
68
61
  <div class="content" v-pre>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-particlex",
3
- "version": "2.5.7",
3
+ "version": "2.5.9",
4
4
  "description": "A concise Hexo theme, based on Particle.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "homepage": "https://github.com/argvchs/hexo-theme-particlex#readme",
23
23
  "dependencies": {
24
- "hexo-helper-crypto": "^1.1.0",
24
+ "hexo-helper-crypto": "^1.1.2",
25
25
  "hexo-renderer-ejs": "^2.0.0"
26
26
  },
27
27
  "scripts": {
@@ -92,6 +92,7 @@
92
92
  box-shadow: 0 0 20px #d9d9d980;
93
93
  padding: 25px 0;
94
94
  text-align: center;
95
+ width: 300px;
95
96
  }
96
97
  #home-card .card-style .avatar {
97
98
  border: #f1f1f1 solid 3px;
@@ -360,11 +361,11 @@
360
361
  height: 50vmin;
361
362
  justify-content: center;
362
363
  padding: 50px;
364
+ text-align: center;
363
365
  width: 50vmin;
364
366
  }
365
367
  #main {
366
368
  margin-right: calc(100% - 100vw);
367
- overflow: auto;
368
369
  }
369
370
  #menu {
370
371
  background: #92cafa;
@@ -488,6 +489,7 @@
488
489
  line-height: 2;
489
490
  overflow: auto;
490
491
  padding: 50px 30px 20px;
492
+ white-space: pre;
491
493
  }
492
494
  .comment iframe,
493
495
  body::-webkit-scrollbar-track {
@@ -504,24 +506,24 @@ body::-webkit-scrollbar-track {
504
506
  margin: 15px auto;
505
507
  max-width: 75%;
506
508
  }
507
- .code-copy {
509
+ .copycode {
508
510
  color: #5c6b72;
509
511
  position: absolute;
510
512
  right: 0;
511
513
  top: 0;
512
514
  }
513
- .code-copy i {
515
+ .copycode i {
514
516
  padding: 15px;
515
517
  position: absolute;
516
518
  right: 0;
517
519
  top: 0;
518
520
  transition: transform 0.25s;
519
521
  }
520
- .code-copy.copied i {
522
+ .copycode.copied i {
521
523
  transform: scale(1.25);
522
524
  }
523
- .code-copy.copied i:first-child,
524
- .code-copy:not(.copied) i:last-child {
525
+ .copycode.copied i:first-child,
526
+ .copycode:not(.copied) i:last-child {
525
527
  opacity: 0;
526
528
  }
527
529
  .fade-enter-active,
@@ -658,7 +660,7 @@ a {
658
660
  text-decoration: none;
659
661
  }
660
662
  a:hover,
661
- .content .code-copy:hover {
663
+ .content .copycode:hover {
662
664
  opacity: 0.8;
663
665
  }
664
666
  b,
@@ -694,13 +696,12 @@ iframe,
694
696
  .friend-link a,
695
697
  .icon-link a,
696
698
  .language,
697
- .code-copy {
699
+ .copycode {
698
700
  user-select: none;
699
701
  }
700
702
  code {
701
703
  background: #bddcf76b;
702
704
  border-radius: 4px;
703
- font-size: 14px;
704
705
  line-height: 2.5;
705
706
  padding: 4px 8px;
706
707
  }
@@ -764,6 +765,7 @@ pre {
764
765
  box-shadow: 0 2px 12px 0 #0000001a;
765
766
  margin: 25px 0;
766
767
  margin: 25px 0;
768
+ white-space: normal;
767
769
  }
768
770
  pre,
769
771
  code,
@@ -824,9 +826,6 @@ ol li {
824
826
  }
825
827
  }
826
828
  @media (min-width: 900px) {
827
- #home-card {
828
- margin-right: auto;
829
- }
830
829
  #home-head #home-info .info .wrap {
831
830
  padding: 25px;
832
831
  }
@@ -855,9 +854,8 @@ ol li {
855
854
  width: 500px;
856
855
  }
857
856
  #home-posts {
858
- margin-left: auto;
859
857
  margin-right: 50px;
860
- width: 900px;
858
+ width: 850px;
861
859
  }
862
860
  #home-posts .post {
863
861
  margin-bottom: 25px;
@@ -867,8 +865,7 @@ ol li {
867
865
  padding: 20px 0;
868
866
  }
869
867
  #home-posts-wrap {
870
- max-width: 1150px;
871
- padding: 30px 0;
868
+ max-width: 1200px;
872
869
  }
873
870
  #menu .desktop-menu {
874
871
  display: block;
@@ -894,7 +891,6 @@ ol li {
894
891
  display: none;
895
892
  }
896
893
  #home-posts {
897
- margin: auto;
898
894
  width: 100%;
899
895
  }
900
896
  #home-posts-wrap,
@@ -2,40 +2,31 @@ mixins.crypto = {
2
2
  data() {
3
3
  return {
4
4
  crypto: "",
5
- check: false,
5
+ check: null,
6
6
  };
7
7
  },
8
- methods: {
9
- SHA(word) {
10
- return CryptoJS.SHA256(word).toString();
11
- },
12
- decrypt(word, secret, shasum) {
8
+ watch: {
9
+ crypto(value) {
10
+ let input = this.$refs.crypto,
11
+ content = this.$refs.content;
12
+ let { encrypted, shasum } = input.dataset;
13
13
  try {
14
- let res = CryptoJS.AES.decrypt(word, secret).toString(CryptoJS.enc.Utf8);
15
- return { check: this.SHA(res) === shasum, decrypted: res };
14
+ let decrypted = CryptoJS.AES.decrypt(encrypted, value).toString(CryptoJS.enc.Utf8);
15
+ if (CryptoJS.SHA256(decrypted).toString() === shasum) {
16
+ this.check = true;
17
+ content.innerHTML = decrypted;
18
+ this.render();
19
+ } else this.check = false;
16
20
  } catch {
17
- return { check: false };
21
+ this.check = false;
18
22
  }
19
23
  },
20
24
  },
21
- watch: {
22
- crypto(value) {
23
- let input = this.$refs.crypto,
24
- content = this.$refs.content;
25
- let { decrypted, check } = this.decrypt(
26
- input.dataset.encrypted,
27
- value,
28
- input.dataset.shasum
29
- );
30
- this.check = check;
31
- if (check) {
32
- input.classList.remove("fail");
33
- input.classList.add("success");
34
- input.disabled = true;
35
- content.innerHTML = decrypted;
36
- this.render();
37
- } else input.classList.add("fail");
25
+ computed: {
26
+ cryptoClass() {
27
+ if (this.check === null) return "";
28
+ if (this.check === true) return "success";
29
+ if (this.check === false) return "fail";
38
30
  },
39
31
  },
40
32
  };
41
- mixins.push(cryptoMixin);
@@ -10,24 +10,29 @@ mixins.highlight = {
10
10
  },
11
11
  methods: {
12
12
  highlight() {
13
- let that = this;
14
13
  let codes = document.querySelectorAll("pre");
15
14
  for (let i of codes) {
16
- let lang = [...i.classList, ...i.firstChild.classList][0] || "plaintext";
17
15
  let code = i.innerText;
18
- i.innerHTML = `<div class="code-content">${code}</div><div class="language">${lang}</div><div class="code-copy"><i class="fa-solid fa-copy fa-fw"></i><i class="fa-solid fa-clone fa-fw"></i></div>`;
19
- let copy = i.querySelector(".code-copy");
20
- copy.addEventListener("click", async function () {
21
- if (that.copying) return;
22
- that.copying = true;
23
- this.classList.add("copied");
16
+ let language = [...i.classList, ...i.firstChild.classList][0] || "plaintext";
17
+ let highlighted = hljs.highlight(code, { language }).value;
18
+ i.innerHTML = `
19
+ <div class="code-content">${highlighted}</div>
20
+ <div class="language">${language}</div>
21
+ <div class="copycode">
22
+ <i class="fa-solid fa-copy fa-fw"></i>
23
+ <i class="fa-solid fa-clone fa-fw"></i>
24
+ </div>
25
+ `;
26
+ let copycode = i.querySelector(".copycode");
27
+ copycode.addEventListener("click", async () => {
28
+ if (this.copying) return;
29
+ this.copying = true;
30
+ copycode.classList.add("copied");
24
31
  await navigator.clipboard.writeText(code);
25
32
  await new Promise(resolve => setTimeout(resolve, 1000));
26
- this.classList.remove("copied");
27
- that.copying = false;
33
+ copycode.classList.remove("copied");
34
+ this.copying = false;
28
35
  });
29
- let content = i.querySelector(".code-content");
30
- hljs.highlightElement(content);
31
36
  }
32
37
  },
33
38
  },
@@ -1,11 +1,10 @@
1
1
  mixins.home = {
2
2
  mounted() {
3
- let menu = this.$refs.menu,
4
- background = this.$refs.homeBackground;
5
- menu.classList.add("menu-color");
6
- let image = background.dataset.image.split(",");
7
- let id = Math.floor(Math.random() * image.length);
8
- background.style.backgroundImage = `url('${image[id]}')`;
3
+ let background = this.$refs.homeBackground;
4
+ let images = background.dataset.images.split(",");
5
+ let id = Math.floor(Math.random() * images.length);
6
+ background.style.backgroundImage = `url('${images[id]}')`;
7
+ this.menuColor = true;
9
8
  },
10
9
  methods: {
11
10
  homeClick() {
@@ -9,15 +9,14 @@ mixins.preview = {
9
9
  },
10
10
  methods: {
11
11
  preview() {
12
- let that = this;
13
12
  let preview = this.$refs.preview,
14
13
  content = this.$refs.previewContent;
15
14
  let images = document.querySelectorAll("img");
16
15
  for (let i of images)
17
- i.addEventListener("click", function () {
18
- content.alt = this.alt;
19
- content.src = this.src;
20
- that.previewShow = true;
16
+ i.addEventListener("click", () => {
17
+ content.alt = i.alt;
18
+ content.src = i.src;
19
+ this.previewShow = true;
21
20
  });
22
21
  preview.addEventListener("click", () => {
23
22
  this.previewShow = false;
package/source/js/main.js CHANGED
@@ -3,8 +3,10 @@ const app = Vue.createApp({
3
3
  data() {
4
4
  return {
5
5
  loading: true,
6
- showMenu: false,
7
- barLocal: 0,
6
+ hiddenMenu: false,
7
+ showMenuItems: false,
8
+ menuColor: false,
9
+ scrollTop: 0,
8
10
  renderers: [],
9
11
  };
10
12
  },
@@ -23,20 +25,19 @@ const app = Vue.createApp({
23
25
  for (let i of this.renderers) i();
24
26
  },
25
27
  handleScroll() {
26
- let menu = this.$refs.menu,
27
- wrap = this.$refs.homePostsWrap;
28
- let newlocal = document.documentElement.scrollTop;
29
- if (this.barLocal < newlocal) {
30
- this.showMenu = false;
31
- menu.classList.add("hidden");
32
- } else menu.classList.remove("hidden");
28
+ let wrap = this.$refs.homePostsWrap;
29
+ let newScrollTop = document.documentElement.scrollTop;
30
+ if (this.scrollTop < newScrollTop) {
31
+ this.hiddenMenu = true;
32
+ this.showMenuItems = false;
33
+ } else this.hiddenMenu = false;
33
34
  if (wrap) {
34
- if (newlocal <= window.innerHeight - 100) menu.classList.add("menu-color");
35
- else menu.classList.remove("menu-color");
36
- if (newlocal <= 400) wrap.style.marginTop = -newlocal / 5 + "px";
35
+ if (newScrollTop <= window.innerHeight - 100) this.menuColor = true;
36
+ else this.menuColor = false;
37
+ if (newScrollTop <= 400) wrap.style.marginTop = -newScrollTop / 5 + "px";
37
38
  else wrap.style.marginTop = "-80px";
38
39
  }
39
- this.barLocal = newlocal;
40
+ this.scrollTop = newScrollTop;
40
41
  },
41
42
  },
42
43
  });