@@ -11,6 +11,7 @@ import { RestBanner } from 'src/rest/components/RestBanner'
|
||||
import { useMainContext } from 'components/context/MainContext'
|
||||
import { useTranslation } from 'src/languages/components/useTranslation'
|
||||
import { Breadcrumbs } from 'components/page-header/Breadcrumbs'
|
||||
import { useLanguages } from 'src/languages/components/LanguagesContext'
|
||||
|
||||
const MINIMAL_RENDER = Boolean(JSON.parse(process.env.MINIMAL_RENDER || 'false'))
|
||||
|
||||
@@ -30,6 +31,7 @@ export const DefaultLayout = (props: Props) => {
|
||||
const { t } = useTranslation(['errors', 'meta', 'scroll_button'])
|
||||
const router = useRouter()
|
||||
const metaDescription = page.introPlainText ? page.introPlainText : t('default_description')
|
||||
const { languages } = useLanguages()
|
||||
|
||||
// This is only true when we do search indexing which renders every page
|
||||
// just to be able to `cheerio` load the main body (and the meta
|
||||
@@ -66,16 +68,20 @@ export const DefaultLayout = (props: Props) => {
|
||||
{/* For Google and Bots */}
|
||||
<meta name="description" content={metaDescription} />
|
||||
{page.hidden && <meta name="robots" content="noindex" />}
|
||||
{page.languageVariants.map((languageVariant) => {
|
||||
return (
|
||||
<link
|
||||
key={languageVariant.href}
|
||||
rel="alternate"
|
||||
hrefLang={languageVariant.hreflang}
|
||||
href={`https://docs.github.com${languageVariant.href}`}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
{Object.values(languages)
|
||||
.filter((lang) => lang.code !== router.locale)
|
||||
.map((variant) => {
|
||||
return (
|
||||
<link
|
||||
key={variant.code}
|
||||
rel="alternate"
|
||||
hrefLang={variant.hreflang || variant.code}
|
||||
href={`https://docs.github.com/${variant.code}${
|
||||
router.asPath === '/' ? '' : router.asPath
|
||||
}`}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
|
||||
{/* For local site search indexing */}
|
||||
{page.topics.length > 0 && <meta name="keywords" content={page.topics.join(',')} />}
|
||||
|
||||
@@ -55,6 +55,7 @@ type EnterpriseServerReleases = {
|
||||
nextDeprecationDate: string
|
||||
supported: Array<string>
|
||||
}
|
||||
|
||||
export type MainContextT = {
|
||||
breadcrumbs: {
|
||||
product: BreadcrumbT
|
||||
@@ -83,7 +84,6 @@ export type MainContextT = {
|
||||
page: {
|
||||
documentType: string
|
||||
type?: string
|
||||
languageVariants: Array<{ name: string; code: string; hreflang: string; href: string }>
|
||||
topics: Array<string>
|
||||
title: string
|
||||
fullTitle?: string
|
||||
@@ -154,7 +154,6 @@ export const getMainContext = async (req: any, res: any): Promise<MainContextT>
|
||||
currentPathWithoutLanguage: req.context.currentPathWithoutLanguage,
|
||||
relativePath: req.context.page?.relativePath,
|
||||
page: {
|
||||
languageVariants: req.context.page.languageVariants,
|
||||
documentType,
|
||||
type: req.context.page.type || null,
|
||||
title: req.context.page.title,
|
||||
|
||||
18
lib/page.js
18
lib/page.js
@@ -1,14 +1,11 @@
|
||||
import assert from 'assert'
|
||||
import path from 'path'
|
||||
import cheerio from 'cheerio'
|
||||
import patterns from './patterns.js'
|
||||
import getApplicableVersions from '#src/versions/lib/get-applicable-versions.js'
|
||||
import generateRedirectsForPermalinks from '#src/redirects/lib/permalinks.js'
|
||||
import getEnglishHeadings from './get-english-headings.js'
|
||||
import getTocItems from './get-toc-items.js'
|
||||
import pathUtils from './path-utils.js'
|
||||
import Permalink from './permalink.js'
|
||||
import languages from '#src/languages/lib/languages.js'
|
||||
import { renderContent } from '#src/content-render/index.js'
|
||||
import processLearningTracks from '#src/learning-track/lib/process-learning-tracks.js'
|
||||
import { productMap } from './all-products.js'
|
||||
@@ -329,21 +326,6 @@ class Page {
|
||||
static getHomepage(requestPath) {
|
||||
return requestPath.replace(/\/articles.*/, '')
|
||||
}
|
||||
|
||||
// given a page path, return an array of objects containing hrefs
|
||||
// for that page in all languages
|
||||
static getLanguageVariants(href) {
|
||||
const suffix = pathUtils.getPathWithoutLanguage(href)
|
||||
return Object.values(languages).map(({ name, code, hreflang }) => {
|
||||
// eslint-disable-line
|
||||
return {
|
||||
name,
|
||||
code,
|
||||
hreflang,
|
||||
href: `/${code}${suffix}`.replace(patterns.trailingSlash, '$1'),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Page
|
||||
|
||||
@@ -3,7 +3,6 @@ import { get } from 'lodash-es'
|
||||
import FailBot from '#src/observability/lib/failbot.js'
|
||||
import patterns from '../lib/patterns.js'
|
||||
import getMiniTocItems from '../lib/get-mini-toc-items.js'
|
||||
import Page from '../lib/page.js'
|
||||
import { pathLanguagePrefixed } from '#src/languages/lib/languages.js'
|
||||
import statsd from '#src/observability/lib/statsd.js'
|
||||
import { allVersions } from '#src/versions/lib/all-versions.js'
|
||||
@@ -88,9 +87,6 @@ export default async function renderPage(req, res) {
|
||||
res.setHeader('Last-Modified', new Date(page.effectiveDate).toUTCString())
|
||||
}
|
||||
|
||||
// collect URLs for variants of this page in all languages
|
||||
page.languageVariants = Page.getLanguageVariants(path)
|
||||
|
||||
// Stop processing if the connection was already dropped
|
||||
if (isConnectionDropped(req, res)) return
|
||||
|
||||
|
||||
@@ -125,6 +125,10 @@ MyApp.getInitialProps = async (appContext: AppContext) => {
|
||||
name: langObj.name,
|
||||
code: langObj.code,
|
||||
}
|
||||
// The `hreflang` is used for the `<link rel="alternate">` tags.
|
||||
if (langObj.hreflang && langObj.hreflang !== langObj.code) {
|
||||
languagesContext.languages[langCode].hreflang = langObj.hreflang
|
||||
}
|
||||
if (langObj.nativeName) {
|
||||
languagesContext.languages[langCode].nativeName = langObj.nativeName
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ export type LanguageItem = {
|
||||
name: string
|
||||
nativeName?: string
|
||||
code: string
|
||||
hreflang?: string
|
||||
}
|
||||
|
||||
export type LanguagesContextT = {
|
||||
|
||||
@@ -306,20 +306,6 @@ describe('Page class', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('Page.getLanguageVariants()', () => {
|
||||
it('returns an array of language variants of the given URL', () => {
|
||||
const variants = Page.getLanguageVariants('/en')
|
||||
expect(variants.every((variant) => variant.name)).toBe(true)
|
||||
expect(variants.every((variant) => variant.code)).toBe(true)
|
||||
expect(variants.every((variant) => variant.href)).toBe(true)
|
||||
})
|
||||
|
||||
it('works for the homepage', () => {
|
||||
const variants = Page.getLanguageVariants('/en')
|
||||
expect(variants.find(({ code }) => code === 'en').href).toBe('/en')
|
||||
})
|
||||
})
|
||||
|
||||
describe('page.versions frontmatter', () => {
|
||||
test('pages that use short names in versions frontmatter', async () => {
|
||||
const page = await Page.init({
|
||||
|
||||
Reference in New Issue
Block a user