hd-garden 0.3.7 → 0.3.9
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/.env.example +8 -5
- package/Makefile +0 -1
- package/README.md +2 -2
- package/app/blog/page.tsx +6 -5
- package/app/columns/page.tsx +1 -1
- package/app/components/Comments.tsx +12 -26
- package/app/components/ContentEmptyState.tsx +6 -6
- package/app/components/GiscusComments.tsx +3 -6
- package/app/globals.css +11 -0
- package/app/lib/fallback-site-config.ts +18 -18
- package/app/lib/giscus-config.ts +39 -0
- package/bin/garden.mjs +16 -0
- package/package.json +1 -1
- package/site.config.yaml +19 -19
- package/templates/site/README.md +3 -1
- package/templates/site/site.config.yaml +19 -19
package/.env.example
CHANGED
|
@@ -8,11 +8,14 @@ ADMIN_URL=https://admin.example.com
|
|
|
8
8
|
# 可选:反向代理或多域名后台时,显式指定 GitHub OAuth 回调地址。
|
|
9
9
|
# GITHUB_OAUTH_REDIRECT_URI=https://admin.example.com/api/auth/github/callback
|
|
10
10
|
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
# 评论默认关闭。打开 https://giscus.app/zh-CN 安装后,去掉注释并填入真实值。
|
|
12
|
+
# 仓库必须是 owner/name 这种公开仓库,且已开启 Discussions。
|
|
13
|
+
# 线上还要把同名四项写进 GitHub Actions Variables。留空会让发布失败。
|
|
14
|
+
# 确定不开放评论时,把 Actions Variable GISCUS_DISABLED 设为 1。
|
|
15
|
+
# GISCUS_REPO=
|
|
16
|
+
# GISCUS_REPO_ID=
|
|
17
|
+
# GISCUS_CATEGORY=
|
|
18
|
+
# GISCUS_CATEGORY_ID=
|
|
16
19
|
|
|
17
20
|
# Webmention.io:注册正式域名后填写域名,不含 https://。
|
|
18
21
|
WEBMENTION_IO_DOMAIN=example.com
|
package/Makefile
CHANGED
package/README.md
CHANGED
|
@@ -55,11 +55,11 @@ make update # 检查、提交并触发自动发布
|
|
|
55
55
|
make update MESSAGE="新增一篇文章"
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
`make dev` 会在首次运行时自动安装依赖并创建 `.env.local`。`make update` 会先检查,再提交并推送工作区中的所有改动。不想发布的文件请先移出仓库或加入 `.gitignore`。
|
|
58
|
+
`make dev` 会在首次运行时自动安装依赖并创建 `.env.local`,同时说明如何接上评论。线上发布要求 Actions Variables 里有 `GISCUS_REPO`、`GISCUS_REPO_ID`、`GISCUS_CATEGORY`、`GISCUS_CATEGORY_ID`;留空会让构建失败。确定不开放评论时设置 `GISCUS_DISABLED=1`。`make update` 会先检查,再提交并推送工作区中的所有改动。不想发布的文件请先移出仓库或加入 `.gitignore`。
|
|
59
59
|
|
|
60
60
|
## 进一步配置
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
评论接法见[从零开始](docs/quick-start.md)。跑通以后,再按需查看:
|
|
63
63
|
|
|
64
64
|
- [评论、Webmentions 与内容分发](docs/integrations.md)
|
|
65
65
|
- [随想管理后台](docs/admin-service.md)
|
package/app/blog/page.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Suspense } from "react";
|
|
2
2
|
import { siteConfig, siteDocumentTitle } from "../site.config";
|
|
3
3
|
import { BlogArchive } from "../components/BlogArchive";
|
|
4
|
+
import { PageIntro } from "../components/PageIntro";
|
|
4
5
|
|
|
5
6
|
export const metadata = {
|
|
6
7
|
title: siteDocumentTitle,
|
|
@@ -10,11 +11,11 @@ export const metadata = {
|
|
|
10
11
|
export default function BlogIndex() {
|
|
11
12
|
return (
|
|
12
13
|
<main className="page-shell index-page">
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
<PageIntro
|
|
15
|
+
eyebrow="POSTS / 博文"
|
|
16
|
+
title={siteConfig.pages.blog.title}
|
|
17
|
+
subtitle={siteConfig.pages.blog.subtitle}
|
|
18
|
+
/>
|
|
18
19
|
<Suspense>
|
|
19
20
|
<BlogArchive />
|
|
20
21
|
</Suspense>
|
package/app/columns/page.tsx
CHANGED
|
@@ -1,29 +1,9 @@
|
|
|
1
1
|
import { ChatCircle, GithubLogo } from "@phosphor-icons/react/ssr";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
type GiscusConfig,
|
|
5
|
-
} from "./GiscusComments";
|
|
6
|
-
|
|
7
|
-
function giscusConfig(): GiscusConfig | undefined {
|
|
8
|
-
const config = {
|
|
9
|
-
repo:
|
|
10
|
-
process.env.GISCUS_REPO ?? process.env.NEXT_PUBLIC_GISCUS_REPO,
|
|
11
|
-
repoId:
|
|
12
|
-
process.env.GISCUS_REPO_ID ?? process.env.NEXT_PUBLIC_GISCUS_REPO_ID,
|
|
13
|
-
category:
|
|
14
|
-
process.env.GISCUS_CATEGORY ??
|
|
15
|
-
process.env.NEXT_PUBLIC_GISCUS_CATEGORY,
|
|
16
|
-
categoryId:
|
|
17
|
-
process.env.GISCUS_CATEGORY_ID ??
|
|
18
|
-
process.env.NEXT_PUBLIC_GISCUS_CATEGORY_ID,
|
|
19
|
-
};
|
|
20
|
-
return Object.values(config).every(Boolean)
|
|
21
|
-
? (config as GiscusConfig)
|
|
22
|
-
: undefined;
|
|
23
|
-
}
|
|
2
|
+
import { readGiscusConfig } from "../lib/giscus-config";
|
|
3
|
+
import { GiscusComments } from "./GiscusComments";
|
|
24
4
|
|
|
25
5
|
export function Comments({ slug }: { slug: string }) {
|
|
26
|
-
const config =
|
|
6
|
+
const config = readGiscusConfig();
|
|
27
7
|
|
|
28
8
|
return (
|
|
29
9
|
<section className="comments" aria-labelledby={`comments-heading-${slug}`}>
|
|
@@ -34,7 +14,7 @@ export function Comments({ slug }: { slug: string }) {
|
|
|
34
14
|
<p>
|
|
35
15
|
{config
|
|
36
16
|
? "评论由 GitHub Discussions 保存和管理。"
|
|
37
|
-
: "
|
|
17
|
+
: "评论还没开放。配好下面四项后,这里才会出现评论框。"}
|
|
38
18
|
</p>
|
|
39
19
|
</div>
|
|
40
20
|
</div>
|
|
@@ -45,8 +25,14 @@ export function Comments({ slug }: { slug: string }) {
|
|
|
45
25
|
<div className="integration-notice">
|
|
46
26
|
<GithubLogo size={20} weight="fill" />
|
|
47
27
|
<p>
|
|
48
|
-
|
|
49
|
-
|
|
28
|
+
打开{" "}
|
|
29
|
+
<a href="https://giscus.app/zh-CN" target="_blank" rel="noreferrer">
|
|
30
|
+
Giscus
|
|
31
|
+
</a>
|
|
32
|
+
,安装到一个已开启 Discussions 的公开仓库,把仓库、仓库 ID、分类、分类 ID
|
|
33
|
+
写入 <code>.env.local</code> 和 GitHub Actions Variables:
|
|
34
|
+
<code>GISCUS_REPO</code>、<code>GISCUS_REPO_ID</code>、
|
|
35
|
+
<code>GISCUS_CATEGORY</code>、<code>GISCUS_CATEGORY_ID</code>。
|
|
50
36
|
</p>
|
|
51
37
|
</div>
|
|
52
38
|
)}
|
|
@@ -7,24 +7,24 @@ const emptyContent = {
|
|
|
7
7
|
posts: {
|
|
8
8
|
icon: Article,
|
|
9
9
|
eyebrow: "NO POSTS YET / 暂无博文",
|
|
10
|
-
title: "
|
|
11
|
-
description: "
|
|
10
|
+
title: "暂无博文。",
|
|
11
|
+
description: "发布文章后会在这里按主题与时间归档。",
|
|
12
12
|
actionHref: "/",
|
|
13
13
|
actionLabel: "返回首页",
|
|
14
14
|
},
|
|
15
15
|
thoughts: {
|
|
16
16
|
icon: Quotes,
|
|
17
17
|
eyebrow: "NO THOUGHTS YET / 暂无随想",
|
|
18
|
-
title: "
|
|
19
|
-
description: "
|
|
18
|
+
title: "暂无随想。",
|
|
19
|
+
description: "日常的碎片记录、短笔记与链接会落在这里。",
|
|
20
20
|
actionHref: "/blog",
|
|
21
21
|
actionLabel: "先读博文",
|
|
22
22
|
},
|
|
23
23
|
columns: {
|
|
24
24
|
icon: Books,
|
|
25
25
|
eyebrow: "NO COLUMNS YET / 暂无专栏",
|
|
26
|
-
title: "
|
|
27
|
-
description: "
|
|
26
|
+
title: "暂无专栏。",
|
|
27
|
+
description: "文章积累成系列后会在这里按顺序呈现。",
|
|
28
28
|
actionHref: "/blog",
|
|
29
29
|
actionLabel: "浏览全部博文",
|
|
30
30
|
},
|
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useRef } from "react";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
category: string;
|
|
9
|
-
categoryId: string;
|
|
10
|
-
};
|
|
5
|
+
import type { GiscusConfig } from "../lib/giscus-config";
|
|
6
|
+
|
|
7
|
+
export type { GiscusConfig };
|
|
11
8
|
|
|
12
9
|
function currentGiscusTheme() {
|
|
13
10
|
return document.documentElement.dataset.theme === "dark" ? "dark" : "light";
|
package/app/globals.css
CHANGED
|
@@ -2934,6 +2934,17 @@ button {
|
|
|
2934
2934
|
font-size: 11px;
|
|
2935
2935
|
}
|
|
2936
2936
|
|
|
2937
|
+
.integration-notice a,
|
|
2938
|
+
.integration-notice code {
|
|
2939
|
+
text-decoration: underline;
|
|
2940
|
+
text-underline-offset: 0.18em;
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
.integration-notice code {
|
|
2944
|
+
text-decoration: none;
|
|
2945
|
+
font-family: var(--font-mono), ui-monospace, monospace;
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2937
2948
|
.integration-status {
|
|
2938
2949
|
margin: 22px 0 0;
|
|
2939
2950
|
color: var(--muted);
|
|
@@ -11,38 +11,38 @@ export const siteConfig = {
|
|
|
11
11
|
},
|
|
12
12
|
pages: {
|
|
13
13
|
home: {
|
|
14
|
-
title: "
|
|
15
|
-
subtitle: "
|
|
14
|
+
title: "记一些正在做的事,\n和想清楚的问题。",
|
|
15
|
+
subtitle: "关注软件工程、系统设计与技术实践,也记录偶发的探索和工作笔记。",
|
|
16
16
|
},
|
|
17
17
|
blog: {
|
|
18
|
-
title: "
|
|
19
|
-
subtitle: "
|
|
18
|
+
title: "博文",
|
|
19
|
+
subtitle: "阶段性的完整梳理与技术总结。",
|
|
20
20
|
},
|
|
21
21
|
thoughts: {
|
|
22
|
-
title: "
|
|
23
|
-
subtitle: "
|
|
22
|
+
title: "随想",
|
|
23
|
+
subtitle: "碎片的念头、偶遇的灵感、短笔记与链接。",
|
|
24
24
|
},
|
|
25
25
|
columns: {
|
|
26
|
-
title: "
|
|
27
|
-
subtitle: "
|
|
26
|
+
title: "专栏",
|
|
27
|
+
subtitle: "按顺序组织的专题系列,沿着清晰的脉络连点成线。",
|
|
28
28
|
},
|
|
29
29
|
about: {
|
|
30
30
|
title: "你好,我是 Your Name。",
|
|
31
|
-
subtitle: "
|
|
32
|
-
heading: "
|
|
31
|
+
subtitle: "欢迎来到我的个人网站。",
|
|
32
|
+
heading: "关于我与这里",
|
|
33
33
|
paragraphs: [
|
|
34
|
-
"
|
|
35
|
-
"
|
|
34
|
+
"一名工程师 / 创作者。平时主要关注系统开发、技术探索与软件设计。",
|
|
35
|
+
"这里是我的公开工作台与数字自留地。比起社交网络上的碎片动态,我更倾向于把探索过程沉淀为有据可查的代码、设计与长篇笔记。",
|
|
36
36
|
],
|
|
37
|
-
quote: "
|
|
37
|
+
quote: "",
|
|
38
38
|
focus: [
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
39
|
+
"软件工程与系统架构",
|
|
40
|
+
"原生工具与高质量交互",
|
|
41
|
+
"个人长期知识沉淀",
|
|
42
42
|
],
|
|
43
43
|
cta: {
|
|
44
44
|
href: "/blog",
|
|
45
|
-
label: "
|
|
45
|
+
label: "浏览博文",
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
48
|
garden: {
|
|
@@ -50,7 +50,7 @@ export const siteConfig = {
|
|
|
50
50
|
subtitle: "",
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
|
-
footer: "
|
|
53
|
+
footer: "持续记录与构建。",
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
export const githubUrl = `https://github.com/${siteConfig.author.github}`;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type GiscusConfig = {
|
|
2
|
+
repo: string;
|
|
3
|
+
repoId: string;
|
|
4
|
+
category: string;
|
|
5
|
+
categoryId: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const PLACEHOLDERS = new Set([
|
|
9
|
+
"owner/repository",
|
|
10
|
+
"R_xxxxxxxxxx",
|
|
11
|
+
"DIC_xxxxxxxxxx",
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
function configuredValue(
|
|
15
|
+
env: Record<string, string | undefined>,
|
|
16
|
+
primary: string,
|
|
17
|
+
fallback: string,
|
|
18
|
+
) {
|
|
19
|
+
const value = (env[primary] ?? env[fallback] ?? "").trim();
|
|
20
|
+
if (!value || PLACEHOLDERS.has(value)) return undefined;
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function readGiscusConfig(
|
|
25
|
+
env: Record<string, string | undefined> = process.env,
|
|
26
|
+
): GiscusConfig | undefined {
|
|
27
|
+
const repo = configuredValue(env, "GISCUS_REPO", "NEXT_PUBLIC_GISCUS_REPO");
|
|
28
|
+
const repoId = configuredValue(env, "GISCUS_REPO_ID", "NEXT_PUBLIC_GISCUS_REPO_ID");
|
|
29
|
+
const category = configuredValue(env, "GISCUS_CATEGORY", "NEXT_PUBLIC_GISCUS_CATEGORY");
|
|
30
|
+
const categoryId = configuredValue(
|
|
31
|
+
env,
|
|
32
|
+
"GISCUS_CATEGORY_ID",
|
|
33
|
+
"NEXT_PUBLIC_GISCUS_CATEGORY_ID",
|
|
34
|
+
);
|
|
35
|
+
if (!repo || !repoId || !category || !categoryId) return undefined;
|
|
36
|
+
if (!/^[^/\s]+\/[^/\s]+$/.test(repo)) return undefined;
|
|
37
|
+
if (!repoId.startsWith("R_") || !categoryId.startsWith("DIC_")) return undefined;
|
|
38
|
+
return { repo, repoId, category, categoryId };
|
|
39
|
+
}
|
package/bin/garden.mjs
CHANGED
|
@@ -88,11 +88,25 @@ function ensurePublic() {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
function printGiscusGuide() {
|
|
92
|
+
process.stdout.write(`评论默认关闭。发布前要接上自己的 Giscus,留空会让 GitHub Actions 构建失败:
|
|
93
|
+
1. 准备一个公开 GitHub 仓库,并开启 Discussions。公开源码仓库可以直接用;私有源码要另建一个公开仓库。
|
|
94
|
+
2. 打开 https://giscus.app/zh-CN ,安装 Giscus App,只授权这个仓库,并选一个分类。
|
|
95
|
+
3. 把仓库、仓库 ID、分类、分类 ID 写入 .env.local 的 GISCUS_REPO、GISCUS_REPO_ID、GISCUS_CATEGORY、GISCUS_CATEGORY_ID。
|
|
96
|
+
4. 在源码仓库 Settings → Secrets and variables → Actions → Variables 写入同样四项。
|
|
97
|
+
示例值不会被当成已配置。确定不开放评论时,把 Actions Variable GISCUS_DISABLED 设为 1。
|
|
98
|
+
`);
|
|
99
|
+
}
|
|
100
|
+
|
|
91
101
|
function ensureEnv() {
|
|
102
|
+
// CI injects the real values. Copying .env.example there would fill any
|
|
103
|
+
// unset key with a sample, which used to turn comments on for owner/repository.
|
|
104
|
+
if (process.env.GITHUB_ACTIONS === "true") return;
|
|
92
105
|
const example = path.join(gardenPackageRoot, ".env.example");
|
|
93
106
|
const local = path.join(siteRoot, ".env.local");
|
|
94
107
|
if (!fs.existsSync(local) && fs.existsSync(example)) {
|
|
95
108
|
fs.copyFileSync(example, local);
|
|
109
|
+
printGiscusGuide();
|
|
96
110
|
}
|
|
97
111
|
}
|
|
98
112
|
|
|
@@ -241,8 +255,10 @@ function initSite() {
|
|
|
241
255
|
process.stdout.write("下一步:\n");
|
|
242
256
|
process.stdout.write(` cd ${destination}\n`);
|
|
243
257
|
process.stdout.write(" npm install\n");
|
|
258
|
+
process.stdout.write(" 按下面四步接上评论,再写文章\n");
|
|
244
259
|
process.stdout.write(" make new TITLE=\"你好,世界\" SLUG=hello\n");
|
|
245
260
|
process.stdout.write(" make dev\n");
|
|
261
|
+
printGiscusGuide();
|
|
246
262
|
}
|
|
247
263
|
|
|
248
264
|
function packagedSkills() {
|
package/package.json
CHANGED
package/site.config.yaml
CHANGED
|
@@ -14,35 +14,35 @@ author:
|
|
|
14
14
|
pages:
|
|
15
15
|
home:
|
|
16
16
|
title: |-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
subtitle:
|
|
17
|
+
记一些正在做的事,
|
|
18
|
+
和想清楚的问题。
|
|
19
|
+
subtitle: 关注软件工程、系统设计与技术实践,也记录偶发的探索和工作笔记。
|
|
20
20
|
blog:
|
|
21
|
-
title:
|
|
22
|
-
subtitle:
|
|
21
|
+
title: 博文
|
|
22
|
+
subtitle: 阶段性的完整梳理与技术总结。
|
|
23
23
|
thoughts:
|
|
24
|
-
title:
|
|
25
|
-
subtitle:
|
|
24
|
+
title: 随想
|
|
25
|
+
subtitle: 碎片的念头、偶遇的灵感、短笔记与链接。
|
|
26
26
|
columns:
|
|
27
|
-
title:
|
|
28
|
-
subtitle:
|
|
27
|
+
title: 专栏
|
|
28
|
+
subtitle: 按顺序组织的专题系列,沿着清晰的脉络连点成线。
|
|
29
29
|
about:
|
|
30
30
|
title: 你好,我是 Your Name。
|
|
31
|
-
subtitle:
|
|
32
|
-
heading:
|
|
31
|
+
subtitle: 欢迎来到我的个人网站。
|
|
32
|
+
heading: 关于我与这里
|
|
33
33
|
paragraphs:
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
quote:
|
|
34
|
+
- 一名工程师 / 创作者。平时主要关注系统开发、技术探索与软件设计。
|
|
35
|
+
- 这里是我的公开工作台与数字自留地。比起社交网络上的碎片动态,我更倾向于把探索过程沉淀为有据可查的代码、设计与长篇笔记。
|
|
36
|
+
quote: ""
|
|
37
37
|
focus:
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
38
|
+
- 软件工程与系统架构
|
|
39
|
+
- 原生工具与高质量交互
|
|
40
|
+
- 个人长期知识沉淀
|
|
41
41
|
cta:
|
|
42
42
|
href: /blog
|
|
43
|
-
label:
|
|
43
|
+
label: 浏览博文
|
|
44
44
|
garden:
|
|
45
45
|
title: 一个基于 Markdown 的个人博客框架。
|
|
46
46
|
subtitle: ""
|
|
47
47
|
|
|
48
|
-
footer:
|
|
48
|
+
footer: 持续记录与构建。
|
package/templates/site/README.md
CHANGED
|
@@ -8,6 +8,8 @@ make new TITLE="你好,世界" SLUG=hello
|
|
|
8
8
|
make dev
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
第一次 `npx garden dev` 会补齐 Makefile 和 skill
|
|
11
|
+
第一次 `npx garden dev` 会补齐 Makefile 和 skill,并创建 `.env.local`。Cursor / Codex 打开这个仓库后会读到 `.agents/skills/`。要更新 skill,再运行 `npx garden skill`。
|
|
12
|
+
|
|
13
|
+
评论默认关闭。发布前打开 [Giscus](https://giscus.app/zh-CN),把仓库、仓库 ID、分类、分类 ID 写入 `.env.local`,并在 GitHub Actions Variables 设置同名的 `GISCUS_REPO`、`GISCUS_REPO_ID`、`GISCUS_CATEGORY`、`GISCUS_CATEGORY_ID`。留空会让发布失败。确定不开放评论时,把 `GISCUS_DISABLED` 设为 `1`。
|
|
12
14
|
|
|
13
15
|
升级引擎:把 `package.json` 里的 `hd-garden` 改到新版本,例如 `^0.4.0`,再运行 `npm install`。
|
|
@@ -12,35 +12,35 @@ author:
|
|
|
12
12
|
pages:
|
|
13
13
|
home:
|
|
14
14
|
title: |-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
subtitle:
|
|
15
|
+
记一些正在做的事,
|
|
16
|
+
和想清楚的问题。
|
|
17
|
+
subtitle: 关注软件工程、系统设计与技术实践,也记录偶发的探索和工作笔记。
|
|
18
18
|
blog:
|
|
19
|
-
title:
|
|
20
|
-
subtitle:
|
|
19
|
+
title: 博文
|
|
20
|
+
subtitle: 阶段性的完整梳理与技术总结。
|
|
21
21
|
thoughts:
|
|
22
|
-
title:
|
|
23
|
-
subtitle:
|
|
22
|
+
title: 随想
|
|
23
|
+
subtitle: 碎片的念头、偶遇的灵感、短笔记与链接。
|
|
24
24
|
columns:
|
|
25
|
-
title:
|
|
26
|
-
subtitle:
|
|
25
|
+
title: 专栏
|
|
26
|
+
subtitle: 按顺序组织的专题系列,沿着清晰的脉络连点成线。
|
|
27
27
|
about:
|
|
28
28
|
title: 你好,我是 Your Name。
|
|
29
|
-
subtitle:
|
|
30
|
-
heading:
|
|
29
|
+
subtitle: 欢迎来到我的个人网站。
|
|
30
|
+
heading: 关于我与这里
|
|
31
31
|
paragraphs:
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
quote:
|
|
32
|
+
- 一名工程师 / 创作者。平时主要关注系统开发、技术探索与软件设计。
|
|
33
|
+
- 这里是我的公开工作台与数字自留地。比起社交网络上的碎片动态,我更倾向于把探索过程沉淀为有据可查的代码、设计与长篇笔记。
|
|
34
|
+
quote: ""
|
|
35
35
|
focus:
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
36
|
+
- 软件工程与系统架构
|
|
37
|
+
- 原生工具与高质量交互
|
|
38
|
+
- 个人长期知识沉淀
|
|
39
39
|
cta:
|
|
40
40
|
href: /blog
|
|
41
|
-
label:
|
|
41
|
+
label: 浏览博文
|
|
42
42
|
garden:
|
|
43
43
|
title: 一个基于 Markdown 的个人博客框架。
|
|
44
44
|
subtitle: ""
|
|
45
45
|
|
|
46
|
-
footer:
|
|
46
|
+
footer: 持续记录与构建。
|