diff --git a/.gitignore b/.gitignore index c83b06a..d8fe03f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /docs/.vuepress/.cache/ /docs/.vuepress/.temp/ /.github/webhooks/hooks.json +/docs/.vuepress/.generated-fallbacks.json diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index b4d6954..380f625 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -1,11 +1,68 @@ import { getDirname, path } from "vuepress/utils" import { defineUserConfig } from 'vuepress' import { viteBundler } from '@vuepress/bundler-vite' +import fs from 'node:fs' import meta from './config/meta' import theme from './config/theme' const __dirname = getDirname(import.meta.url) +const docsDir = path.resolve(__dirname, '..') + +const FALLBACK_LOCALE = 'en' +const OTHER_LOCALES = ['de', 'es', 'fr'] + +// --------------------------------------------------------------------------- +// Before VuePress starts: create stub markdown files for EN articles that +// are missing in other locales. This ensures the blog plugin picks them up +// (it requires real files with filePathRelative). +// Generated stubs are tracked via a manifest and cleaned up on each run. +// --------------------------------------------------------------------------- +const manifestPath = path.resolve(__dirname, '.generated-fallbacks.json') + +;(() => { + // Clean up previously generated stubs + if (fs.existsSync(manifestPath)) { + const oldPaths = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) + for (const p of oldPaths) { + if (fs.existsSync(p)) fs.rmSync(p, { recursive: true }) + } + } + + const enNewsDir = path.resolve(docsDir, FALLBACK_LOCALE, 'news') + if (!fs.existsSync(enNewsDir)) return + + const enSlugs = fs.readdirSync(enNewsDir, { withFileTypes: true }) + .filter((d) => d.isDirectory()) + .map((d) => d.name) + + const generated = [] + + for (const locale of OTHER_LOCALES) { + const localeNewsDir = path.resolve(docsDir, locale, 'news') + if (!fs.existsSync(localeNewsDir)) fs.mkdirSync(localeNewsDir, { recursive: true }) + + const existingSlugs = new Set( + fs.readdirSync(localeNewsDir, { withFileTypes: true }) + .filter((d) => d.isDirectory()) + .map((d) => d.name) + ) + + for (const slug of enSlugs) { + if (existingSlugs.has(slug)) continue + + const enFile = path.resolve(enNewsDir, slug, 'README.md') + if (!fs.existsSync(enFile)) continue + + const targetDir = path.resolve(localeNewsDir, slug) + fs.mkdirSync(targetDir, { recursive: true }) + fs.copyFileSync(enFile, path.resolve(targetDir, 'README.md')) + generated.push(targetDir) + } + } + + fs.writeFileSync(manifestPath, JSON.stringify(generated, null, 2)) +})() export default defineUserConfig({ ...meta,