diff --git a/src/config/redirect.js b/src/config/redirect.js index c6a4bae5d9..8693073e94 100644 --- a/src/config/redirect.js +++ b/src/config/redirect.js @@ -1,3 +1,5 @@ +import { languagesArray } from '../i18n/locales'; + // Redirect .html and non-.html blog post URLs to the new format. This will ensure that any existing links to blog posts will continue to work and redirect users to the correct location on the new site. const blog = { '/2024/07/16/welcome-post.html': '/en/blog/2024-07-16-welcome-post', @@ -64,6 +66,63 @@ const pages = { '/en/changelog/4x': 'https://github.com/expressjs/express/releases', }; -const redirects = { ...blog, ...api_v2, ...pages }; +const api = { + '/5x/api.html': '/en/5x/api', + '/4x/api.html': '/en/4x/api', + '/3x/api.html': '/en/3x/api', + '/5x/api': '/en/5x/api', + '/4x/api': '/en/4x/api', + '/3x/api': '/en/3x/api', +}; + +const verDocsArr = [ + '/advanced/developing-template-engines', + '/guide/overriding-express-api', + '/guide/behind-proxies', + '/guide/debugging', + '/guide/error-handling', + '/guide/using-template-engines', + '/guide/using-middleware', + '/guide/writing-middleware', + '/guide/routing', + '/starter/faq', + '/starter/examples', + '/starter/static-files', + '/starter/basic-routing', + '/starter/installing', + '/starter/generator', + '/starter/hello-world', +]; + +// const verDocs = { +// '/en/advanced/developing-template-engines': '/en/5x/advanced/developing-template-engines', +// '/en/guide/overriding-express-api': '/en/5x/guide/overriding-express-api', +// '/en/guide/behind-proxies': '/en/5x/guide/behind-proxies', +// '/en/guide/debugging': '/en/5x/guide/debugging', +// '/en/guide/error-handling': '/en/5x/guide/error-handling', +// '/en/guide/using-template-engines': '/en/5x/guide/using-template-engines', +// '/en/guide/using-middleware': '/en/5x/guide/using-middleware', +// '/en/guide/writing-middleware': '/en/5x/guide/writing-middleware', +// '/en/guide/routing': '/en/5x/guide/routing', +// '/en/starter/faq': '/en/5x/starter/faq', +// '/en/starter/examples': '/en/5x/starter/examples', +// '/en/starter/static-files': '/en/5x/starter/static-files', +// '/en/starter/basic-routing': '/en/5x/starter/basic-routing', +// '/en/starter/installing': '/en/5x/starter/installing', +// '/en/starter/generator': '/en/5x/starter/generator', +// '/en/starter/hello-world': '/en/5x/starter/hello-world', +// }; + +const generateVerDocs = () => { + return Object.fromEntries( + languagesArray.flatMap((lang) => + verDocsArr.map((route) => [`/${lang.code}${route}`, `/${lang.code}/5x${route}`]) + ) + ); +}; + +const verDocs = generateVerDocs(); + +const redirects = { ...blog, ...api_v2, ...pages, ...api, ...verDocs }; export default redirects; diff --git a/src/content.config.ts b/src/content.config.ts index 9449b30173..68c00e5762 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -46,9 +46,9 @@ const blogCollection = defineCollection({ const npmCollection = defineCollection({ loader: async () => { - const res = await fetch('https://registry.npmjs.org/express/latest'); - const { version } = await res.json(); - return [{ id: 'express', version }]; + // const res = await fetch('https://registry.npmjs.org/express/latest'); + // const { version } = await res.json(); + return [{ id: 'express', version: '5x' }]; }, schema: z.object({ version: z.string() }), }); diff --git a/src/content/api/3x/api.mdx b/src/content/api/3x/api.mdx index 71a52c55b0..780e403fda 100644 --- a/src/content/api/3x/api.mdx +++ b/src/content/api/3x/api.mdx @@ -1,5 +1,5 @@ --- -title: Express 3.x - Referencia de API +title: Express 3.x description: Access the API reference for Express.js version 3.x, noting that this version is end-of-life and no longer maintained - includes details on modules and methods. --- diff --git a/src/pages/[lang]/[...slug].astro b/src/pages/[lang]/[...slug].astro index 9ab6f30f42..604c7ca220 100644 --- a/src/pages/[lang]/[...slug].astro +++ b/src/pages/[lang]/[...slug].astro @@ -10,182 +10,67 @@ import { resourcesMenu } from '@/config/menu/resources'; import type { LanguageCode } from '@i18n/locales'; export async function getStaticPaths() { - const DEFAULT_VERSION = '5x'; - const VERSION_PREFIXES = ['5x', '4x', '3x']; - const DEFAULT_LANG = 'en'; - - const pages = await getCollection('docs'); + const langArr = Object.keys(languages); + const verDocs = await getCollection('docs'); const api = await getCollection('api'); - const contentPages = await getCollection('pages'); + const nonVerDocs = await getCollection('pages'); - type AnyPage = (typeof pages)[0] | (typeof api)[0] | (typeof contentPages)[0]; + type AnyPage = (typeof verDocs)[0] | (typeof api)[0] | (typeof nonVerDocs)[0]; const paths: Array<{ params: { lang: string; slug: string }; props: { page: AnyPage; version?: string }; }> = []; - // Helper to create a map of existing content for fallback logic - const existingContent = new Map(); - pages.forEach((page) => { + verDocs.forEach((page) => { const [lang, ...slugParts] = page.id.split('/'); const fullSlug = slugParts.join('/'); - existingContent.set(`${lang}/${fullSlug}`, page); - }); - - api.forEach((page) => { - existingContent.set(`en/${page.id}`, page); - }); - - pages.forEach((page) => { - const [lang, ...slugParts] = page.id.split('/'); - const fullSlug = slugParts.join('/'); - - const isVersioned = VERSION_PREFIXES.some((v) => fullSlug.startsWith(`${v}/`)); + // TODO: wait for crowdin setup, after this write logic to use english page + // if translated page is not available for versioned docs paths.push({ params: { lang, slug: fullSlug }, - props: { page, version: isVersioned ? slugParts[0] : DEFAULT_VERSION }, + props: { page, version: slugParts[0] }, }); }); - contentPages.forEach((page) => { + nonVerDocs.forEach((page) => { const [lang, ...slugParts] = page.id.split('/'); const fullSlug = slugParts.join('/'); + // TODO: wait for crowdin setup, after this write logic to use english page + // if translated page is not available for non versioned docs paths.push({ params: { lang, slug: fullSlug }, props: { page }, }); }); - for (const lang of Object.keys(languages)) { - api.forEach((page) => { - const slugParts = page.id.split('/'); - const version = slugParts[0]; - const slug = page.id; - - paths.push({ - params: { lang, slug }, - props: { page, version }, - }); - }); - } - - const defaultVersionApiPages = api.filter((page) => page.id.startsWith(`${DEFAULT_VERSION}/`)); - - for (const lang of Object.keys(languages)) { - defaultVersionApiPages.forEach((page) => { - const [, ...restSlugParts] = page.id.split('/'); - const nonVersionedSlug = restSlugParts.join('/'); - - const exists = paths.some( - (p) => p.params.lang === lang && p.params.slug === nonVersionedSlug - ); - - if (!exists && nonVersionedSlug) { + api.forEach((page) => { + const slugParts = page.id.split('/'); + const version = slugParts[0]; + const slug = page.id; + + if (slugParts.length === 2) { + // only add translations pages for '/en/5x/api', '/en/4x/api', '/en/3x/api' + // We are not translating apis this is for lagacy urls support + //! Can we use redirects for 27 pages? + langArr.forEach((lang) => { paths.push({ - params: { lang, slug: nonVersionedSlug }, - props: { page, version: DEFAULT_VERSION }, + params: { lang, slug }, + props: { page, version }, }); - } - }); - } - - const defaultVersionPages = pages.filter((page) => { - const [, ...slugParts] = page.id.split('/'); - return slugParts[0] === DEFAULT_VERSION; - }); - - defaultVersionPages.forEach((page) => { - const [lang, , ...restSlugParts] = page.id.split('/'); - const nonVersionedSlug = restSlugParts.join('/'); - - const exists = paths.some((p) => p.params.lang === lang && p.params.slug === nonVersionedSlug); - - if (!exists && nonVersionedSlug) { + }); + } else { + // add properties/methods pages only in english + // TODO: disable translations btn on properties/methods pages paths.push({ - params: { lang, slug: nonVersionedSlug }, - props: { page, version: DEFAULT_VERSION }, + params: { lang: 'en', slug }, + props: { page, version }, }); } }); - // Fallback for non-versioned default-version slugs: use English content for missing languages - const englishDefaultVersionPages = defaultVersionPages.filter((p) => - p.id.startsWith(`${DEFAULT_LANG}/`) - ); - - for (const lang of Object.keys(languages)) { - if (lang === DEFAULT_LANG) continue; - - englishDefaultVersionPages.forEach((page) => { - const [, , ...restSlugParts] = page.id.split('/'); - const nonVersionedSlug = restSlugParts.join('/'); - - const exists = paths.some( - (p) => p.params.lang === lang && p.params.slug === nonVersionedSlug - ); - - if (!exists && nonVersionedSlug) { - paths.push({ - params: { lang, slug: nonVersionedSlug }, - props: { page, version: DEFAULT_VERSION }, - }); - } - }); - } - - // Fallback: Create paths for non-English languages using English pages content - for (const lang of Object.keys(languages)) { - if (lang === DEFAULT_LANG) continue; - - const englishContentPages = contentPages.filter((p) => p.id.startsWith(`${DEFAULT_LANG}/`)); - - englishContentPages.forEach((page) => { - const [, ...slugParts] = page.id.split('/'); - const fullSlug = slugParts.join('/'); - - const langSpecificExists = paths.some( - (p) => p.params.lang === lang && p.params.slug === fullSlug - ); - - if (!langSpecificExists) { - paths.push({ - params: { lang, slug: fullSlug }, - props: { page }, - }); - } - }); - } - - // Fallback: Create paths for non-English languages using English docs content - for (const lang of Object.keys(languages)) { - if (lang === DEFAULT_LANG) continue; // Skip English, already added - - const englishPages = pages.filter((p) => p.id.startsWith(`${DEFAULT_LANG}/`)); - - englishPages.forEach((page) => { - const [, ...slugParts] = page.id.split('/'); - const fullSlug = slugParts.join('/'); - - const langSpecificExists = paths.some( - (p) => p.params.lang === lang && p.params.slug === fullSlug - ); - - // If no language-specific version exists, add fallback to English - if (!langSpecificExists) { - paths.push({ - params: { lang, slug: fullSlug }, - props: { - page, - version: slugParts[0] === DEFAULT_VERSION ? DEFAULT_VERSION : slugParts[0], - }, - }); - } - }); - } - return paths; } diff --git a/src/pages/[lang]/blog/[slug].astro b/src/pages/[lang]/blog/[slug].astro index 2e90ed2bb4..d1555ad518 100644 --- a/src/pages/[lang]/blog/[slug].astro +++ b/src/pages/[lang]/blog/[slug].astro @@ -15,7 +15,7 @@ import { export async function getStaticPaths() { const posts = await getCollection('blog'); - + //! Should we remove translations for blog posts? return Object.keys(languages).flatMap((lang) => posts.map((post) => { const filename = post.id.split('/').pop()!;