diff --git a/src/content-render/unified/rewrite-local-links.js b/src/content-render/unified/rewrite-local-links.js index 424886d7c9..69d3167a10 100644 --- a/src/content-render/unified/rewrite-local-links.js +++ b/src/content-render/unified/rewrite-local-links.js @@ -42,14 +42,20 @@ const matcherAnchorLinks = (node) => // Content authors write links like `/some/article/path`, but they need to be // rewritten on the fly to match the current language and page version export default function rewriteLocalLinks(context) { - const { currentLanguage, currentVersion } = context + const { currentLanguage, autotitleLanguage, currentVersion } = context // There's no languageCode or version passed, so nothing to do if (!currentLanguage || !currentVersion) return return async function (tree) { const nodes = [] visit(tree, matcherInternalLinks, (node) => { - const newHref = getNewHref(node, currentLanguage, currentVersion) + // The context *might* have a `autotitleLanguage` which can be + // different from the regular `currentLanguage`. + // This means that AUTOTITLE links should be different from how, + // for example, reusables or other `{% data ... %}` Liquid tags work. + // Our release notes, for example, prefer to force the rendered text + // in English, but all AUTOTITLE links in the current language. + const newHref = getNewHref(node, autotitleLanguage || currentLanguage, currentVersion) if (newHref) { node.properties.href = newHref } diff --git a/src/release-notes/middleware/ghae-release-notes.js b/src/release-notes/middleware/ghae-release-notes.js index b1e6065ce4..ba6c2793f4 100644 --- a/src/release-notes/middleware/ghae-release-notes.js +++ b/src/release-notes/middleware/ghae-release-notes.js @@ -15,7 +15,18 @@ export default async function ghaeReleaseNotesContext(req, res, next) { ) return next() - const ghaeReleaseNotes = getReleaseNotes('github-ae', req.language) + // (This applies to ghes release notes too) + // We deliberately force the language to be English for now. + // The underlying reason is that the content (in data/release-notes/**/*.yml) + // is Markdown that does NOT use variables controlled by English-only + // things like product names. + // Therefore, the **nouns (like product names) get translated** instead + // of left as is. For example. "Le GitHubbe Cöpilotte" instead + // of "GitHub Copilot". + // Until the Markdown sources used for release notes have Liquid + // variables (like `{% data variables.product.prodname_ghe_cloud %}}`) + // we'll force the text to be that from English. + const ghaeReleaseNotes = getReleaseNotes('github-ae', 'en') // internalLatestRelease is set in lib/all-versions, e.g., '3.5' but UI still displays '@latest'. let requestedRelease = req.context.currentVersionObj.internalLatestRelease @@ -29,16 +40,29 @@ export default async function ghaeReleaseNotesContext(req, res, next) { // Returns [{version, patches: [ {version, patchVersion, intro, date, sections: { features: [], bugs: []...}} ] }] req.context.ghaeReleases = formatReleases(ghaeReleaseNotes) + // This means the AUTOTITLE links are in the current language, but + // since we're already force the source of the release notes from English + // exclusively, by doing this we can force all reusables to be in English + // too and leave links as is. + const originalLanguage = req.context.currentLanguage + req.context.autotitleLanguage = originalLanguage + req.context.currentLanguage = 'en' + // Run _all_ the GHAE patches through the markdown rendering pipeline. // This is different from req.context.ghesReleaseNotes, which renders one release at a time. // Returns all patches: [{version, patchVersion, intro, date, sections}] - req.context.ghaeReleaseNotes = ( - await Promise.all( - req.context.ghaeReleases.map( - async (release) => await renderPatchNotes(release.patches, req.context), - ), - ) - ).flat() + try { + req.context.ghaeReleaseNotes = ( + await Promise.all( + req.context.ghaeReleases.map( + async (release) => await renderPatchNotes(release.patches, req.context), + ), + ) + ).flat() + } finally { + // Restore the original language + req.context.currentLanguage = originalLanguage + } return next() } diff --git a/src/release-notes/middleware/ghes-release-notes.js b/src/release-notes/middleware/ghes-release-notes.js index aa73b87ed1..d1c6ee6175 100644 --- a/src/release-notes/middleware/ghes-release-notes.js +++ b/src/release-notes/middleware/ghes-release-notes.js @@ -8,7 +8,18 @@ export default async function ghesReleaseNotesContext(req, res, next) { const [requestedPlan, requestedRelease] = req.context.currentVersion.split('@') if (requestedPlan !== 'enterprise-server') return next() - const ghesReleaseNotes = getReleaseNotes('enterprise-server', req.language) + // (This applies to ghae release notes too) + // We deliberately force the language to be English for now. + // The underlying reason is that the content (in data/release-notes/**/*.yml) + // is Markdown that does NOT use variables controlled by English-only + // things like product names. + // Therefore, the **nouns (like product names) get translated** instead + // of left as is. For example. "Le GitHubbe Cöpilotte" instead + // of "GitHub Copilot". + // Until the Markdown sources used for release notes have Liquid + // variables (like `{% data variables.product.prodname_ghe_cloud %}}`) + // we'll force the text to be that from English. + const ghesReleaseNotes = getReleaseNotes('enterprise-server', 'en') // If the requested GHES release isn't found in data/release-notes/enterprise-server/*, // and it IS a valid GHES release, try being helpful and redirecting to the old location. @@ -32,23 +43,35 @@ export default async function ghesReleaseNotesContext(req, res, next) { (r) => r.version === requestedRelease, ).patches - // Run the current release notes through the markdown rendering pipeline. - // Returns the current release's patches array: [{version, patchVersion, intro, date, sections}] - req.context.ghesReleaseNotes = await executeWithFallback( - req.context, - () => renderPatchNotes(currentReleaseNotes, req.context), - (enContext) => { - // Something in the release notes ultimately caused a Liquid - // rendering error. Let's start over and gather the English release - // notes instead. - const ghesReleaseNotes = getReleaseNotes('enterprise-server', 'en') - enContext.ghesReleases = formatReleases(ghesReleaseNotes) - const currentReleaseNotes = enContext.ghesReleases.find( - (r) => r.version === requestedRelease, - ).patches - return renderPatchNotes(currentReleaseNotes, enContext) - }, - ) + // This means the AUTOTITLE links are in the current language, but + // since we're already force the source of the release notes from English + // exclusively, by doing this we can force all reusables to be in English + // too and leave links as is. + const originalLanguage = req.context.currentLanguage + req.context.autotitleLanguage = originalLanguage + req.context.currentLanguage = 'en' + + try { + // Run the current release notes through the markdown rendering pipeline. + // Returns the current release's patches array: [{version, patchVersion, intro, date, sections}] + req.context.ghesReleaseNotes = await executeWithFallback( + req.context, + () => renderPatchNotes(currentReleaseNotes, req.context), + (enContext) => { + // Something in the release notes ultimately caused a Liquid + // rendering error. Let's start over and gather the English release + // notes instead. + enContext.ghesReleases = formatReleases(ghesReleaseNotes) + const currentReleaseNotes = enContext.ghesReleases.find( + (r) => r.version === requestedRelease, + ).patches + return renderPatchNotes(currentReleaseNotes, enContext) + }, + ) + } finally { + // Restore the original language + req.context.currentLanguage = originalLanguage + } // GHES release notes on docs started with 2.20 but older release notes exist on enterprise.github.com. // So we want to use _all_ GHES versions when calculating next and previous releases.