mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
Core: Apply hideLocale to Source getPage APIs
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@fumadocs/content-collections': patch
|
||||
---
|
||||
|
||||
Improve types
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-core': patch
|
||||
---
|
||||
|
||||
Apply `hideLocale` to Source `getPage` APIs
|
||||
@@ -19,7 +19,6 @@ import {
|
||||
type StructuredData,
|
||||
} from 'fumadocs-core/mdx-plugins';
|
||||
import type { z as Zod } from 'zod';
|
||||
import { type TableOfContents } from 'fumadocs-core/server';
|
||||
import {
|
||||
resolvePlugin,
|
||||
resolvePlugins,
|
||||
@@ -42,6 +41,9 @@ export interface TransformOptions
|
||||
rehypeCodeOptions?: RehypeCodeOptions | boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default TOC types support `ReactNode`, which isn't serializable
|
||||
*/
|
||||
export type SerializableTOC = {
|
||||
title: string;
|
||||
url: string;
|
||||
@@ -72,7 +74,7 @@ export async function transformMDX<D extends BaseDoc>(
|
||||
): Promise<
|
||||
D & {
|
||||
body: string;
|
||||
toc: InterfaceToObject<TableOfContents>;
|
||||
toc: SerializableTOC;
|
||||
/**
|
||||
* `StructuredData` for search indexes
|
||||
*/
|
||||
|
||||
@@ -25,19 +25,13 @@ export interface Separator {
|
||||
}
|
||||
|
||||
export interface Folder {
|
||||
/**
|
||||
* Optional id to be attached to folders
|
||||
*
|
||||
* @deprecated use `$ref`
|
||||
*/
|
||||
id?: string;
|
||||
|
||||
$ref?: {
|
||||
metaFile?: string;
|
||||
};
|
||||
|
||||
type: 'folder';
|
||||
name: ReactNode;
|
||||
description?: ReactNode;
|
||||
root?: boolean;
|
||||
defaultOpen?: boolean;
|
||||
index?: Item;
|
||||
|
||||
@@ -169,10 +169,22 @@ function indexPages(
|
||||
};
|
||||
}
|
||||
|
||||
export function createGetUrl(baseUrl: string): UrlFn {
|
||||
export function createGetUrl(baseUrl: string, i18n?: I18nConfig): UrlFn {
|
||||
return (slugs, locale) => {
|
||||
const paths = locale
|
||||
? [locale, ...baseUrl.split('/'), ...slugs]
|
||||
const hideLocale = i18n?.hideLocale ?? 'never';
|
||||
let urlLocale: string | undefined;
|
||||
|
||||
if (hideLocale === 'never') {
|
||||
urlLocale = locale;
|
||||
} else if (
|
||||
hideLocale === 'default-locale' &&
|
||||
locale !== i18n?.defaultLanguage
|
||||
) {
|
||||
urlLocale = locale;
|
||||
}
|
||||
|
||||
const paths = urlLocale
|
||||
? [urlLocale, ...baseUrl.split('/'), ...slugs]
|
||||
: [...baseUrl.split('/'), ...slugs];
|
||||
|
||||
return `/${paths.filter((v) => v.length > 0).join('/')}`;
|
||||
@@ -201,47 +213,44 @@ export function loader<Options extends LoaderOptions>(
|
||||
return createOutput(options) as ReturnType<typeof loader<Options>>;
|
||||
}
|
||||
|
||||
function createOutput({
|
||||
source,
|
||||
icon: resolveIcon,
|
||||
rootDir = '',
|
||||
transformers,
|
||||
baseUrl = '/',
|
||||
slugs: slugsFn = getSlugs,
|
||||
url: getUrl = createGetUrl(baseUrl),
|
||||
pageTree: pageTreeOptions = {},
|
||||
i18n,
|
||||
}: LoaderOptions): LoaderOutput<LoaderConfig> {
|
||||
function createOutput(options: LoaderOptions): LoaderOutput<LoaderConfig> {
|
||||
const {
|
||||
source,
|
||||
rootDir = '',
|
||||
baseUrl = '/',
|
||||
slugs: slugsFn = getSlugs,
|
||||
url: getUrl = createGetUrl(baseUrl, options.i18n),
|
||||
} = options;
|
||||
const storage = loadFiles(
|
||||
typeof source.files === 'function' ? source.files(rootDir) : source.files,
|
||||
{
|
||||
transformers,
|
||||
transformers: options.transformers,
|
||||
rootDir,
|
||||
getSlugs: slugsFn,
|
||||
},
|
||||
);
|
||||
const walker = indexPages(storage, getUrl, i18n?.languages);
|
||||
const walker = indexPages(storage, getUrl, options.i18n?.languages);
|
||||
const builder = createPageTreeBuilder();
|
||||
const pageTree =
|
||||
i18n === undefined
|
||||
options.i18n === undefined
|
||||
? builder.build({
|
||||
storage,
|
||||
resolveIcon,
|
||||
resolveIcon: options.icon,
|
||||
getUrl,
|
||||
...pageTreeOptions,
|
||||
...options.pageTree,
|
||||
})
|
||||
: builder.buildI18n({
|
||||
storage,
|
||||
resolveIcon,
|
||||
resolveIcon: options.icon,
|
||||
getUrl,
|
||||
i18n,
|
||||
...pageTreeOptions,
|
||||
i18n: options.i18n,
|
||||
...options.pageTree,
|
||||
});
|
||||
|
||||
return {
|
||||
_i18n: i18n,
|
||||
_i18n: options.i18n,
|
||||
pageTree: pageTree as LoaderOutput<LoaderConfig>['pageTree'],
|
||||
getPages(language = i18n?.defaultLanguage ?? '') {
|
||||
getPages(language = options.i18n?.defaultLanguage ?? '') {
|
||||
return Array.from(walker.i18n.get(language)?.values() ?? []);
|
||||
},
|
||||
getLanguages() {
|
||||
@@ -258,7 +267,7 @@ function createOutput({
|
||||
|
||||
return list;
|
||||
},
|
||||
getPage(slugs = [], language = i18n?.defaultLanguage ?? '') {
|
||||
getPage(slugs = [], language = options.i18n?.defaultLanguage ?? '') {
|
||||
return walker.i18n.get(language)?.get(slugs.join('/'));
|
||||
},
|
||||
getNodeMeta(node) {
|
||||
@@ -273,7 +282,7 @@ function createOutput({
|
||||
},
|
||||
// @ts-expect-error -- ignore this
|
||||
generateParams(slug, lang) {
|
||||
if (i18n) {
|
||||
if (options.i18n) {
|
||||
return this.getLanguages().flatMap((entry) =>
|
||||
entry.pages.map((page) => ({
|
||||
[slug ?? 'slug']: page.slugs,
|
||||
|
||||
@@ -209,6 +209,7 @@ function buildFolderNode(
|
||||
icon: ctx.options.resolveIcon?.(metadata?.icon) ?? index?.icon,
|
||||
root: metadata?.root,
|
||||
defaultOpen: metadata?.defaultOpen,
|
||||
description: metadata?.description,
|
||||
index,
|
||||
children,
|
||||
$ref: !ctx.options.noRef
|
||||
@@ -227,25 +228,14 @@ function buildFileNode(
|
||||
file: PageFile,
|
||||
ctx: PageTreeBuilderContext,
|
||||
): PageTree.Item {
|
||||
let urlLocale: string | undefined;
|
||||
const localized =
|
||||
findLocalizedFile(file.file.flattenedPath, 'page', ctx) ?? file;
|
||||
|
||||
const hideLocale = ctx.i18n?.hideLocale ?? 'never';
|
||||
if (hideLocale === 'never') {
|
||||
urlLocale = ctx.lang;
|
||||
} else if (
|
||||
hideLocale === 'default-locale' &&
|
||||
ctx.lang !== ctx.i18n?.defaultLanguage
|
||||
) {
|
||||
urlLocale = ctx.lang;
|
||||
}
|
||||
|
||||
const item: PageTree.Item = {
|
||||
type: 'page',
|
||||
name: localized.data.data.title,
|
||||
icon: ctx.options.resolveIcon?.(localized.data.data.icon),
|
||||
url: ctx.options.getUrl(localized.data.slugs, urlLocale),
|
||||
url: ctx.options.getUrl(localized.data.slugs, ctx.lang),
|
||||
$ref: !ctx.options.noRef
|
||||
? {
|
||||
file: localized.file.path,
|
||||
|
||||
@@ -6,6 +6,8 @@ export interface MetaData {
|
||||
root?: boolean | undefined;
|
||||
pages?: string[] | undefined;
|
||||
defaultOpen?: boolean | undefined;
|
||||
|
||||
description?: string | undefined;
|
||||
}
|
||||
|
||||
export interface PageData {
|
||||
|
||||
@@ -403,6 +403,6 @@ test('Internationalized Routing: Hide Prefix', () => {
|
||||
`);
|
||||
|
||||
expect(result.getPages().length).toBe(2);
|
||||
expect(result.getPage(['test'])?.url).toBe('/en/test');
|
||||
expect(result.getPage(['test'])?.url).toBe('/test');
|
||||
expect(result.getPage(['test'], 'cn')?.url).toBe('/cn/test');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user