From 7778187f2dc31554fa7541da9648235c994d4ae8 Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Sun, 30 Jul 2023 16:37:32 +0530 Subject: [PATCH] feat: i18n with sitemap (#2708) --- docs/.vitepress/config.ts | 5 ++- src/node/build/generateSitemap.ts | 56 +++++++++++++++++++++++++------ src/node/utils/getGitTimestamp.ts | 2 ++ 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 7033ca61..d1ae2feb 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -13,7 +13,10 @@ export default defineConfig({ cleanUrls: true, sitemap: { - hostname: 'https://vitepress.dev' + hostname: 'https://vitepress.dev', + transformItems(items) { + return items.filter((item) => !item.url.includes('migration')) + } }, head: [ diff --git a/src/node/build/generateSitemap.ts b/src/node/build/generateSitemap.ts index 21351233..f94980b3 100644 --- a/src/node/build/generateSitemap.ts +++ b/src/node/build/generateSitemap.ts @@ -14,19 +14,55 @@ import { task } from '../utils/task' export async function generateSitemap(siteConfig: SiteConfig) { if (!siteConfig.sitemap?.hostname) return + const getLastmod = async (url: string) => { + if (!siteConfig.lastUpdated) return undefined + + let path = url.replace(/(^|\/)$/, '$1index') + path = path.replace(/(\.html)?$/, '.md') + path = siteConfig.rewrites.inv[path] || path + + return (await getGitTimestamp(path)) || undefined + } + await task('generating sitemap', async () => { - let items: SitemapItem[] = await Promise.all( - siteConfig.pages.map(async (page) => { - // - let url = siteConfig.rewrites.map[page] || page - url = url.replace(/(^|\/)index\.md$/, '$1') - url = url.replace(/\.md$/, siteConfig.cleanUrls ? '' : '.html') - - const lastmod = siteConfig.lastUpdated && (await getGitTimestamp(page)) - return lastmod ? { url, lastmod } : { url } + const locales = siteConfig.userConfig.locales || {} + const filteredLocales = Object.keys(locales).filter( + (locale) => locales[locale].lang && locale !== 'root' + ) + const defaultLang = + locales?.root?.lang || siteConfig.userConfig.lang || 'en-US' + + const pages = siteConfig.pages.map( + (page) => siteConfig.rewrites.map[page] || page + ) + + const groupedPages: Record = {} + pages.forEach((page) => { + const locale = page.split('/')[0] + const lang = locales[locale]?.lang || defaultLang + + let url = page.replace(/(^|\/)index\.md$/, '$1') + url = url.replace(/\.md$/, siteConfig.cleanUrls ? '' : '.html') + if (filteredLocales.includes(locale)) page = page.slice(locale.length + 1) + + if (!groupedPages[page]) groupedPages[page] = [] + groupedPages[page].push({ url, lang }) + }) + + const _items = await Promise.all( + Object.values(groupedPages).map(async (pages) => { + if (pages.length < 2) + return { url: pages[0].url, lastmod: await getLastmod(pages[0].url) } + + return await Promise.all( + pages.map(async ({ url }) => { + return { url, lastmod: await getLastmod(url), links: pages } + }) + ) }) ) - items = items.sort((a, b) => a.url.localeCompare(b.url)) + + let items: SitemapItem[] = _items.flat() items = (await siteConfig.sitemap?.transformItems?.(items)) || items const sitemapStream = new SitemapStream(siteConfig.sitemap) diff --git a/src/node/utils/getGitTimestamp.ts b/src/node/utils/getGitTimestamp.ts index 51d01df7..fd4f648e 100644 --- a/src/node/utils/getGitTimestamp.ts +++ b/src/node/utils/getGitTimestamp.ts @@ -1,4 +1,5 @@ import { spawn } from 'cross-spawn' +import fs from 'fs-extra' import { basename, dirname } from 'path' const cache = new Map() @@ -9,6 +10,7 @@ export function getGitTimestamp(file: string) { return new Promise((resolve, reject) => { const cwd = dirname(file) + if (!fs.existsSync(cwd)) return resolve(0) const fileName = basename(file) const child = spawn('git', ['log', '-1', '--pretty="%ai"', fileName], { cwd