@guzhongren/sha 0.1.1 → 0.1.3
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/README.md +22 -20
- package/create.mjs +127 -0
- package/package.json +8 -3
- package/src/config.ts +2 -0
- package/src/index.ts +1 -0
- package/src/pages/rss.xml.ts +22 -0
- package/src/types.ts +2 -0
package/README.md
CHANGED
|
@@ -2,16 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
Config-driven Astro blog theme for technical writing. The theme is consumed as an Astro integration and injects default pages, layouts, and styling.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
Scaffold a new blog in one command:
|
|
6
8
|
|
|
7
9
|
```sh
|
|
8
|
-
pnpm
|
|
10
|
+
pnpm dlx @guzhongren/sha my-blog
|
|
11
|
+
cd my-blog && pnpm dev
|
|
9
12
|
```
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
This creates a complete project with `astro.config.mjs`, content collections bridge, and a sample post.
|
|
15
|
+
|
|
16
|
+
## Manual Setup
|
|
17
|
+
|
|
18
|
+
If you prefer to set up manually or add the theme to an existing Astro project:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
pnpm add @guzhongren/sha astro @astrojs/mdx @astrojs/markdown-remark tailwindcss @tailwindcss/vite
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### astro.config.mjs
|
|
12
25
|
|
|
13
26
|
```js
|
|
14
|
-
// astro.config.mjs
|
|
15
27
|
import { defineConfig } from "astro/config";
|
|
16
28
|
import mdx from "@astrojs/mdx";
|
|
17
29
|
import tailwindcss from "@tailwindcss/vite";
|
|
@@ -22,21 +34,13 @@ export default defineConfig({
|
|
|
22
34
|
integrations: [
|
|
23
35
|
blogTheme({
|
|
24
36
|
site: {
|
|
25
|
-
name: "
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
name: "My Blog",
|
|
38
|
+
title: "My Blog",
|
|
39
|
+
description: "A blog powered by @guzhongren/sha",
|
|
40
|
+
lang: "en",
|
|
28
41
|
},
|
|
29
42
|
author: {
|
|
30
|
-
name: "
|
|
31
|
-
headline: "全栈开发者 / 技术顾问",
|
|
32
|
-
bio: "写工程实践、架构思考、开源与日常观察。",
|
|
33
|
-
avatar: "/avatar.svg",
|
|
34
|
-
},
|
|
35
|
-
diagrams: {
|
|
36
|
-
mermaid: true,
|
|
37
|
-
plantuml: {
|
|
38
|
-
serverUrl: "https://www.plantuml.com/plantuml/svg",
|
|
39
|
-
},
|
|
43
|
+
name: "Author",
|
|
40
44
|
},
|
|
41
45
|
}),
|
|
42
46
|
mdx(),
|
|
@@ -49,9 +53,7 @@ export default defineConfig({
|
|
|
49
53
|
|
|
50
54
|
Register `blogTheme(...)` before `mdx()` when using theme shortcodes such as ECharts. The theme pre-processes content before MDX parses it.
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Astro requires the app to export content collections:
|
|
56
|
+
### Content collections bridge
|
|
55
57
|
|
|
56
58
|
```ts
|
|
57
59
|
// src/content.config.ts
|
package/create.mjs
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
|
|
6
|
+
const name = process.argv[2];
|
|
7
|
+
if (!name) {
|
|
8
|
+
console.error("Usage: pnpm dlx @guzhongren/sha <project-dir>");
|
|
9
|
+
console.error(" node create.mjs <project-dir>");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const root = join(process.cwd(), name);
|
|
14
|
+
|
|
15
|
+
// Dir tree
|
|
16
|
+
mkdirSync(join(root, "src", "content", "posts"), { recursive: true });
|
|
17
|
+
|
|
18
|
+
// package.json
|
|
19
|
+
writeFileSync(
|
|
20
|
+
join(root, "package.json"),
|
|
21
|
+
JSON.stringify(
|
|
22
|
+
{
|
|
23
|
+
name: name,
|
|
24
|
+
version: "0.0.1",
|
|
25
|
+
type: "module",
|
|
26
|
+
private: true,
|
|
27
|
+
scripts: {
|
|
28
|
+
dev: "astro dev",
|
|
29
|
+
sync: "astro sync",
|
|
30
|
+
build: "astro build",
|
|
31
|
+
preview: "astro preview",
|
|
32
|
+
},
|
|
33
|
+
dependencies: {
|
|
34
|
+
"@astrojs/markdown-remark": "^7.0.0",
|
|
35
|
+
"@astrojs/mdx": "^7.0.5",
|
|
36
|
+
"@guzhongren/sha": "^0.1.1",
|
|
37
|
+
"@tailwindcss/vite": "^4.3.3",
|
|
38
|
+
astro: "^7.1.6",
|
|
39
|
+
tailwindcss: "^4.3.3",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
null,
|
|
43
|
+
2,
|
|
44
|
+
) + "\n",
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
// astro.config.mjs
|
|
48
|
+
writeFileSync(
|
|
49
|
+
join(root, "astro.config.mjs"),
|
|
50
|
+
`import { defineConfig } from "astro/config";
|
|
51
|
+
import mdx from "@astrojs/mdx";
|
|
52
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
53
|
+
import blogTheme from "@guzhongren/sha";
|
|
54
|
+
|
|
55
|
+
export default defineConfig({
|
|
56
|
+
site: "https://example.com",
|
|
57
|
+
integrations: [
|
|
58
|
+
blogTheme({
|
|
59
|
+
site: {
|
|
60
|
+
name: "My Blog",
|
|
61
|
+
title: "My Blog",
|
|
62
|
+
description: "A blog powered by @guzhongren/sha",
|
|
63
|
+
lang: "en",
|
|
64
|
+
},
|
|
65
|
+
author: {
|
|
66
|
+
name: "Author",
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
mdx(),
|
|
70
|
+
],
|
|
71
|
+
vite: {
|
|
72
|
+
plugins: [tailwindcss()],
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
`,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// src/content.config.ts
|
|
79
|
+
writeFileSync(
|
|
80
|
+
join(root, "src", "content.config.ts"),
|
|
81
|
+
`export { collections } from "@guzhongren/sha/content";\n`,
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// hello-world post
|
|
85
|
+
writeFileSync(
|
|
86
|
+
join(root, "src", "content", "posts", "hello-world.md"),
|
|
87
|
+
`---
|
|
88
|
+
title: "Hello World"
|
|
89
|
+
description: "My first blog post"
|
|
90
|
+
publishDate: ${new Date().toISOString().slice(0, 10)}
|
|
91
|
+
category: "Uncategorized"
|
|
92
|
+
tags: ["hello"]
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
Welcome to my blog! 🎉
|
|
96
|
+
`,
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
// tsconfig.json
|
|
100
|
+
writeFileSync(
|
|
101
|
+
join(root, "tsconfig.json"),
|
|
102
|
+
`{
|
|
103
|
+
"extends": "astro/tsconfigs/strict"
|
|
104
|
+
}
|
|
105
|
+
`,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
// .gitignore
|
|
109
|
+
writeFileSync(join(root, ".gitignore"), "node_modules/\n.astro/\ndist/\n");
|
|
110
|
+
|
|
111
|
+
// pnpm-workspace.yaml (minimumReleaseAgeExclude for fresh packages)
|
|
112
|
+
writeFileSync(
|
|
113
|
+
join(root, "pnpm-workspace.yaml"),
|
|
114
|
+
`allowBuilds:
|
|
115
|
+
esbuild: true
|
|
116
|
+
minimumReleaseAgeExclude:
|
|
117
|
+
- "@guzhongren/sha"
|
|
118
|
+
`,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// Install deps
|
|
122
|
+
console.log(`\n✓ Scaffolded "${name}"`);
|
|
123
|
+
console.log("Installing dependencies...\n");
|
|
124
|
+
execSync("pnpm install", { cwd: root, stdio: "inherit" });
|
|
125
|
+
|
|
126
|
+
console.log(`\n✓ Done! Start the dev server:\n`);
|
|
127
|
+
console.log(` cd ${name} && pnpm dev\n`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guzhongren/sha",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "个人 Astro 博客主题 — 开箱即用的内容驱动博客",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,22 +15,27 @@
|
|
|
15
15
|
],
|
|
16
16
|
"files": [
|
|
17
17
|
"src/",
|
|
18
|
+
"create.mjs",
|
|
18
19
|
"README.md",
|
|
19
20
|
"LICENSE"
|
|
20
21
|
],
|
|
22
|
+
"bin": {
|
|
23
|
+
"create-sha-blog": "./create.mjs"
|
|
24
|
+
},
|
|
21
25
|
"exports": {
|
|
22
26
|
".": "./src/index.ts",
|
|
23
27
|
"./content": "./src/content.ts",
|
|
24
28
|
"./styles.css": "./src/styles/global.css"
|
|
25
29
|
},
|
|
26
30
|
"peerDependencies": {
|
|
27
|
-
"astro": "^7.1.3",
|
|
28
|
-
"@astrojs/mdx": "^7.0.0",
|
|
29
31
|
"@astrojs/markdown-remark": "^7.0.0",
|
|
32
|
+
"@astrojs/mdx": "^7.0.0",
|
|
30
33
|
"@tailwindcss/vite": "^4.0.0",
|
|
34
|
+
"astro": "^7.1.3",
|
|
31
35
|
"tailwindcss": "^4.0.0"
|
|
32
36
|
},
|
|
33
37
|
"dependencies": {
|
|
38
|
+
"@astrojs/rss": "^4.0.19",
|
|
34
39
|
"echarts": "^6.1.0",
|
|
35
40
|
"gemoji": "^8.1.0",
|
|
36
41
|
"mermaid": "^11.16.0",
|
package/src/config.ts
CHANGED
|
@@ -49,6 +49,7 @@ export function normalizeOptions(options: BlogThemeOptions): NormalizedBlogTheme
|
|
|
49
49
|
categories: false,
|
|
50
50
|
about: false,
|
|
51
51
|
search: false,
|
|
52
|
+
rss: false,
|
|
52
53
|
}
|
|
53
54
|
: {
|
|
54
55
|
home: options.routes?.home ?? true,
|
|
@@ -57,6 +58,7 @@ export function normalizeOptions(options: BlogThemeOptions): NormalizedBlogTheme
|
|
|
57
58
|
categories: options.routes?.categories ?? true,
|
|
58
59
|
about: options.routes?.about ?? true,
|
|
59
60
|
search: options.routes?.search ?? true,
|
|
61
|
+
rss: options.routes?.rss ?? true,
|
|
60
62
|
},
|
|
61
63
|
};
|
|
62
64
|
}
|
package/src/index.ts
CHANGED
|
@@ -100,6 +100,7 @@ export default function blogTheme(options: BlogThemeOptions): AstroIntegration {
|
|
|
100
100
|
}
|
|
101
101
|
if (config.routes.about) injectRoute({ pattern: "/about", entrypoint: route("./pages/about.astro") });
|
|
102
102
|
if (config.routes.search) injectRoute({ pattern: "/search", entrypoint: route("./pages/search.astro") });
|
|
103
|
+
if (config.routes.rss) injectRoute({ pattern: "/rss.xml", entrypoint: route("./pages/rss.xml.ts") });
|
|
103
104
|
},
|
|
104
105
|
"astro:build:done": async ({ dir }) => {
|
|
105
106
|
if (!config.routes.search) return;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import rss from "@astrojs/rss";
|
|
2
|
+
import { getCollection } from "astro:content";
|
|
3
|
+
import config from "virtual:blog-theme/config";
|
|
4
|
+
import { isPublished, sortPosts, postHref } from "../utils";
|
|
5
|
+
|
|
6
|
+
export async function GET(context: { site: URL }) {
|
|
7
|
+
const posts = sortPosts((await getCollection("posts")).filter(isPublished));
|
|
8
|
+
|
|
9
|
+
return rss({
|
|
10
|
+
xmlns: { atom: "http://www.w3.org/2005/Atom" },
|
|
11
|
+
title: config.site.title,
|
|
12
|
+
description: config.site.description,
|
|
13
|
+
site: context.site,
|
|
14
|
+
items: posts.map((post) => ({
|
|
15
|
+
title: post.data.title,
|
|
16
|
+
description: post.data.description,
|
|
17
|
+
pubDate: post.data.publishDate ?? new Date(),
|
|
18
|
+
link: postHref(post),
|
|
19
|
+
})),
|
|
20
|
+
customData: `<language>${config.site.lang}</language>`,
|
|
21
|
+
});
|
|
22
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -46,6 +46,7 @@ export type BlogThemeOptions = {
|
|
|
46
46
|
categories?: boolean;
|
|
47
47
|
about?: boolean;
|
|
48
48
|
search?: boolean;
|
|
49
|
+
rss?: boolean;
|
|
49
50
|
};
|
|
50
51
|
};
|
|
51
52
|
|
|
@@ -90,5 +91,6 @@ export type NormalizedBlogThemeOptions = {
|
|
|
90
91
|
categories: boolean;
|
|
91
92
|
about: boolean;
|
|
92
93
|
search: boolean;
|
|
94
|
+
rss: boolean;
|
|
93
95
|
};
|
|
94
96
|
};
|