diff --git a/src/components/LeftSidebar/LeftSidebar.astro b/src/components/LeftSidebar/LeftSidebar.astro index c3e73a7c94935..edf6e18ec6b90 100644 --- a/src/components/LeftSidebar/LeftSidebar.astro +++ b/src/components/LeftSidebar/LeftSidebar.astro @@ -35,7 +35,7 @@ let activeTab: 'learn' | 'api' = 'learn'; // Certain pages are not in the sidebar nav, so we manually set the active tab based on other factors (e.g. Algolia page category). const isReference = ['Error Reference', 'Reference'].includes( - getPageCategory(new URL(currentPage, import.meta.url)) + getPageCategory({ pathname: currentPage }) ); if (isReference) { activeTab = 'api'; diff --git a/src/components/LeftSidebar/SidebarContent.astro b/src/components/LeftSidebar/SidebarContent.astro index 6afd711d034ab..22eb038d2334b 100644 --- a/src/components/LeftSidebar/SidebarContent.astro +++ b/src/components/LeftSidebar/SidebarContent.astro @@ -1,5 +1,6 @@ --- -import { getLanguageFromURL, removeSubpageSegment } from '../../util'; +import { getLanguageFromURL } from '~/util'; +import { isSubPage } from '~/util/isSubPage'; export interface Props { type: TabType; @@ -44,11 +45,7 @@ const lang = getLanguageFromURL(Astro.url.pathname); {isFallback && EN} diff --git a/src/content/docs/es/core-concepts/sharing-state.mdx b/src/content/docs/es/core-concepts/sharing-state.mdx index 8d56c02654dda..b8b00fa6f7fd2 100644 --- a/src/content/docs/es/core-concepts/sharing-state.mdx +++ b/src/content/docs/es/core-concepts/sharing-state.mdx @@ -1,6 +1,8 @@ --- title: Compartiendo Estado +description: Learn how to share state across components — and frameworks! — with Nano Stores. i18nReady: true +type: recipe --- import UIFrameworkTabs from '~/components/tabs/UIFrameworkTabs.astro' diff --git a/src/content/docs/es/guides/rss.mdx b/src/content/docs/es/guides/rss.mdx index 18566819280b7..22f2f3bc934d5 100644 --- a/src/content/docs/es/guides/rss.mdx +++ b/src/content/docs/es/guides/rss.mdx @@ -2,6 +2,7 @@ title: RSS description: Introducción a RSS en Astro i18nReady: true +type: recipe --- import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; diff --git a/src/content/docs/fr/core-concepts/sharing-state.mdx b/src/content/docs/fr/core-concepts/sharing-state.mdx index 33d33a24e3a88..cc293957de0b5 100644 --- a/src/content/docs/fr/core-concepts/sharing-state.mdx +++ b/src/content/docs/fr/core-concepts/sharing-state.mdx @@ -1,6 +1,8 @@ --- title: Partage d'État +description: Learn how to share state across components — and frameworks! — with Nano Stores. i18nReady: true +type: recipe --- import UIFrameworkTabs from '~/components/tabs/UIFrameworkTabs.astro' import LoopingVideo from '~/components/LoopingVideo.astro' diff --git a/src/content/docs/fr/guides/rss.mdx b/src/content/docs/fr/guides/rss.mdx index 851447f047e8d..f2675796abf3c 100644 --- a/src/content/docs/fr/guides/rss.mdx +++ b/src/content/docs/fr/guides/rss.mdx @@ -1,6 +1,7 @@ --- title: Flux RSS description: Une introduction aux flux RSS avec Astro. +type: recipe --- import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro' import Since from '~/components/Since.astro' diff --git a/src/content/docs/ja/guides/rss.mdx b/src/content/docs/ja/guides/rss.mdx index 6c30742fddaf2..1d2e707a0bbe8 100644 --- a/src/content/docs/ja/guides/rss.mdx +++ b/src/content/docs/ja/guides/rss.mdx @@ -2,6 +2,7 @@ title: RSS description: AstroのRSS入門 i18nReady: true +type: recipe --- import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro' diff --git a/src/content/docs/pt-br/core-concepts/sharing-state.mdx b/src/content/docs/pt-br/core-concepts/sharing-state.mdx index c6c22bb71ff17..e4a2497bfec32 100644 --- a/src/content/docs/pt-br/core-concepts/sharing-state.mdx +++ b/src/content/docs/pt-br/core-concepts/sharing-state.mdx @@ -1,6 +1,8 @@ --- title: Compartilhamento de Estado +description: Aprenda como compartilhar estado entre componentes — e frameworks! — com Nano Stores. i18nReady: true +type: recipe --- import UIFrameworkTabs from '~/components/tabs/UIFrameworkTabs.astro'; import LoopingVideo from '~/components/LoopingVideo.astro'; diff --git a/src/content/docs/pt-br/guides/rss.mdx b/src/content/docs/pt-br/guides/rss.mdx index 34e5612d5f5bd..3feec642bce5a 100644 --- a/src/content/docs/pt-br/guides/rss.mdx +++ b/src/content/docs/pt-br/guides/rss.mdx @@ -2,6 +2,7 @@ title: RSS description: Uma introdução a RSS em Astro i18nReady: true +type: recipe --- import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'; import Since from '~/components/Since.astro'; diff --git a/src/content/docs/zh-cn/core-concepts/sharing-state.mdx b/src/content/docs/zh-cn/core-concepts/sharing-state.mdx index cbdb1d9e99ca8..447a66ff9f457 100644 --- a/src/content/docs/zh-cn/core-concepts/sharing-state.mdx +++ b/src/content/docs/zh-cn/core-concepts/sharing-state.mdx @@ -1,6 +1,8 @@ --- title: 状态共享 +description: Learn how to share state across components — and frameworks! — with Nano Stores. i18nReady: false +type: recipe --- import UIFrameworkTabs from '~/components/tabs/UIFrameworkTabs.astro' import LoopingVideo from '~/components/LoopingVideo.astro' diff --git a/src/content/docs/zh-cn/guides/rss.mdx b/src/content/docs/zh-cn/guides/rss.mdx index bb968203569d8..82fa6c884bc62 100644 --- a/src/content/docs/zh-cn/guides/rss.mdx +++ b/src/content/docs/zh-cn/guides/rss.mdx @@ -1,6 +1,7 @@ --- title: RSS description: Astro RSS 介绍 +type: recipe --- Astro 支持为博客和其他内容网站快速自动生成 RSS 摘要。更多关于 RSS 摘要的信息参见 [aboutfeeds.com](https://aboutfeeds.com/)。 diff --git a/src/util.ts b/src/util.ts index bf526d70fba2c..0b43ae52668ce 100644 --- a/src/util.ts +++ b/src/util.ts @@ -21,18 +21,3 @@ export const stripLangFromSlug = (slug: CollectionEntry<'docs'>['slug']) => /** Get a page’s lang tag from its slug (e.g. `'en/migrate'` => `'en'`). */ export const getLangFromSlug = (slug: CollectionEntry<'docs'>['slug']) => slug.split('/')[0]; - -/** Remove the subpage segment of a URL string */ -export function removeSubpageSegment(path: string) { - // Include new pages with subpages as part of this regex. - const regex = /(?:install|deploy|integrations-guide|tutorial|migrate-to-astro|recipes|cms)\//; - const matches = regex.exec(path); - - if (matches) { - const matchIndex = matches.index; - // Get the first slash index after the main page path segment. - const slashIndex = path.slice(matchIndex).indexOf('/') + matchIndex; - return path.slice(0, slashIndex); - } - return path; -} diff --git a/src/util/getPageCategory.ts b/src/util/getPageCategory.ts index 17ded868b6d61..d7c5af7815b49 100644 --- a/src/util/getPageCategory.ts +++ b/src/util/getPageCategory.ts @@ -16,7 +16,7 @@ const categories = [ * @param url URL for the current page. * @returns The category for the current page as used by Algolia DocSearch to group search results. */ -export function getPageCategory(url: URL) { +export function getPageCategory(url: { pathname: string }) { const langAgnosticPath = url.pathname.replace(/\/\w\w(-\w\w)?\//, ''); for (const [path, label] of categories) { if (langAgnosticPath.startsWith(path)) return label; diff --git a/src/util/isSubPage.ts b/src/util/isSubPage.ts new file mode 100644 index 0000000000000..9de1b984f019c --- /dev/null +++ b/src/util/isSubPage.ts @@ -0,0 +1,49 @@ +import type { CollectionEntry } from 'astro:content'; +import { englishPages } from '~/content'; +import { getPageCategory } from './getPageCategory'; + +/** Remove the sub-page segment of a URL string */ +export function removeSubPageSegment(path: string) { + // Include new pages with sub-pages as part of this regex. + const regex = /(?:install|deploy|integrations-guide|tutorial|migrate-to-astro|recipes|cms)\//; + const matches = regex.exec(path); + + if (matches) { + const matchIndex = matches.index; + // Get the first slash index after the main page path segment. + const slashIndex = path.slice(matchIndex).indexOf('/') + matchIndex; + return path.slice(0, slashIndex); + } + return path; +} + +const typeIndexes: Partial['data']['type'], string>> = { + recipe: 'recipes', +}; + +const categoryIndex: Partial, string>> = { + 'Error Reference': 'reference/error-reference', +}; + +/** + * Test if `currentPage` is considered a sub-page of `parentSlug`. + * @param currentPage The full slug for the current page, e.g. `'en/guides/rss'` + * @param parentSlug The language-less slug for the parent to test against e.g. `'guides/content-collections'` + */ +export function isSubPage(currentPage: string, parentSlug: string): boolean { + // Test 1: do the two pages share a base URL segment? + if (removeSubPageSegment(currentPage).endsWith(removeSubPageSegment(parentSlug))) { + return true; + } + // Test 2: is there a known parent page for this page category? + const category = getPageCategory({ pathname: '/' + currentPage + '/' }); + if (categoryIndex[category] === parentSlug) { + return true; + } + // Test 3: is there a known parent page for this page type? + const type = englishPages.find(({ slug }) => slug === currentPage)?.data.type; + if (type && typeIndexes[type] === parentSlug) { + return true; + } + return false; +}