hexo-theme-stellar 2.0.0-rc.1 → 2.0.0-rc.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/CHANGELOG.md +24 -0
- package/README.md +54 -62
- package/README_EN.md +62 -39
- package/_config.yml +65 -58
- package/assets/icon-v2-x512.webp +0 -0
- package/layout/404.ejs +4 -1
- package/layout/_partial/head.ejs +5 -5
- package/layout/_partial/primitives/shell.ejs +1 -0
- package/layout/_partial/scripts/runtime.ejs +4 -0
- package/layout/_partial/widgets/tagtree.ejs +1 -1
- package/layout/layout.ejs +5 -2
- package/layout/settings.ejs +1 -1
- package/package.json +14 -4
- package/scripts/generators/notebooks.js +2 -2
- package/scripts/lib/brand.js +2 -2
- package/scripts/lib/content-defaults.js +8 -4
- package/scripts/lib/contribution-registry.js +1 -1
- package/scripts/lib/models/index.js +8 -4
- package/scripts/schema/config-rules.js +13 -11
- package/scripts/schema/config-schema.js +2 -1
- package/scripts/schema/content-config-rules.js +2 -0
- package/scripts/schema/model-schema.js +14 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.0-rc.2
|
|
4
|
+
|
|
5
|
+
> 发布日期:2026-09-07
|
|
6
|
+
|
|
7
|
+
本节记录从公开候选 `2.0.0-rc.1` 到 `2.0.0-rc.2` 最终文件树的净变化。
|
|
8
|
+
|
|
9
|
+
### 新功能
|
|
10
|
+
|
|
11
|
+
- Notebook 列表、设置页与错误页的专属配置统一收敛到 `profiles`;404 页新增默认关闭的评论区,可独立覆盖标题、线程、Provider 与参数。
|
|
12
|
+
- 可信页面注入补全 `head_begin/head_end/body_begin/body_end` 四个位置,站点主题配置与页面 Front Matter 使用同一合并顺序和原样输出语义。
|
|
13
|
+
|
|
14
|
+
### 修复与工程变化
|
|
15
|
+
|
|
16
|
+
- 将 `hexo-front-matter` 声明为主题直接依赖,避免源码配置与 `stellar new note` 依赖 Hexo 宿主的传递依赖。
|
|
17
|
+
- 重构中英文 README,明确 npm、源码与 Blueprint 三种安装入口,并补充随 npm 包分发的 Stellar 图标、项目描述、关键词和作者元数据。
|
|
18
|
+
|
|
19
|
+
### 升级注意(配置变更与破坏性改动)
|
|
20
|
+
|
|
21
|
+
- 从 RC1 升级时,将顶层 `notebook` 移到 `profiles.notebook`,将 `settings.about` 移到 `profiles.settings.about`,将 `error_page.image` 移到 `profiles.error.image`。
|
|
22
|
+
- `profiles.notebook_index` 更名为 `profiles.notebooks`,`profiles.note_index` 更名为 `profiles.notebook`;Note 内容页继续使用 `profiles.note`。
|
|
23
|
+
- `inject` 内容会作为可信 HTML 原样输出;只应配置维护者完全信任的内容,站点级内容在前、页面 Front Matter 在后。
|
|
24
|
+
|
|
25
|
+
Full Changelog: [2.0.0-rc.1...2.0.0-rc.2](https://github.com/xaoxuu/hexo-theme-stellar/compare/2.0.0-rc.1...2.0.0-rc.2)
|
|
26
|
+
|
|
3
27
|
## 2.0.0-rc.1
|
|
4
28
|
|
|
5
29
|
> 发布日期:2026-09-07
|
package/README.md
CHANGED
|
@@ -1,81 +1,87 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="assets/icon-v2-x512.webp" width="160" alt="Stellar">
|
|
3
|
+
<h1>Stellar</h1>
|
|
4
|
+
<p>每个人的独立博客</p>
|
|
5
|
+
<p>基于 Hexo 的全能个人知识库,开箱即用,内置海量标签和动态数据组件。可用于个人博客、项目文档、知识库、专栏、笔记等。</p>
|
|
6
|
+
<p><a href="README.md">简体中文</a> · <a href="README_EN.md">English</a></p>
|
|
7
|
+
<p>
|
|
8
|
+
<a href="https://github.com/xaoxuu/hexo-theme-stellar/releases"><img src="https://img.shields.io/github/v/release/xaoxuu/hexo-theme-stellar" alt="release"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/hexo-theme-stellar"><img src="https://img.shields.io/npm/v/hexo-theme-stellar" alt="npm"></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/hexo-theme-stellar"><img src="https://img.shields.io/npm/dm/hexo-theme-stellar" alt="npm downloads"></a>
|
|
11
|
+
<a href="https://github.com/xaoxuu/hexo-theme-stellar"><img src="https://img.shields.io/github/stars/xaoxuu/hexo-theme-stellar" alt="stars"></a>
|
|
12
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/xaoxuu/hexo-theme-stellar" alt="license"></a>
|
|
13
|
+
</p>
|
|
14
|
+
<p>
|
|
15
|
+
<a href="https://xaoxuu.com/wiki/stellar/start/install/">创建第一个博客</a> ·
|
|
16
|
+
<a href="https://xaoxuu.com/wiki/stellar/support/examples/">站点示例</a> ·
|
|
17
|
+
<a href="https://xaoxuu.com/wiki/stellar/">完整文档</a>
|
|
18
|
+
</p>
|
|
19
|
+
</div>
|
|
2
20
|
|
|
3
|
-
|
|
21
|
+
## 在纷繁中建立秩序
|
|
4
22
|
|
|
5
|
-
|
|
23
|
+
> 真正的简约不止删繁就简,而是在纷繁中建立秩序。
|
|
6
24
|
|
|
7
|
-
|
|
25
|
+
### 完善的内容组织体系
|
|
8
26
|
|
|
9
|
-
|
|
27
|
+
从普通文章开始。项目需要稳定的文档目录时,用 Wiki;文章逐渐形成系列时,收进专栏;零散知识需要长期积累时,放进笔记本。它们共享同一套导航、搜索、侧栏与阅读体验,没有启用的内容系统不会增加额外负担。
|
|
10
28
|
|
|
11
|
-
|
|
29
|
+
### 灵活的排版与表达方式
|
|
12
30
|
|
|
13
|
-
|
|
14
|
-
[](https://github.com/xaoxuu/hexo-theme-stellar/blob/main/LICENSE)
|
|
15
|
-
[](https://github.com/xaoxuu/hexo-theme-stellar)
|
|
16
|
-
[](https://www.npmjs.com/package/hexo-theme-stellar)
|
|
17
|
-
[](https://github.com/xaoxuu/hexo-theme-stellar/releases)
|
|
31
|
+
从外观预设、配色和字体,到分栏、选项卡、折叠块与图库,站点的样子和内容的表达方式都可以按需组合。本地搜索可以直接定位到相关章节,响应式布局会在窄屏上把主要空间留给正文。
|
|
18
32
|
|
|
19
|
-
|
|
33
|
+
### 静态页面,也能常看常新
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
手写内容沉淀观点,外部数据保持新鲜。远程内容、社区数据和外部服务可以按需加载,与静态正文保持解耦;经常变化的数据不必每次都随整站重新生成。
|
|
22
36
|
|
|
23
|
-
|
|
37
|
+
## 站点示例
|
|
24
38
|
|
|
25
|
-
|
|
39
|
+
[Stellar Examples](https://github.com/xaoxuu/hexo-theme-stellar-examples/) 提供可以直接运行的示例站,适合先体验接近自己目标的站点,再逐步替换内容与配置。更多真实站点见[站点示例](https://xaoxuu.com/wiki/stellar/support/examples/)。
|
|
26
40
|
|
|
27
|
-
|
|
41
|
+
## 开始使用
|
|
28
42
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
## 写作、检索和阅读是一件事
|
|
32
|
-
|
|
33
|
-
提示框、折叠、标签页、图库、时间线、聊天和表格等内容组件可以互相组合。Markdown 表达不够时,不需要临时拼一套风格各异的插件。
|
|
34
|
-
|
|
35
|
-
本地搜索由主题生成索引,结果可以直接落到文章章节;桌面端目录和信息栏到了手机上会变成抽屉,把位置让给正文。
|
|
43
|
+
### 环境要求
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
- Node.js 22 或更高版本
|
|
46
|
+
- Hexo 8 或更高版本
|
|
38
47
|
|
|
39
|
-
|
|
48
|
+
### 从蓝图创建
|
|
40
49
|
|
|
41
|
-
|
|
50
|
+
准备好 Git 和 npm 后,一条命令即可启动交互式蓝图安装器:
|
|
42
51
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
| 星迹 · Blog | 使用经典侧栏整理文章、分类与专栏 |
|
|
47
|
-
| 个人知识库 · Knowledge | 把博客、项目资料和长期主题放在一起 |
|
|
48
|
-
| 项目文档 · Docs | 给一个项目维护清晰的文档目录 |
|
|
52
|
+
```bash
|
|
53
|
+
sh -c "$(curl -fsSL https://github.com/xaoxuu/hexo-theme-stellar-examples/raw/main/install.sh)"
|
|
54
|
+
```
|
|
49
55
|
|
|
50
|
-
|
|
56
|
+
安装器会读取示例仓库的 [`blueprints.json`](https://github.com/xaoxuu/hexo-theme-stellar-examples/blob/main/blueprints.json),展示当前可用的蓝图,并依次确认蓝图、项目目录、依赖安装和创建计划。
|
|
51
57
|
|
|
52
|
-
|
|
58
|
+
### 从 npm 安装
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
在博客根目录安装 npm 当前提供的默认版本,并确认实际安装结果:
|
|
55
61
|
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
hexo-
|
|
59
|
-
node: '>= 22'
|
|
60
|
-
npm: '>= 10'
|
|
62
|
+
```bash
|
|
63
|
+
npm install hexo-theme-stellar
|
|
64
|
+
npm ls hexo-theme-stellar
|
|
61
65
|
```
|
|
62
66
|
|
|
63
|
-
###
|
|
67
|
+
### 跟随最新源码
|
|
64
68
|
|
|
65
|
-
|
|
69
|
+
将官方仓库的 `main` 分支添加为子模块,并安装主题自身的依赖:
|
|
66
70
|
|
|
67
71
|
```bash
|
|
68
72
|
git submodule add -b main https://github.com/xaoxuu/hexo-theme-stellar.git themes/stellar
|
|
69
73
|
npm install --prefix themes/stellar
|
|
70
74
|
```
|
|
71
75
|
|
|
72
|
-
|
|
76
|
+
### 启用并检查
|
|
77
|
+
|
|
78
|
+
在博客 `_config.yml` 中启用主题:
|
|
73
79
|
|
|
74
80
|
```yaml
|
|
75
81
|
theme: stellar
|
|
76
82
|
```
|
|
77
83
|
|
|
78
|
-
|
|
84
|
+
然后运行 Doctor 并生成站点:
|
|
79
85
|
|
|
80
86
|
```bash
|
|
81
87
|
npx hexo stellar doctor
|
|
@@ -84,29 +90,15 @@ npx hexo generate
|
|
|
84
90
|
|
|
85
91
|
完整步骤见[环境与安装](https://xaoxuu.com/wiki/stellar/start/install/)和[创建第一个站点](https://xaoxuu.com/wiki/stellar/start/first-site/)。
|
|
86
92
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
npm install hexo-theme-stellar
|
|
91
|
-
```
|
|
93
|
+
## 文档与社区
|
|
92
94
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
- [从第一篇文章开始](https://xaoxuu.com/wiki/stellar/start/first-site/)
|
|
98
|
-
- [把博客变成自己的样子](https://xaoxuu.com/wiki/stellar/start/configuration/)
|
|
99
|
-
- [用 Wiki 写项目文档](https://xaoxuu.com/wiki/stellar/guides/wiki/)
|
|
100
|
-
- [把文章整理成专栏](https://xaoxuu.com/wiki/stellar/guides/topic/)
|
|
101
|
-
- [建立自己的笔记本](https://xaoxuu.com/wiki/stellar/guides/notebook/)
|
|
95
|
+
- [配置自己的站点](https://xaoxuu.com/wiki/stellar/start/configuration/)
|
|
96
|
+
- [使用内容组件](https://xaoxuu.com/wiki/stellar/reference/tags/)
|
|
97
|
+
- [管理 Wiki、专栏与笔记本](https://xaoxuu.com/wiki/stellar/reference/collection/)
|
|
102
98
|
- [主题配置参考](https://xaoxuu.com/wiki/stellar/reference/theme/)
|
|
103
99
|
- [从 v1 迁移到 v2](https://xaoxuu.com/wiki/stellar/migration/v1-to-v2/)
|
|
104
|
-
|
|
105
|
-
## 社区
|
|
106
|
-
|
|
107
100
|
- [Issues](https://github.com/xaoxuu/hexo-theme-stellar/issues/):反馈可以复现的问题
|
|
108
101
|
- [Discussions](https://github.com/xaoxuu/hexo-theme-stellar/discussions/):交流使用经验和想法
|
|
109
|
-
- [蓝图与展示墙](https://xaoxuu.com/wiki/stellar/support/examples/):看看不同的人怎样使用 Stellar
|
|
110
102
|
- [贡献指南](CONTRIBUTING.md):参与主题开发与文档维护
|
|
111
103
|
|
|
112
104
|
## 开源许可
|
package/README_EN.md
CHANGED
|
@@ -1,79 +1,102 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="assets/icon-v2-x512.webp" width="160" alt="Stellar">
|
|
3
|
+
<h1>Stellar</h1>
|
|
4
|
+
<p>A blog that grows with your work</p>
|
|
5
|
+
<p>A complete, versatile, and feature-rich personal knowledge base designed to grow over time.</p>
|
|
6
|
+
<p><a href="README_EN.md">English</a> · <a href="README.md">简体中文</a></p>
|
|
7
|
+
<p>
|
|
8
|
+
<a href="https://github.com/xaoxuu/hexo-theme-stellar/releases"><img src="https://img.shields.io/github/v/release/xaoxuu/hexo-theme-stellar" alt="release"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/hexo-theme-stellar"><img src="https://img.shields.io/npm/v/hexo-theme-stellar" alt="npm"></a>
|
|
10
|
+
<a href="https://www.npmjs.com/package/hexo-theme-stellar"><img src="https://img.shields.io/npm/dm/hexo-theme-stellar" alt="npm downloads"></a>
|
|
11
|
+
<a href="https://github.com/xaoxuu/hexo-theme-stellar"><img src="https://img.shields.io/github/stars/xaoxuu/hexo-theme-stellar" alt="stars"></a>
|
|
12
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/xaoxuu/hexo-theme-stellar" alt="license"></a>
|
|
13
|
+
</p>
|
|
14
|
+
<p>
|
|
15
|
+
<a href="https://xaoxuu.com/wiki/stellar/start/install/">Create your first blog</a> ·
|
|
16
|
+
<a href="https://xaoxuu.com/wiki/stellar/support/examples/">Site examples</a> ·
|
|
17
|
+
<a href="https://xaoxuu.com/wiki/stellar/">Documentation</a>
|
|
18
|
+
</p>
|
|
19
|
+
</div>
|
|
2
20
|
|
|
3
|
-
|
|
21
|
+
## Bring order to everything you publish
|
|
4
22
|
|
|
5
|
-
|
|
23
|
+
> True simplicity is not just subtraction; it is creating order within complexity.
|
|
6
24
|
|
|
7
|
-
|
|
25
|
+
### A complete system for organizing content
|
|
8
26
|
|
|
9
|
-
|
|
27
|
+
Start with regular posts. Give a project its own Wiki when it needs stable documentation, collect related posts into a Topic, and keep evolving knowledge in a Notebook. They share the same navigation, search, sidebars, and reading experience, while unused content systems stay out of the way.
|
|
10
28
|
|
|
11
|
-
|
|
12
|
-
[](https://github.com/xaoxuu/hexo-theme-stellar/blob/main/LICENSE)
|
|
13
|
-
[](https://github.com/xaoxuu/hexo-theme-stellar)
|
|
14
|
-
[](https://www.npmjs.com/package/hexo-theme-stellar)
|
|
29
|
+
### Flexible layout and expression
|
|
15
30
|
|
|
16
|
-
|
|
31
|
+
From appearance presets, colors, and type to columns, tabs, folding sections, and galleries, you can shape both the site and the way its content is presented. Local search can take readers directly to a matching section, while responsive layouts leave the main space to the article on narrow screens.
|
|
17
32
|
|
|
18
|
-
|
|
33
|
+
### Static pages that stay fresh
|
|
19
34
|
|
|
20
|
-
|
|
35
|
+
Your writing preserves ideas while external data stays current. Remote content, community data, and external services can load on demand without being coupled to the static article, so frequently changing data does not require a full-site rebuild.
|
|
21
36
|
|
|
22
|
-
##
|
|
37
|
+
## Site examples
|
|
23
38
|
|
|
24
|
-
|
|
39
|
+
[Stellar Examples](https://github.com/xaoxuu/hexo-theme-stellar-examples/) provides runnable sites you can explore before replacing their content and configuration at your own pace. Visit [Site examples](https://xaoxuu.com/wiki/stellar/support/examples/) for more real sites.
|
|
25
40
|
|
|
26
|
-
|
|
41
|
+
## Get started
|
|
27
42
|
|
|
28
|
-
|
|
43
|
+
### Requirements
|
|
29
44
|
|
|
30
|
-
|
|
45
|
+
- Node.js 22 or newer
|
|
46
|
+
- Hexo 8 or newer
|
|
31
47
|
|
|
32
|
-
|
|
48
|
+
### Create from a Blueprint
|
|
33
49
|
|
|
34
|
-
|
|
35
|
-
| --- | --- |
|
|
36
|
-
| Light Blog | Essays, personal notes, and distraction-free reading |
|
|
37
|
-
| Blog | A classic sidebar blog with categories and series |
|
|
38
|
-
| Knowledge | A personal site combining articles and long-lived knowledge |
|
|
39
|
-
| Docs | Documentation for a single project |
|
|
50
|
+
With Git and npm available, launch the interactive Blueprint installer with one command:
|
|
40
51
|
|
|
41
|
-
|
|
52
|
+
```bash
|
|
53
|
+
sh -c "$(curl -fsSL https://github.com/xaoxuu/hexo-theme-stellar-examples/raw/main/install.sh)"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The installer reads the example repository's [`blueprints.json`](https://github.com/xaoxuu/hexo-theme-stellar-examples/blob/main/blueprints.json), presents the available Blueprints, then confirms the Blueprint, project directory, dependency installation, and creation plan.
|
|
57
|
+
|
|
58
|
+
### Install from npm
|
|
59
|
+
|
|
60
|
+
Install the default version currently provided by npm, then confirm what was installed:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install hexo-theme-stellar
|
|
64
|
+
npm ls hexo-theme-stellar
|
|
65
|
+
```
|
|
42
66
|
|
|
43
|
-
|
|
67
|
+
### Follow the latest source
|
|
44
68
|
|
|
45
|
-
|
|
69
|
+
Add the official repository's `main` branch as a submodule and install the theme's own dependencies:
|
|
46
70
|
|
|
47
71
|
```bash
|
|
48
72
|
git submodule add -b main https://github.com/xaoxuu/hexo-theme-stellar.git themes/stellar
|
|
49
73
|
npm install --prefix themes/stellar
|
|
50
74
|
```
|
|
51
75
|
|
|
52
|
-
Enable
|
|
76
|
+
### Enable and check
|
|
77
|
+
|
|
78
|
+
Enable the theme in your site's `_config.yml`:
|
|
53
79
|
|
|
54
80
|
```yaml
|
|
55
81
|
theme: stellar
|
|
56
82
|
```
|
|
57
83
|
|
|
58
|
-
Then
|
|
84
|
+
Then run Doctor and generate the site:
|
|
59
85
|
|
|
60
86
|
```bash
|
|
61
87
|
npx hexo stellar doctor
|
|
62
88
|
npx hexo generate
|
|
63
89
|
```
|
|
64
90
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
## Stable npm release
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
npm install hexo-theme-stellar
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
This command may still install v1. Run `npm ls hexo-theme-stellar` before using any v2 configuration.
|
|
91
|
+
See [Installation](https://xaoxuu.com/wiki/stellar/start/install/) and [Create your first site](https://xaoxuu.com/wiki/stellar/start/first-site/) for the complete workflow.
|
|
74
92
|
|
|
75
|
-
##
|
|
93
|
+
## Documentation and community
|
|
76
94
|
|
|
95
|
+
- [Configure your site](https://xaoxuu.com/wiki/stellar/start/configuration/)
|
|
96
|
+
- [Use content components](https://xaoxuu.com/wiki/stellar/reference/tags/)
|
|
97
|
+
- [Manage Wikis, Topics, and Notebooks](https://xaoxuu.com/wiki/stellar/reference/collection/)
|
|
98
|
+
- [Theme configuration reference](https://xaoxuu.com/wiki/stellar/reference/theme/)
|
|
99
|
+
- [Migrate from v1 to v2](https://xaoxuu.com/wiki/stellar/migration/v1-to-v2/)
|
|
77
100
|
- [Issues](https://github.com/xaoxuu/hexo-theme-stellar/issues/) for reproducible problems
|
|
78
101
|
- [Discussions](https://github.com/xaoxuu/hexo-theme-stellar/discussions/) for ideas and usage questions
|
|
79
102
|
- [Contributing](CONTRIBUTING.md) for code and documentation work
|
package/_config.yml
CHANGED
|
@@ -133,7 +133,7 @@ footer:
|
|
|
133
133
|
# 设置主内容区页脚导航分栏;空数组表示不显示分栏。
|
|
134
134
|
sections: []
|
|
135
135
|
|
|
136
|
-
#
|
|
136
|
+
# 配置各页面与内容 Profile 的专属设置、路由、导航和 Region 默认值;省略字段时继承站点级 Region。
|
|
137
137
|
profiles:
|
|
138
138
|
# 配置主页默认布局。
|
|
139
139
|
home:
|
|
@@ -265,8 +265,37 @@ profiles:
|
|
|
265
265
|
- ghrepo
|
|
266
266
|
- toc
|
|
267
267
|
|
|
268
|
+
# 配置单个 Notebook Collection 与列表页。
|
|
269
|
+
notebook:
|
|
270
|
+
# 设置 Notebook 列表页高亮的主菜单项;null 表示不高亮。
|
|
271
|
+
active_menu: null
|
|
272
|
+
# 配置 Notebook 列表页 Leftbar 覆盖项。
|
|
273
|
+
leftbar:
|
|
274
|
+
# 设置 Notebook 列表页 Leftbar 内容 Widget;数组会整体替换站点级列表。
|
|
275
|
+
widgets:
|
|
276
|
+
- tagtree
|
|
277
|
+
- recent
|
|
278
|
+
# 配置 Notebook 列表页 Rightbar 覆盖项。
|
|
279
|
+
rightbar:
|
|
280
|
+
# 设置 Notebook 列表页 Rightbar Widget;空数组表示显式隐藏。
|
|
281
|
+
widgets: []
|
|
282
|
+
# 配置 Notebook 条目列表。
|
|
283
|
+
listing:
|
|
284
|
+
# 设置每页条目数;null 表示继承站点分页配置,0 表示禁用分页。
|
|
285
|
+
per_page: null
|
|
286
|
+
# 配置 Notebook 条目排序。
|
|
287
|
+
sort:
|
|
288
|
+
# 设置排序字段;可选值为 date、updated 或 title。
|
|
289
|
+
field: updated
|
|
290
|
+
# 设置排序方向;可选值为 asc 或 desc。
|
|
291
|
+
direction: desc
|
|
292
|
+
# 设置没有 excerpt 和 description 时的自动摘要最大字符数;0 表示不自动生成摘要。
|
|
293
|
+
excerpt_length: 128
|
|
294
|
+
# 配置 Notebook 标签对应的图标;空对象表示不指定图标。
|
|
295
|
+
tag_icons: {}
|
|
296
|
+
|
|
268
297
|
# 配置 Notebook 总索引页默认布局。
|
|
269
|
-
|
|
298
|
+
notebooks:
|
|
270
299
|
# 设置 Notebook 总索引页的自动生成路径;null 表示不生成总索引页。
|
|
271
300
|
path: /notebooks/
|
|
272
301
|
# 设置 Notebook 总索引页高亮的主菜单项;null 表示不高亮。
|
|
@@ -281,21 +310,6 @@ profiles:
|
|
|
281
310
|
# 设置 Notebook 总索引页 Rightbar Widget;空数组表示显式隐藏。
|
|
282
311
|
widgets: []
|
|
283
312
|
|
|
284
|
-
# 配置 Notebook 列表页默认布局。
|
|
285
|
-
note_index:
|
|
286
|
-
# 设置 Notebook 列表页高亮的主菜单项;null 表示不高亮。
|
|
287
|
-
active_menu: null
|
|
288
|
-
# 配置 Notebook 列表页 Leftbar 覆盖项。
|
|
289
|
-
leftbar:
|
|
290
|
-
# 设置 Notebook 列表页 Leftbar 内容 Widget;数组会整体替换站点级列表。
|
|
291
|
-
widgets:
|
|
292
|
-
- tagtree
|
|
293
|
-
- recent
|
|
294
|
-
# 配置 Notebook 列表页 Rightbar 覆盖项。
|
|
295
|
-
rightbar:
|
|
296
|
-
# 设置 Notebook 列表页 Rightbar Widget;空数组表示显式隐藏。
|
|
297
|
-
widgets: []
|
|
298
|
-
|
|
299
313
|
# 配置 Notebook 内容页默认布局。
|
|
300
314
|
note:
|
|
301
315
|
# 设置 Notebook 内容页高亮的主菜单项;null 表示不高亮。
|
|
@@ -347,6 +361,22 @@ profiles:
|
|
|
347
361
|
settings:
|
|
348
362
|
# 设置设置页的生成路径。
|
|
349
363
|
path: /settings/
|
|
364
|
+
# 配置设置页的关于信息。
|
|
365
|
+
about:
|
|
366
|
+
# 设置关于信息条目;数组会整体替换。
|
|
367
|
+
items:
|
|
368
|
+
# 设置条目名称。
|
|
369
|
+
- key: 博客框架
|
|
370
|
+
# 设置条目内容,支持主题模板变量。
|
|
371
|
+
value: Hexo {hexo.version}
|
|
372
|
+
# 设置条目链接。
|
|
373
|
+
url: https://hexo.io/
|
|
374
|
+
# 设置条目名称。
|
|
375
|
+
- key: 主题版本
|
|
376
|
+
# 设置条目内容,支持主题模板变量。
|
|
377
|
+
value: Stellar {theme.version}
|
|
378
|
+
# 设置条目链接,支持主题模板变量。
|
|
379
|
+
url: '{theme.tree}'
|
|
350
380
|
# 设置设置页高亮的主菜单项;null 表示不高亮。
|
|
351
381
|
active_menu: null
|
|
352
382
|
# 配置设置页 Leftbar 覆盖项。
|
|
@@ -363,6 +393,20 @@ profiles:
|
|
|
363
393
|
error:
|
|
364
394
|
# 设置错误页的生成路径。
|
|
365
395
|
path: /404.html
|
|
396
|
+
# 设置错误页插图地址;null 表示不显示插图。
|
|
397
|
+
image: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/404/1c830bfcd517d.svg
|
|
398
|
+
# 配置错误页评论区。
|
|
399
|
+
comments:
|
|
400
|
+
# 控制是否显示错误页评论区。
|
|
401
|
+
enabled: false
|
|
402
|
+
# 设置错误页评论区标题;null 表示使用默认标题。
|
|
403
|
+
title: null
|
|
404
|
+
# 设置错误页评论线程标识;null 表示由页面上下文决定。
|
|
405
|
+
id: null
|
|
406
|
+
# 设置错误页专用评论 Provider;null 表示使用全局 Provider。
|
|
407
|
+
provider: null
|
|
408
|
+
# 设置错误页专用评论 Provider 参数;空对象表示不覆盖参数。
|
|
409
|
+
options: {}
|
|
366
410
|
# 设置错误页高亮的主菜单项;null 表示不高亮。
|
|
367
411
|
active_menu: post
|
|
368
412
|
# 配置错误页 Leftbar 覆盖项。
|
|
@@ -427,42 +471,6 @@ article:
|
|
|
427
471
|
# 控制文章页页脚是否显示标签。
|
|
428
472
|
show_tags: true
|
|
429
473
|
|
|
430
|
-
# 配置 Notebook 列表与内容页的展示行为。
|
|
431
|
-
notebook:
|
|
432
|
-
# 配置 Notebook 列表。
|
|
433
|
-
listing:
|
|
434
|
-
# 设置每页条目数;null 表示继承站点分页配置,0 表示禁用分页。
|
|
435
|
-
per_page: null
|
|
436
|
-
# 配置 Notebook 条目排序。
|
|
437
|
-
sort:
|
|
438
|
-
# 设置排序字段;可选值为 date、updated 或 title。
|
|
439
|
-
field: updated
|
|
440
|
-
# 设置排序方向;可选值为 asc 或 desc。
|
|
441
|
-
direction: desc
|
|
442
|
-
# 设置没有 excerpt 和 description 时的自动摘要最大字符数;0 表示不自动生成摘要。
|
|
443
|
-
excerpt_length: 128
|
|
444
|
-
# 配置 Notebook 标签对应的图标;空对象表示不指定图标。
|
|
445
|
-
tag_icons: {}
|
|
446
|
-
|
|
447
|
-
# 配置设置页内容。
|
|
448
|
-
settings:
|
|
449
|
-
# 配置设置页的关于信息。
|
|
450
|
-
about:
|
|
451
|
-
# 设置关于信息条目;数组会整体替换。
|
|
452
|
-
items:
|
|
453
|
-
# 设置条目名称。
|
|
454
|
-
- key: 博客框架
|
|
455
|
-
# 设置条目内容,支持主题模板变量。
|
|
456
|
-
value: Hexo {hexo.version}
|
|
457
|
-
# 设置条目链接。
|
|
458
|
-
url: https://hexo.io/
|
|
459
|
-
# 设置条目名称。
|
|
460
|
-
- key: 主题版本
|
|
461
|
-
# 设置条目内容,支持主题模板变量。
|
|
462
|
-
value: Stellar {theme.version}
|
|
463
|
-
# 设置条目链接,支持主题模板变量。
|
|
464
|
-
url: '{theme.tree}'
|
|
465
|
-
|
|
466
474
|
# -----------------------------------------------------------------------------
|
|
467
475
|
# 外观
|
|
468
476
|
# -----------------------------------------------------------------------------
|
|
@@ -893,11 +901,6 @@ fallbacks:
|
|
|
893
901
|
# 设置封面占位图地址。
|
|
894
902
|
cover: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/cover/76b86c0226ffd.svg
|
|
895
903
|
|
|
896
|
-
# 配置错误页资源。
|
|
897
|
-
error_page:
|
|
898
|
-
# 设置错误页插图地址;null 表示不显示插图。
|
|
899
|
-
image: https://gcore.jsdelivr.net/gh/cdn-x/placeholder@1.0.12/404/1c830bfcd517d.svg
|
|
900
|
-
|
|
901
904
|
# -----------------------------------------------------------------------------
|
|
902
905
|
# SEO
|
|
903
906
|
# -----------------------------------------------------------------------------
|
|
@@ -928,7 +931,11 @@ structured_data:
|
|
|
928
931
|
|
|
929
932
|
# 配置原样注入页面的可信内容。
|
|
930
933
|
inject:
|
|
934
|
+
# 设置注入到 <head> 后的内容;空字符串表示不注入。
|
|
935
|
+
head_begin: ''
|
|
931
936
|
# 设置注入到 </head> 前的内容;空字符串表示不注入。
|
|
932
937
|
head_end: ''
|
|
938
|
+
# 设置注入到 <body> 后的内容;空字符串表示不注入。
|
|
939
|
+
body_begin: ''
|
|
933
940
|
# 设置注入到 </body> 前的内容;空字符串表示不注入。
|
|
934
941
|
body_end: ''
|
|
Binary file
|
package/layout/404.ejs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<%
|
|
2
2
|
page.robots = 'none';
|
|
3
|
+
var errorProfile = stellar_config('profiles.error') || {}
|
|
4
|
+
var errorComments = comments_model(page, errorProfile.comments)
|
|
3
5
|
%>
|
|
4
6
|
<article class='md-text error-page'>
|
|
5
|
-
<% var errorImage =
|
|
7
|
+
<% var errorImage = errorProfile.image %>
|
|
6
8
|
<% if (errorImage) { %>
|
|
7
9
|
<h1><img id='error' src='<%- errorImage %>' alt='404'></h1>
|
|
8
10
|
<% } %>
|
|
@@ -17,3 +19,4 @@ page.robots = 'none';
|
|
|
17
19
|
<br><br>
|
|
18
20
|
<a class='button' id='back' href="<%- config.root %>"><%- __('page.error.action') %></a>
|
|
19
21
|
</article>
|
|
22
|
+
<%- partial('_partial/comments/layout', {comments: errorComments}) %>
|
package/layout/_partial/head.ejs
CHANGED
|
@@ -11,8 +11,7 @@ var stellarSeo = {
|
|
|
11
11
|
}
|
|
12
12
|
var stellarResources = {
|
|
13
13
|
preconnect: stellar_config('preconnect'),
|
|
14
|
-
fallbacks: stellar_config('fallbacks')
|
|
15
|
-
errorPage: stellar_config('errorPage')
|
|
14
|
+
fallbacks: stellar_config('fallbacks')
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
function generate_title() {
|
|
@@ -159,8 +158,8 @@ function preconnect() {
|
|
|
159
158
|
return el;
|
|
160
159
|
}
|
|
161
160
|
|
|
162
|
-
function custom_inject() {
|
|
163
|
-
return stellar_inject(
|
|
161
|
+
function custom_inject(kind) {
|
|
162
|
+
return stellar_inject(kind, pageRender ? pageRender.document[`${kind}Inject`] : pageConfig.inject?.[kind])
|
|
164
163
|
}
|
|
165
164
|
|
|
166
165
|
function generate_canonical() {
|
|
@@ -183,6 +182,7 @@ function generate_canonical() {
|
|
|
183
182
|
%>
|
|
184
183
|
|
|
185
184
|
<head>
|
|
185
|
+
<%- custom_inject('headBegin') %>
|
|
186
186
|
<meta charset="utf-8">
|
|
187
187
|
<meta name="hexo-theme" content="<%- stellar_info('tree') %>" theme-name="<%- stellar_info('name') %>" theme-version="<%- stellar_info('version') %>">
|
|
188
188
|
<%- generate_canonical() %>
|
|
@@ -248,7 +248,7 @@ function generate_canonical() {
|
|
|
248
248
|
<% } %>
|
|
249
249
|
|
|
250
250
|
<%- json_ld(pageViewModel || undefined) %>
|
|
251
|
-
<%- custom_inject() %>
|
|
251
|
+
<%- custom_inject('headEnd') %>
|
|
252
252
|
|
|
253
253
|
<!-- icons.yml 驱动的 CSS 装饰图标 -->
|
|
254
254
|
<%
|
|
@@ -15,6 +15,7 @@ var html = '<!DOCTYPE html>'
|
|
|
15
15
|
html += `<html lang="${language}"${htmlAttributes}>`
|
|
16
16
|
html += head
|
|
17
17
|
html += `<body${pageAttributes}>`
|
|
18
|
+
html += bodyBegin || ''
|
|
18
19
|
html += siteBackground || ''
|
|
19
20
|
html += cover || ''
|
|
20
21
|
html += `<div class="site-shell" id="start" data-regions="${presentRegions.join(' ')}">`
|
|
@@ -15,6 +15,10 @@ var runtimeHomeComments = stellar_config('profiles.home.comments')
|
|
|
15
15
|
if (!runtimeViewModel && runtimeHomeComments && runtimeHomeComments !== false && is_home_first_page()) {
|
|
16
16
|
runtimeCommentOverrides = typeof runtimeHomeComments === 'object' ? runtimeHomeComments : {enabled: true}
|
|
17
17
|
}
|
|
18
|
+
var runtimeErrorComments = stellar_config('profiles.error.comments')
|
|
19
|
+
if (!runtimeViewModel && page.layout === '404' && runtimeErrorComments && runtimeErrorComments !== false) {
|
|
20
|
+
runtimeCommentOverrides = typeof runtimeErrorComments === 'object' ? runtimeErrorComments : {enabled: true}
|
|
21
|
+
}
|
|
18
22
|
var runtimeComments = runtimeViewModel?.render?.article?.comments || comments_model(page, runtimeCommentOverrides)
|
|
19
23
|
var runtimeProfile = runtimeViewModel?.collection?.profile
|
|
20
24
|
|| (page.notebookIndex?.mode === 'notes' ? 'notebook' : page.layout || '')
|
|
@@ -15,7 +15,7 @@ function isLeaf(tag) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
function getTagcon(tag) {
|
|
18
|
-
var tagIcons = stellar_config('notebook.tagIcons') || {}
|
|
18
|
+
var tagIcons = stellar_config('profiles.notebook.tagIcons') || {}
|
|
19
19
|
return tagIcons[tag.name] || tagIcons[tag.id] || tagIcons[tag.label] || tagIcons[tag.label.toLowerCase()] || 'quot:hashtag'
|
|
20
20
|
}
|
|
21
21
|
|
package/layout/layout.ejs
CHANGED
|
@@ -53,6 +53,7 @@ function shellDocument(options) {
|
|
|
53
53
|
documentModel: options.documentModel,
|
|
54
54
|
pageModel: options.pageModel,
|
|
55
55
|
head: options.head,
|
|
56
|
+
bodyBegin: options.bodyBegin,
|
|
56
57
|
siteBackground: options.siteBackground,
|
|
57
58
|
cover: options.cover,
|
|
58
59
|
regions: options.regions,
|
|
@@ -118,6 +119,7 @@ if (renderViewModel) {
|
|
|
118
119
|
indent: render.layout.indent
|
|
119
120
|
},
|
|
120
121
|
head: partial('_partial/head', {viewModel: renderViewModel}),
|
|
122
|
+
bodyBegin: stellar_inject('bodyBegin', render.document.bodyBeginInject),
|
|
121
123
|
siteBackground: siteBackground(render.layout.siteBackground),
|
|
122
124
|
cover: coverSlot(renderViewModel),
|
|
123
125
|
regions: {
|
|
@@ -148,9 +150,9 @@ if (renderViewModel) {
|
|
|
148
150
|
if (is_home()) {
|
|
149
151
|
profileKey = 'home'
|
|
150
152
|
} else if (page.layout === 'notebooks') {
|
|
151
|
-
profileKey = '
|
|
153
|
+
profileKey = 'notebooks'
|
|
152
154
|
} else if (page.layout === 'notes') {
|
|
153
|
-
profileKey = '
|
|
155
|
+
profileKey = 'notebook'
|
|
154
156
|
collectionRegions = notebookIndex?.layout
|
|
155
157
|
} else if (is_category() || is_tag() || is_archive() || ['categories', 'tags', 'archives'].includes(page.layout)) {
|
|
156
158
|
profileKey = 'blogIndex'
|
|
@@ -187,6 +189,7 @@ if (renderViewModel) {
|
|
|
187
189
|
indent: indent
|
|
188
190
|
},
|
|
189
191
|
head: partial('_partial/head'),
|
|
192
|
+
bodyBegin: stellar_inject('bodyBegin', pageConfig.inject?.bodyBegin),
|
|
190
193
|
siteBackground: siteBackground(appearance.backgrounds.page.image),
|
|
191
194
|
cover: coverSlot(),
|
|
192
195
|
regions: {
|
package/layout/settings.ejs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
page.robots = 'noindex,nofollow'
|
|
3
3
|
var provider = stellar_config('comments.provider') || ''
|
|
4
4
|
var providerSupported = ['artalk', 'waline', 'twikoo'].includes(String(provider).toLowerCase())
|
|
5
|
-
var settingsConfig = stellar_config('settings') || {}
|
|
5
|
+
var settingsConfig = stellar_config('profiles.settings') || {}
|
|
6
6
|
var aboutItems = settingsConfig.about?.items || []
|
|
7
7
|
var cacheItems = [
|
|
8
8
|
{ id: 'search', label: __('settings.cache.search') },
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hexo-theme-stellar",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0-rc.2",
|
|
4
|
+
"description": "An all-in-one Hexo theme for blogs, project documentation, knowledge bases, series, and notebooks.",
|
|
5
5
|
"main": "package.json",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"lint": "eslint .",
|
|
@@ -24,10 +24,19 @@
|
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
26
26
|
"hexo",
|
|
27
|
+
"hexo-theme",
|
|
27
28
|
"theme",
|
|
28
|
-
"stellar"
|
|
29
|
+
"stellar",
|
|
30
|
+
"blog",
|
|
31
|
+
"wiki",
|
|
32
|
+
"documentation",
|
|
33
|
+
"knowledge-base",
|
|
34
|
+
"notebook"
|
|
29
35
|
],
|
|
30
|
-
"author":
|
|
36
|
+
"author": {
|
|
37
|
+
"name": "xaoxuu",
|
|
38
|
+
"url": "https://github.com/xaoxuu/"
|
|
39
|
+
},
|
|
31
40
|
"license": "MIT",
|
|
32
41
|
"engines": {
|
|
33
42
|
"node": ">=22"
|
|
@@ -38,6 +47,7 @@
|
|
|
38
47
|
"dependencies": {
|
|
39
48
|
"cheerio": "^1.1.0",
|
|
40
49
|
"glob": "^10.4.0",
|
|
50
|
+
"hexo-front-matter": "^4.2.1",
|
|
41
51
|
"hexo-renderer-ejs": "^2.0.0",
|
|
42
52
|
"hexo-renderer-stylus": "^3.0.1",
|
|
43
53
|
"hexo-pagination": "^3.0.0",
|
|
@@ -12,7 +12,7 @@ const { selectListingItems, stableSort } = require("../lib/collection-pipeline/s
|
|
|
12
12
|
hexo.extend.generator.register("notebooks", function (locals) {
|
|
13
13
|
const { notebookIndex } = hexo.stellar.data;
|
|
14
14
|
const profiles = requireLayoutProfiles(hexo.stellar?.config);
|
|
15
|
-
const profile = profiles.
|
|
15
|
+
const profile = profiles.notebooks;
|
|
16
16
|
if (!notebookIndex?.items || notebookIndex.items.length === 0) {
|
|
17
17
|
return [];
|
|
18
18
|
}
|
|
@@ -79,7 +79,7 @@ hexo.extend.generator.register("notebooks", function (locals) {
|
|
|
79
79
|
layout: ["notes"],
|
|
80
80
|
data: {
|
|
81
81
|
layout: "notes",
|
|
82
|
-
navigation: { menu: notebook.navigation.menu ?? profiles.
|
|
82
|
+
navigation: { menu: notebook.navigation.menu ?? profiles.notebook.activeMenu }
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
85
|
for (const slice of slices) {
|
package/scripts/lib/brand.js
CHANGED
|
@@ -8,14 +8,18 @@ const {
|
|
|
8
8
|
} = require("./config-schema");
|
|
9
9
|
|
|
10
10
|
function requireContentConfig(stellarConfig, source = "_config.stellar.yml") {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const article = stellarConfig?.article;
|
|
12
|
+
const notebook = stellarConfig?.profiles?.notebook;
|
|
13
|
+
if (isPlainObject(article) && isPlainObject(notebook)) {
|
|
14
|
+
return { article, notebook };
|
|
13
15
|
}
|
|
16
|
+
const path = isPlainObject(article) ? "stellarConfig.profiles.notebook" : "stellarConfig.article";
|
|
17
|
+
const actual = isPlainObject(article) ? notebook : article;
|
|
14
18
|
throw new ConfigSchemaError([Object.freeze({
|
|
15
19
|
code: "invalid_type",
|
|
16
20
|
source,
|
|
17
|
-
path
|
|
18
|
-
actualType: valueType(
|
|
21
|
+
path,
|
|
22
|
+
actualType: valueType(actual),
|
|
19
23
|
expected: "normalized content defaults object",
|
|
20
24
|
migration: null
|
|
21
25
|
})]);
|
|
@@ -177,7 +177,7 @@ const CONTRIBUTIONS = defineContributions([
|
|
|
177
177
|
tests: [RUNTIME_TEST, RUNTIME_CONSUMPTION_TEST],
|
|
178
178
|
defaultsOwner: CONFIG_OWNER("comments.provider"),
|
|
179
179
|
project(context) {
|
|
180
|
-
if (typeof context.comments.service !== "string" || context.comments.service.length === 0) return null;
|
|
180
|
+
if (context.comments.enabled !== true || typeof context.comments.service !== "string" || context.comments.service.length === 0) return null;
|
|
181
181
|
return configResult({
|
|
182
182
|
provider: context.comments.service,
|
|
183
183
|
options: context.comments.options || {},
|
|
@@ -499,7 +499,9 @@ function buildPostRenderModel(input, collection, item) {
|
|
|
499
499
|
return {
|
|
500
500
|
document: {
|
|
501
501
|
language: normalizeLanguage(page.lang, page.language, frontMatter.lang, frontMatter.language, siteConfig.language),
|
|
502
|
+
headBeginInject: normalizeInject(frontMatter.inject?.headBegin),
|
|
502
503
|
headEndInject: normalizeInject(frontMatter.inject?.headEnd),
|
|
504
|
+
bodyBeginInject: normalizeInject(frontMatter.inject?.bodyBegin),
|
|
503
505
|
bodyEndInject: normalizeInject(frontMatter.inject?.bodyEnd),
|
|
504
506
|
preferredTheme: appearance.colorScheme === "auto"
|
|
505
507
|
? "auto"
|
|
@@ -690,7 +692,9 @@ function buildWikiRenderModel(input, collection, item) {
|
|
|
690
692
|
return {
|
|
691
693
|
document: {
|
|
692
694
|
language,
|
|
695
|
+
headBeginInject: normalizeInject(frontMatter.inject?.headBegin),
|
|
693
696
|
headEndInject: normalizeInject(frontMatter.inject?.headEnd),
|
|
697
|
+
bodyBeginInject: normalizeInject(frontMatter.inject?.bodyBegin),
|
|
694
698
|
bodyEndInject: normalizeInject(frontMatter.inject?.bodyEnd),
|
|
695
699
|
preferredTheme: appearance.colorScheme === "auto" ? "auto" : String(appearance.colorScheme || "")
|
|
696
700
|
},
|
|
@@ -1059,7 +1063,7 @@ function notebookBaseDir(collectionId, collectionConfig, stellarConfig) {
|
|
|
1059
1063
|
if (typeof collectionConfig.route?.path === "string" && collectionConfig.route.path.length > 0) {
|
|
1060
1064
|
return normalizeCollectionPath(collectionConfig.route.path);
|
|
1061
1065
|
}
|
|
1062
|
-
const root = profilePath(requireLayoutProfiles(stellarConfig).
|
|
1066
|
+
const root = profilePath(requireLayoutProfiles(stellarConfig).notebooks.path);
|
|
1063
1067
|
return normalizeCollectionPath([root, collectionId].filter(Boolean).join("/"));
|
|
1064
1068
|
}
|
|
1065
1069
|
|
|
@@ -1098,11 +1102,11 @@ function buildNotebookCollectionModel(input, collectionId) {
|
|
|
1098
1102
|
const defaultListing = notebookDefaults.listing;
|
|
1099
1103
|
const baseDir = notebookBaseDir(collectionId, collectionConfig, input.stellarConfig);
|
|
1100
1104
|
const identity = normalizeCollectionIdentity(collectionConfig);
|
|
1101
|
-
const profileNavigation = toRenderNavigation(profiles.
|
|
1105
|
+
const profileNavigation = toRenderNavigation(profiles.notebook);
|
|
1102
1106
|
const collectionNavigation = toContentNavigation(collectionConfig);
|
|
1103
1107
|
const collectionRegions = pick(collectionConfig, CONTENT_MODEL_FIELDS.regionIds);
|
|
1104
1108
|
const defaultBrand = collectionBrand(identity, baseDir, {
|
|
1105
|
-
indexPath: profiles.
|
|
1109
|
+
indexPath: profiles.notebooks.path,
|
|
1106
1110
|
backLabel: "btn.all_notebook"
|
|
1107
1111
|
});
|
|
1108
1112
|
assertCollectionBrandConfig(collectionConfig, "collection", input.collectionSource || "<collection>");
|
|
@@ -1218,7 +1222,7 @@ function buildNotebookRenderModel(input, collection, item) {
|
|
|
1218
1222
|
articleStyle: core.layout.articleStyle,
|
|
1219
1223
|
indent: core.layout.indent,
|
|
1220
1224
|
siteBackground: core.layout.siteBackground,
|
|
1221
|
-
notebookIndexPath: profilePath(requireLayoutProfiles(input.stellarConfig).
|
|
1225
|
+
notebookIndexPath: profilePath(requireLayoutProfiles(input.stellarConfig).notebooks.path),
|
|
1222
1226
|
notebookPath: collection.route.baseDir,
|
|
1223
1227
|
algoliaFilterPath: collection.route.baseDir,
|
|
1224
1228
|
topbar: core.layout.topbar,
|
|
@@ -152,7 +152,6 @@ const inheritedRegionBrand = properties => ({
|
|
|
152
152
|
});
|
|
153
153
|
|
|
154
154
|
const CONFIG_RULES = Object.freeze([
|
|
155
|
-
["settings.about.items", { items: aboutItem }],
|
|
156
155
|
["footer.sections", { items: footerSection }],
|
|
157
156
|
["footer.content", { normalizer: "trusted_text" }],
|
|
158
157
|
|
|
@@ -182,10 +181,12 @@ const CONFIG_RULES = Object.freeze([
|
|
|
182
181
|
["profiles.*.rightbar.enabled", { type: ["boolean", "null"], defaultValue: null }],
|
|
183
182
|
["profiles.*.rightbar.widgets", { type: ["array", "null"], defaultValue: null, items: widgetItems }],
|
|
184
183
|
["profiles.*.listing_nav.tabs", { validator: "navigation_tabs", items: navigationTab }],
|
|
185
|
-
["profiles.
|
|
186
|
-
["profiles.
|
|
187
|
-
["profiles
|
|
188
|
-
["profiles
|
|
184
|
+
["profiles.error.image", { type: ["string", "null"], validator: "nullable_resource" }],
|
|
185
|
+
["profiles.settings.about.items", { items: aboutItem }],
|
|
186
|
+
["profiles.*.comments.title", { type: ["string", "null"] }],
|
|
187
|
+
["profiles.*.comments.id", { type: ["string", "null"], normalizer: "nullable_trimmed_string", validator: "nullable_non_empty_string" }],
|
|
188
|
+
["profiles.*.comments.provider", { type: ["string", "null"], values: [null, "beaudar", "utterances", "giscus", "twikoo", "waline", "artalk"] }],
|
|
189
|
+
["profiles.*.comments.options", parameterBag],
|
|
189
190
|
|
|
190
191
|
["article.style", { values: ["tech", "story"] }],
|
|
191
192
|
["article.paragraph_indent", { values: ["auto", "always", "never"] }],
|
|
@@ -198,11 +199,11 @@ const CONFIG_RULES = Object.freeze([
|
|
|
198
199
|
["article.footer.license", { type: ["boolean", "string"], validator: "license_value" }],
|
|
199
200
|
["article.footer.share", { items: item("string", { defaultValue: "", values: SHARE_SERVICE_IDS }), normalizer: "trimmed_string_list" }],
|
|
200
201
|
["article.related_posts_limit", { minimum: 0, validator: "non_negative_integer" }],
|
|
201
|
-
["notebook.listing.excerpt_length", { minimum: 0, validator: "non_negative_integer" }],
|
|
202
|
-
["notebook.listing.per_page", { type: ["number", "null"], minimum: 0, validator: "nullable_non_negative_integer" }],
|
|
203
|
-
["notebook.listing.sort.field", { values: ["date", "updated", "title"] }],
|
|
204
|
-
["notebook.listing.sort.direction", { values: ["asc", "desc"] }],
|
|
205
|
-
["notebook.tag_icons", { ...stringRecord(), validator: "non_empty_record_keys" }],
|
|
202
|
+
["profiles.notebook.listing.excerpt_length", { minimum: 0, validator: "non_negative_integer" }],
|
|
203
|
+
["profiles.notebook.listing.per_page", { type: ["number", "null"], minimum: 0, validator: "nullable_non_negative_integer" }],
|
|
204
|
+
["profiles.notebook.listing.sort.field", { values: ["date", "updated", "title"] }],
|
|
205
|
+
["profiles.notebook.listing.sort.direction", { values: ["asc", "desc"] }],
|
|
206
|
+
["profiles.notebook.tag_icons", { ...stringRecord(), validator: "non_empty_record_keys" }],
|
|
206
207
|
|
|
207
208
|
["appearance.preset", { values: ["card", "glass", "minimal", "flat"] }],
|
|
208
209
|
["appearance.color_scheme", { values: ["auto", "light", "dark"] }],
|
|
@@ -231,7 +232,6 @@ const CONFIG_RULES = Object.freeze([
|
|
|
231
232
|
["structured_data.same_as", { items: item("string", { defaultValue: "" }), normalizer: "trimmed_string_list" }],
|
|
232
233
|
["preconnect", { items: item("string", { defaultValue: "" }), normalizer: "origin_list" }],
|
|
233
234
|
["fallbacks.*", { validator: "resource" }],
|
|
234
|
-
["error_page.image", { type: ["string", "null"], validator: "nullable_resource" }],
|
|
235
235
|
|
|
236
236
|
["search.provider", { type: ["string", "null"], values: [null, "local", "algolia"] }],
|
|
237
237
|
["search.local.cache_ttl_seconds", { minimum: 0, validator: "non_negative_integer" }],
|
|
@@ -278,7 +278,9 @@ const CONFIG_RULES = Object.freeze([
|
|
|
278
278
|
["services.github_card.provider", { values: ["github_readme_stats"] }],
|
|
279
279
|
["services.github_card.github_readme_stats", { runtimeKey: "github_readme_stats" }],
|
|
280
280
|
["services.*.*.endpoint", { validator: "absolute_http_url" }],
|
|
281
|
+
["inject.head_begin", { normalizer: "trusted_text" }],
|
|
281
282
|
["inject.head_end", { normalizer: "trusted_text" }],
|
|
283
|
+
["inject.body_begin", { normalizer: "trusted_text" }],
|
|
282
284
|
["inject.body_end", { normalizer: "trusted_text" }]
|
|
283
285
|
]);
|
|
284
286
|
|
|
@@ -19,7 +19,8 @@ const LEGACY_THEME_ROOTS = Object.freeze({
|
|
|
19
19
|
data_cache: null,
|
|
20
20
|
plugins: "features",
|
|
21
21
|
style: "appearance",
|
|
22
|
-
|
|
22
|
+
notebook: "profiles.notebook",
|
|
23
|
+
default: "fallbacks | profiles.error.image",
|
|
23
24
|
api_host: "services.github | services.github_card",
|
|
24
25
|
system: null
|
|
25
26
|
});
|
|
@@ -228,7 +228,9 @@ const FRONT_MATTER_TARGET_DEFINITIONS = [
|
|
|
228
228
|
["seo", "object", literal({}), { boundary: "sealed" }],
|
|
229
229
|
["seo.open_graph", "object", literal({}), { boundary: "parameter_bag" }],
|
|
230
230
|
["inject", "object", literal({}), { boundary: "sealed" }],
|
|
231
|
+
["inject.head_begin", "string", literal("")],
|
|
231
232
|
["inject.head_end", "string", literal("")],
|
|
233
|
+
["inject.body_begin", "string", literal("")],
|
|
232
234
|
["inject.body_end", "string", literal("")]
|
|
233
235
|
];
|
|
234
236
|
|
|
@@ -452,12 +452,12 @@ function collectionSchema(profile) {
|
|
|
452
452
|
cardStyle: field(["string", "null"], { default: inherited("hexo.stellar.config.article.listing.cardLayout"), example: "hero", required: true })
|
|
453
453
|
} : {}),
|
|
454
454
|
excerptLength: field(["number", "null"], {
|
|
455
|
-
default: profile === "notebook" ? inherited("hexo.stellar.config.notebook.listing.excerptLength") : literal(null),
|
|
455
|
+
default: profile === "notebook" ? inherited("hexo.stellar.config.profiles.notebook.listing.excerptLength") : literal(null),
|
|
456
456
|
example: 128,
|
|
457
457
|
required: true
|
|
458
458
|
}),
|
|
459
459
|
perPage: field(["number", "null"], {
|
|
460
|
-
default: profile === "notebook" ? inherited("hexo.stellar.config.notebook.listing.perPage", "site.per_page") : literal(null),
|
|
460
|
+
default: profile === "notebook" ? inherited("hexo.stellar.config.profiles.notebook.listing.perPage", "site.per_page") : literal(null),
|
|
461
461
|
example: 10,
|
|
462
462
|
required: true
|
|
463
463
|
}),
|
|
@@ -465,7 +465,7 @@ function collectionSchema(profile) {
|
|
|
465
465
|
sort: object({
|
|
466
466
|
field: field("string", { default: profile === "topic" ? literal("date") : literal("updated"), example: "updated", required: true }),
|
|
467
467
|
direction: field("string", { default: literal("desc"), example: "desc", required: true })
|
|
468
|
-
}, { default: derived("collection.listing.sort", "hexo.stellar.config.notebook.listing.sort"), example: { field: "updated", direction: "desc" }, required: true })
|
|
468
|
+
}, { default: derived("collection.listing.sort", "hexo.stellar.config.profiles.notebook.listing.sort"), example: { field: "updated", direction: "desc" }, required: true })
|
|
469
469
|
})
|
|
470
470
|
};
|
|
471
471
|
|
|
@@ -618,10 +618,12 @@ function pageViewModelSchema(profile) {
|
|
|
618
618
|
properties.render = object({
|
|
619
619
|
document: object({
|
|
620
620
|
language: field("string", { default: derived("page.lang", "page.language", "site.language"), example: "zh-CN", required: true }),
|
|
621
|
+
headBeginInject: field("string", { default: literal(""), example: "", required: true }),
|
|
621
622
|
headEndInject: field("string", { default: literal(""), example: "", required: true }),
|
|
623
|
+
bodyBeginInject: field("string", { default: literal(""), example: "", required: true }),
|
|
622
624
|
bodyEndInject: field("string", { default: literal(""), example: "", required: true }),
|
|
623
625
|
preferredTheme: field("string", { default: derived("hexo.stellar.config.appearance.colorScheme"), example: "auto", required: true })
|
|
624
|
-
}, { required: true, example: { language: "zh-CN", headEndInject: "", bodyEndInject: "", preferredTheme: "auto" } }),
|
|
626
|
+
}, { required: true, example: { language: "zh-CN", headBeginInject: "", headEndInject: "", bodyBeginInject: "", bodyEndInject: "", preferredTheme: "auto" } }),
|
|
625
627
|
layout: object({
|
|
626
628
|
pageType: field("string", { default: literal("content"), example: "content", required: true }),
|
|
627
629
|
articleStyle: field(["string", "null"], { default: inherited("item.presentation.article.style"), example: "tech", required: true }),
|
|
@@ -692,7 +694,7 @@ function pageViewModelSchema(profile) {
|
|
|
692
694
|
}, { required: true, example: { href: "blog/hello", title: "Hello Stellar", layout: "post", date: null, cover: "", caption: "", excerpt: "", categories: [], categoryStyle: "", tags: [], authorId: "", priority: 0, listed: true, cardStyle: "classic" } })
|
|
693
695
|
}, {
|
|
694
696
|
default: computed(`由 ${profile === "topic" ? "Topic" : "Post"} PageViewModel 构建器生成`),
|
|
695
|
-
example: { document: { language: "zh-CN", headEndInject: "", bodyEndInject: "" }, layout: { pageType: "content" }, seo: { title: "Hello Stellar - Stellar" } },
|
|
697
|
+
example: { document: { language: "zh-CN", headBeginInject: "", headEndInject: "", bodyBeginInject: "", bodyEndInject: "" }, layout: { pageType: "content" }, seo: { title: "Hello Stellar - Stellar" } },
|
|
696
698
|
required: true
|
|
697
699
|
});
|
|
698
700
|
}
|
|
@@ -761,10 +763,12 @@ function pageViewModelSchema(profile) {
|
|
|
761
763
|
properties.render = object({
|
|
762
764
|
document: object({
|
|
763
765
|
language: field("string", { default: derived("page.lang", "page.language", "site.language"), example: "zh-CN", required: true }),
|
|
766
|
+
headBeginInject: field("string", { default: literal(""), example: "", required: true }),
|
|
764
767
|
headEndInject: field("string", { default: literal(""), example: "", required: true }),
|
|
768
|
+
bodyBeginInject: field("string", { default: literal(""), example: "", required: true }),
|
|
765
769
|
bodyEndInject: field("string", { default: literal(""), example: "", required: true }),
|
|
766
770
|
preferredTheme: field("string", { default: derived("hexo.stellar.config.appearance.colorScheme"), example: "auto", required: true })
|
|
767
|
-
}, { required: true, example: { language: "zh-CN", headEndInject: "", bodyEndInject: "", preferredTheme: "auto" } }),
|
|
771
|
+
}, { required: true, example: { language: "zh-CN", headBeginInject: "", headEndInject: "", bodyBeginInject: "", bodyEndInject: "", preferredTheme: "auto" } }),
|
|
768
772
|
layout: object({
|
|
769
773
|
pageType: field("string", { default: literal("content"), example: "content", required: true }),
|
|
770
774
|
articleStyle: field(["string", "null"], { default: inherited("item.presentation.article.style"), example: "tech", required: true }),
|
|
@@ -873,16 +877,18 @@ function pageViewModelSchema(profile) {
|
|
|
873
877
|
properties.render = object({
|
|
874
878
|
document: object({
|
|
875
879
|
language: field("string", { default: derived("page.lang", "page.language", "site.language"), example: "zh-CN", required: true }),
|
|
880
|
+
headBeginInject: field("string", { default: literal(""), example: "", required: true }),
|
|
876
881
|
headEndInject: field("string", { default: literal(""), example: "", required: true }),
|
|
882
|
+
bodyBeginInject: field("string", { default: literal(""), example: "", required: true }),
|
|
877
883
|
bodyEndInject: field("string", { default: literal(""), example: "", required: true }),
|
|
878
884
|
preferredTheme: field("string", { default: derived("appearance.colorScheme"), example: "auto", required: true })
|
|
879
|
-
}, { required: true, example: { language: "zh-CN", headEndInject: "", bodyEndInject: "", preferredTheme: "auto" } }),
|
|
885
|
+
}, { required: true, example: { language: "zh-CN", headBeginInject: "", headEndInject: "", bodyBeginInject: "", bodyEndInject: "", preferredTheme: "auto" } }),
|
|
880
886
|
layout: object({
|
|
881
887
|
pageType: field("string", { default: literal("content"), example: "content", required: true }),
|
|
882
888
|
articleStyle: field(["string", "null"], { default: inherited("item.presentation.article.style"), example: "tech", required: true }),
|
|
883
889
|
indent: field("boolean", { default: computed("由 article.paragraphIndent 与 style 解析"), example: false, required: true }),
|
|
884
890
|
siteBackground: field("boolean", { default: derived("appearance.backgrounds.page.image"), example: false, required: true }),
|
|
885
|
-
notebookIndexPath: field("string", { default: derived("hexo.stellar.config.profiles.
|
|
891
|
+
notebookIndexPath: field("string", { default: derived("hexo.stellar.config.profiles.notebooks.path"), example: "notebooks", required: true }),
|
|
886
892
|
notebookPath: field("string", { default: inherited("collection.route.baseDir"), example: "notes/dev", required: true }),
|
|
887
893
|
algoliaFilterPath: field("string", { default: inherited("collection.route.baseDir"), example: "notes/dev", required: true }),
|
|
888
894
|
...renderRegionsSchema(factory),
|