feat: initialize VitePress CMS
This commit is contained in:
113
src/utils/siteContent.ts
Normal file
113
src/utils/siteContent.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import type { SiteSettings } from "../types";
|
||||
|
||||
export function parseFrontmatter(source: string) {
|
||||
const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
|
||||
|
||||
if (!match) {
|
||||
return {
|
||||
title: "",
|
||||
description: "",
|
||||
content: source,
|
||||
};
|
||||
}
|
||||
|
||||
const frontmatter = match[1];
|
||||
const title = frontmatter.match(/^title:\s*(.+)$/m)?.[1]?.trim().replace(/^["']|["']$/g, "") ?? "";
|
||||
const description =
|
||||
frontmatter.match(/^description:\s*(.+)$/m)?.[1]?.trim().replace(/^["']|["']$/g, "") ?? "";
|
||||
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
content: source.slice(match[0].length),
|
||||
};
|
||||
}
|
||||
|
||||
export function stringifyMarkdownPage(page: {
|
||||
title: string;
|
||||
description: string;
|
||||
content: string;
|
||||
}) {
|
||||
const frontmatter = [
|
||||
"---",
|
||||
`title: ${page.title || "未命名页面"}`,
|
||||
`description: ${page.description || ""}`,
|
||||
"---",
|
||||
"",
|
||||
].join("\n");
|
||||
|
||||
return `${frontmatter}${page.content.trimStart()}`;
|
||||
}
|
||||
|
||||
function readStringValue(source: string, key: string, fallback = "") {
|
||||
const pattern = new RegExp(`${key}:\\s*["'\`]([^"'\`]+)["'\`]`);
|
||||
return source.match(pattern)?.[1] ?? fallback;
|
||||
}
|
||||
|
||||
function readBooleanValue(source: string, key: string, fallback = false) {
|
||||
const pattern = new RegExp(`${key}:\\s*(true|false)`);
|
||||
const value = source.match(pattern)?.[1];
|
||||
return value ? value === "true" : fallback;
|
||||
}
|
||||
|
||||
export function parseSiteSettings(source: string): SiteSettings {
|
||||
const socialLinksSource = source.match(/socialLinks:\s*\[([\s\S]*?)\]/)?.[1] ?? "";
|
||||
|
||||
return {
|
||||
title: readStringValue(source, "title", "VitePress Site"),
|
||||
description: readStringValue(source, "description"),
|
||||
logo: readStringValue(source, "logo", "/logo.svg"),
|
||||
lastUpdated: readBooleanValue(source, "lastUpdated", true),
|
||||
localSearch: /search:\s*{[\s\S]*?provider:\s*["']local["'][\s\S]*?}/.test(source),
|
||||
outline: readBooleanValue(source, "outline", true),
|
||||
socialKind: readStringValue(socialLinksSource, "icon", "github"),
|
||||
socialLink: readStringValue(socialLinksSource, "link", "https://github.com/example/vitepress-cms"),
|
||||
};
|
||||
}
|
||||
|
||||
export function stringifySiteConfig(settings: SiteSettings) {
|
||||
const searchConfig = settings.localSearch
|
||||
? ` search: {
|
||||
provider: "local",
|
||||
},`
|
||||
: "";
|
||||
|
||||
return `import { defineConfig } from "vitepress";
|
||||
|
||||
export default defineConfig({
|
||||
title: ${JSON.stringify(settings.title)},
|
||||
description: ${JSON.stringify(settings.description)},
|
||||
lastUpdated: ${settings.lastUpdated},
|
||||
themeConfig: {
|
||||
logo: ${JSON.stringify(settings.logo)},
|
||||
outline: ${settings.outline},
|
||||
nav: [
|
||||
{ text: "首页", link: "/" },
|
||||
{ text: "指南", link: "/guide/getting-started" },
|
||||
{ text: "配置", link: "/guide/config" },
|
||||
{ text: "更新日志", link: "/changelog" },
|
||||
],
|
||||
sidebar: {
|
||||
"/guide/": [
|
||||
{
|
||||
text: "指南",
|
||||
items: [
|
||||
{ text: "快速开始", link: "/guide/getting-started" },
|
||||
{ text: "页面管理", link: "/guide/pages" },
|
||||
{ text: "配置说明", link: "/guide/config" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
socialLinks: [
|
||||
{ icon: ${JSON.stringify(settings.socialKind)}, link: ${JSON.stringify(settings.socialLink)} },
|
||||
],
|
||||
footer: {
|
||||
message: "Powered by VitePress-CMS",
|
||||
copyright: "Copyright 2026",
|
||||
},
|
||||
${searchConfig}
|
||||
},
|
||||
});
|
||||
`;
|
||||
}
|
||||
Reference in New Issue
Block a user