From 729a0d6840771f403f1abb4cc89568c76f42b966 Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Sat, 11 Oct 2025 10:31:40 +0800 Subject: [PATCH 1/8] build: add `lunaria` locales detector --- .github/workflows/docs-deploy.yml | 2 +- docs/lunaria.config.json | 31 +++++++++++ docs/package.json | 5 +- pnpm-lock.yaml | 86 +++++++++++++++++++++++++++++++ pnpm-workspace.yaml | 1 + 5 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 docs/lunaria.config.json diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index a15b94c799..f24eb9a114 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -32,7 +32,7 @@ jobs: - name: Docs build env: NODE_OPTIONS: --max_old_space_size=8192 - run: pnpm docs:build + run: pnpm docs:build && pnpm lunaria:build - name: Deploy docs uses: JamesIves/github-pages-deploy-action@v4 diff --git a/docs/lunaria.config.json b/docs/lunaria.config.json new file mode 100644 index 0000000000..7d14b6b408 --- /dev/null +++ b/docs/lunaria.config.json @@ -0,0 +1,31 @@ +{ + "$schema": "./node_modules/@lunariajs/core/config.schema.json", + "repository": { + "name": "pengzhanbo/vuepress-theme-plume", + "rootDir": "docs" + }, + "files": [ + { + "location": "**/*.md", + "pattern": "@lang/@path", + "type": "universal", + "ignore": [".vuepress/**", "./snippet/**", "node_modules", "**/*.snippet.md"] + } + ], + "defaultLocale": { + "label": "简体中文", + "lang": "zh" + }, + "locales": [ + { + "label": "简体中文", + "lang": "zh" + }, + { + "label": "English", + "lang": "en" + } + ], + "outDir": ".vuepress/dist/_translations", + "ignoreKeywords": ["lunaria-ignore"] +} diff --git a/docs/package.json b/docs/package.json index 09dccaefb8..c20962484c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -6,13 +6,16 @@ "docs:build": "vuepress build --clean-cache --clean-temp", "docs:clean": "rimraf .vuepress/.temp .vuepress/.cache .vuepress/dist", "docs:dev": "vuepress dev", - "docs:serve": "http-server .vuepress/dist -d 0" + "docs:serve": "http-server .vuepress/dist -d 0", + "lunaria:build": "lunaria build", + "lunaria:preview": "lunaria preview" }, "peerDependencies": { "vuepress": "catalog:vuepress" }, "dependencies": { "@iconify/json": "catalog:peer", + "@lunariajs/core": "catalog:dev", "@simonwep/pickr": "catalog:dev", "@vuepress/bundler-vite": "catalog:vuepress", "@vuepress/plugin-llms": "catalog:vuepress", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 914499e49b..71b0a6deb6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,6 +12,9 @@ catalogs: '@commitlint/config-conventional': specifier: ^20.0.0 version: 20.0.0 + '@lunariajs/core': + specifier: ^0.1.1 + version: 0.1.1 '@pengzhanbo/eslint-config-vue': specifier: ^1.38.0 version: 1.38.0 @@ -520,6 +523,9 @@ importers: '@iconify/json': specifier: catalog:peer version: 2.2.393 + '@lunariajs/core': + specifier: catalog:dev + version: 0.1.1 '@simonwep/pickr': specifier: catalog:dev version: 1.9.1 @@ -1074,6 +1080,9 @@ packages: '@chevrotain/utils@11.0.3': resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} + '@clack/core@0.3.5': + resolution: {integrity: sha512-5cfhQNH+1VQ2xLQlmzXMqUoiaH0lRBq9/CLW9lTyMbuKLC3+xEK01tHVvyut++mLOn5urSHmkm6I0Lg9MaJSTQ==} + '@clack/core@0.5.0': resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==} @@ -1615,12 +1624,23 @@ packages: '@kurkle/color@0.3.4': resolution: {integrity: sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==} + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} + + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + '@lit-labs/ssr-dom-shim@1.4.0': resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} '@lit/reactive-element@2.1.1': resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} + '@lunariajs/core@0.1.1': + resolution: {integrity: sha512-sAqM9+DVsLe3xHM9wu2pEnKGYMs/bWS9qpR+CGHol3RihOELnOQTzHddXbdB1MtgesbI8dnQuG64Ocd8KkWsng==} + engines: {node: '>=18.17.0'} + hasBin: true + '@mdit-vue/plugin-component@2.1.4': resolution: {integrity: sha512-fiLbwcaE6gZE4c8Mkdkc4X38ltXh/EdnuPE1hepFT2dLiW6I4X8ho2Wq7nhYuT8RmV4OKlCFENwCuXlKcpV/sw==} @@ -4533,6 +4553,10 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-port@7.1.0: + resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==} + engines: {node: '>=16'} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} @@ -5105,6 +5129,10 @@ packages: resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} engines: {node: 20 || >=22} + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + jiti@2.5.1: resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} hasBin: true @@ -5933,6 +5961,9 @@ packages: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -6513,6 +6544,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-git@3.28.0: + resolution: {integrity: sha512-Rs/vQRwsn1ILH1oBUy8NucJlXmnnLeLCfcvbSehkPzbv3wwoFWIdtfd6Ndo6ZPhlPsCZ60CPI4rxurnwAa+a2w==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -6996,6 +7030,9 @@ packages: engines: {node: '>=0.8.0'} hasBin: true + ultramatter@0.0.4: + resolution: {integrity: sha512-1f/hO3mR+/Hgue4eInOF/Qm/wzDqwhYha4DxM0hre9YIUyso3fE2XtrAU6B4njLqTC8CM49EZaYgsVSa+dXHGw==} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -7412,6 +7449,9 @@ packages: resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} engines: {node: '>=12.20'} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zrender@6.0.0: resolution: {integrity: sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==} @@ -7686,6 +7726,11 @@ snapshots: '@chevrotain/utils@11.0.3': {} + '@clack/core@0.3.5': + dependencies: + picocolors: 1.1.1 + sisteransi: 1.0.5 + '@clack/core@0.5.0': dependencies: picocolors: 1.1.1 @@ -8241,12 +8286,35 @@ snapshots: '@kurkle/color@0.3.4': {} + '@kwsites/file-exists@1.1.1': + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + '@lit-labs/ssr-dom-shim@1.4.0': {} '@lit/reactive-element@2.1.1': dependencies: '@lit-labs/ssr-dom-shim': 1.4.0 + '@lunariajs/core@0.1.1': + dependencies: + '@clack/core': 0.3.5 + fast-glob: 3.3.3 + get-port: 7.1.0 + jiti: 1.21.7 + micromatch: 4.0.8 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + simple-git: 3.28.0 + ultramatter: 0.0.4 + zod: 3.25.76 + transitivePeerDependencies: + - supports-color + '@mdit-vue/plugin-component@2.1.4': dependencies: '@types/markdown-it': 14.1.2 @@ -11623,6 +11691,8 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-port@7.1.0: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -12257,6 +12327,8 @@ snapshots: dependencies: '@isaacs/cliui': 8.0.2 + jiti@1.21.7: {} + jiti@2.5.1: {} joi@18.0.1: @@ -13311,6 +13383,8 @@ snapshots: lru-cache: 11.2.1 minipass: 7.1.2 + path-to-regexp@6.3.0: {} + path-type@4.0.0: {} path-type@6.0.0: {} @@ -13937,6 +14011,14 @@ snapshots: signal-exit@4.1.0: {} + simple-git@3.28.0: + dependencies: + '@kwsites/file-exists': 1.1.1 + '@kwsites/promise-deferred': 1.1.1 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + sisteransi@1.0.5: {} sitemap@8.0.0: @@ -14443,6 +14525,8 @@ snapshots: uglify-js@3.19.3: optional: true + ultramatter@0.0.4: {} + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -14883,6 +14967,8 @@ snapshots: yocto-queue@1.2.1: {} + zod@3.25.76: {} + zrender@6.0.0: dependencies: tslib: 2.3.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 9a4ab565a8..cfc63427cc 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -18,6 +18,7 @@ catalogs: dev: '@commitlint/cli': ^20.1.0 '@commitlint/config-conventional': ^20.0.0 + '@lunariajs/core': ^0.1.1 '@pengzhanbo/eslint-config-vue': ^1.38.0 '@pengzhanbo/stylelint-config': ^1.38.0 '@simonwep/pickr': ^1.9.1 From 0f350226effbe17a0e2cdc8a7c9b8c4c48ab71e1 Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Sat, 11 Oct 2025 10:37:26 +0800 Subject: [PATCH 2/8] build: add `lunaria` locales detector --- .github/workflows/docs-deploy.yml | 2 +- docs/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index f24eb9a114..a15b94c799 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -32,7 +32,7 @@ jobs: - name: Docs build env: NODE_OPTIONS: --max_old_space_size=8192 - run: pnpm docs:build && pnpm lunaria:build + run: pnpm docs:build - name: Deploy docs uses: JamesIves/github-pages-deploy-action@v4 diff --git a/docs/package.json b/docs/package.json index c20962484c..c5f5b52c97 100644 --- a/docs/package.json +++ b/docs/package.json @@ -3,7 +3,7 @@ "type": "module", "private": true, "scripts": { - "docs:build": "vuepress build --clean-cache --clean-temp", + "docs:build": "vuepress build --clean-cache --clean-temp && pnpm lunaria:build", "docs:clean": "rimraf .vuepress/.temp .vuepress/.cache .vuepress/dist", "docs:dev": "vuepress dev", "docs:serve": "http-server .vuepress/dist -d 0", From 3a07f590cbed071eaaea6f99703e1791a1794550 Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Sun, 12 Oct 2025 01:37:43 +0800 Subject: [PATCH 3/8] fix(theme): incorrect sidebar link prefix, close #714, #710 (#715) --- theme/src/client/composables/sidebar.ts | 2 +- theme/src/node/prepare/prepareSidebar.ts | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/theme/src/client/composables/sidebar.ts b/theme/src/client/composables/sidebar.ts index cb05428a58..4ffe30c1d8 100644 --- a/theme/src/client/composables/sidebar.ts +++ b/theme/src/client/composables/sidebar.ts @@ -121,7 +121,7 @@ export function getSidebar(routePath: string, routeLocal: string): ResolvedSideb return resolveSidebarItems(sidebar, routeLocal) } else if (isPlainObject(sidebar)) { - const prefix = normalizePrefix(routeLocal, removeLeadingSlash(sidebar.prefix || '')) + const prefix = normalizePrefix(routeLocal, sidebar.prefix) return resolveSidebarItems( sidebar.items === 'auto' ? autoDirSidebar.value[prefix] diff --git a/theme/src/node/prepare/prepareSidebar.ts b/theme/src/node/prepare/prepareSidebar.ts index 33b0a22ebf..51821e6169 100644 --- a/theme/src/node/prepare/prepareSidebar.ts +++ b/theme/src/node/prepare/prepareSidebar.ts @@ -8,6 +8,7 @@ import type { ThemeSidebarItem, } from '../../shared/index.js' import { + ensureLeadingSlash, entries, isArray, isPlainObject, @@ -45,7 +46,7 @@ function getSidebarData( } else if (isPlainObject(sidebar)) { entries(sidebar).forEach(([dirname, config]) => { - const prefix = normalizeLink(localePath, dirname) + const prefix = normalizeLink(localePath, removeLeadingSlash(dirname)) if (config === 'auto') { autoDirList.push(prefix) } @@ -103,11 +104,11 @@ function fileSorting(filepath?: string): number | false { function getAutoDirSidebar( app: App, - localePath: string, + prefix: string, ): { link: string, sidebar: ThemeSidebarItem[] } { - const locale = removeLeadingSlash(localePath) + const rootPath = removeLeadingSlash(prefix) let pages = (app.pages as Page[]) - .filter(page => page.data.filePathRelative?.startsWith(locale)) + .filter(page => page.data.filePathRelative?.startsWith(rootPath)) .map((page) => { return { ...page, splitPath: page.data.filePathRelative?.split('/') || [] } }) @@ -134,7 +135,7 @@ function getAutoDirSidebar( for (const page of pages) { const { data, title, path, frontmatter } = page const paths = (data.filePathRelative || '') - .slice(localePath.replace(/^\/|\/$/g, '').length + 1) + .slice(rootPath.replace(/^\/|\/$/g, '').length + 1) .split('/') const collection = findCollection(page) as ThemeDocCollection | undefined let index = 0 @@ -229,7 +230,7 @@ function getAllSidebar(): Record { const sidebar = locale === '/' ? (opt.sidebar || options.sidebar) : opt.sidebar locales[locale] = {} for (const [key, value] of entries(sidebar || {})) { - locales[locale][normalizeLink(key)] = value + locales[locale][ensureLeadingSlash(key)] = value } const collections = rawCollections?.filter(item => item.type === 'doc') if (collections?.length) { @@ -237,7 +238,7 @@ function getAllSidebar(): Record { if (collection.sidebar) { locales[locale][normalizeLink(collection.linkPrefix || collection.dir)] = { items: collection.sidebar, - prefix: normalizeLink(collection.dir), + prefix: normalizeLink(locale, removeLeadingSlash(collection.dir)), } } } From 86b7f2e695df7c3404d29e4755f42c7b83d7579b Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Sun, 12 Oct 2025 14:27:15 +0800 Subject: [PATCH 4/8] docs: update sponsor --- docs/sponsor.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/sponsor.md b/docs/sponsor.md index 9c5137fe98..ed638227a8 100644 --- a/docs/sponsor.md +++ b/docs/sponsor.md @@ -86,6 +86,7 @@ search: false | G*k | 2025-08-21 | 20.00 | 请你喝一杯咖啡 | | g*y | 2025-09-09 | 20.00 | 用过的最棒的博客系统!作者也很积极耐心的解答问题 | | *士 | 2025-09-30 | 30.00 | 感谢大佬制作的漂亮好用的主题!希望 plume 越来越好 | +| N*~ | 2025-10-12 | 27.00 | 一杯奶茶~ | From 338ca4ad7c3479a4821f53771e485faaecc0d075 Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Sun, 12 Oct 2025 14:28:04 +0800 Subject: [PATCH 5/8] fix(theme): optimize post category styles --- .../client/components/Posts/VPPostsCategories.vue | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/theme/src/client/components/Posts/VPPostsCategories.vue b/theme/src/client/components/Posts/VPPostsCategories.vue index 4b47cc745e..ccf706e983 100644 --- a/theme/src/client/components/Posts/VPPostsCategories.vue +++ b/theme/src/client/components/Posts/VPPostsCategories.vue @@ -7,7 +7,7 @@ const { categories } = usePostsCategory() From 8cec3f23e4765560424b160ac17891098c8ee97a Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Sun, 12 Oct 2025 14:31:32 +0800 Subject: [PATCH 6/8] fix(theme): fix page transition flickering (#717) --- theme/src/client/components/VPSwitchAppearance.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/theme/src/client/components/VPSwitchAppearance.vue b/theme/src/client/components/VPSwitchAppearance.vue index ff2c216307..a52eeebe4e 100644 --- a/theme/src/client/components/VPSwitchAppearance.vue +++ b/theme/src/client/components/VPSwitchAppearance.vue @@ -71,6 +71,7 @@ const toggleAppearance = inject('toggle-appearance', async ({ clientX: x, client { duration, easing: 'ease-in', + fill: 'forwards', pseudoElement: `::view-transition-${isDark.value ? 'old' : 'new'}(root)`, }, ) @@ -120,10 +121,15 @@ watchPostEffect(() => {