This commit is contained in:
babayaga 2025-08-21 13:58:39 +02:00
parent 7a8e2606ba
commit 38823d946f
2 changed files with 34 additions and 12 deletions

View File

@ -6,6 +6,7 @@ import type { SidebarGroup as SidebarGroupType } from './types';
import type { MarkdownHeading } from 'astro';
import Translate from "@polymech/astro-base/components/i18n.astro";
import SidebarPersister from './SidebarPersister.astro';
import { I18N_SOURCE_LANGUAGE } from "config/config.js";
interface Props {
config: SidebarGroupType[];
@ -17,14 +18,24 @@ interface Props {
const { config, currentUrl, headings = [], pageNavigation = [] } = Astro.props;
const currentPath = currentUrl ? getCurrentPath(currentUrl) : '';
// Extract locale from URL path (e.g., /es/resources/ -> 'es')
let locale: string = I18N_SOURCE_LANGUAGE; // Default to source language
if (currentPath) {
const pathSegments = currentPath.split('/').filter(segment => segment);
// Check if first segment is a language code (2 letters)
if (pathSegments.length > 0 && /^[a-z]{2}$/.test(pathSegments[0])) {
locale = pathSegments[0];
}
}
// Process all sidebar groups
const processedGroups = await Promise.all(
config.map(group => processSidebarGroup(group, currentPath))
config.map(group => processSidebarGroup(group, currentPath, locale))
);
// Process page-level navigation
const processedPageNav = await Promise.all(
pageNavigation.map(group => processSidebarGroup({...group, isPageLevel: true}, currentPath))
pageNavigation.map(group => processSidebarGroup({...group, isPageLevel: true}, currentPath, locale))
);
---

View File

@ -2,6 +2,7 @@ import { getCollection } from 'astro:content';
import type { SidebarGroup, SidebarLink, SortFunction } from './types.js';
import { filterCollection, defaultFilters, type CollectionFilter } from '../../base/collections.js';
import { z } from 'zod';
import { I18N_SOURCE_LANGUAGE } from "config/config.js";
interface DirectoryStructure {
[key: string]: {
@ -19,6 +20,7 @@ export const SidebarGenerationOptionsSchema = z.object({
sortBy: z.enum(['alphabetical', 'date', 'custom']).default('alphabetical'),
customSort: z.any().optional(), // We'll validate this at runtime
filters: z.array(z.any()).optional(), // We'll validate this at runtime
locale: z.string().default(I18N_SOURCE_LANGUAGE), // Language code for URL generation, defaults to source language
}).strict();
// Define the proper TypeScript types
@ -30,6 +32,7 @@ export interface SidebarGenerationOptions {
sortBy: 'alphabetical' | 'date' | 'custom';
customSort?: (a: SidebarLink | SidebarGroup, b: SidebarLink | SidebarGroup) => number;
filters?: CollectionFilter[];
locale: string; // Required, defaults to I18N_SOURCE_LANGUAGE
}
/**
@ -84,7 +87,8 @@ export async function generateLinksFromDirectory(
* maxDepth: 3,
* collapsedByDefault: true,
* sortBy: 'date',
* filters: [hasTitle, isNotDraft]
* filters: [hasTitle, isNotDraft],
* locale: 'es' // Include language code in URLs
* });
*
* // Using the helper function
@ -119,7 +123,8 @@ export async function generateLinksFromDirectoryWithConfig(
validatedOptions.collapsedByDefault,
validatedOptions.sortBy,
validatedOptions.customSort,
entries
entries,
validatedOptions.locale
);
} catch (error) {
console.warn(`Could not load collection "${directory}":`, error);
@ -176,14 +181,15 @@ function buildSidebarFromStructure(
collapsedByDefault: boolean = false,
sortBy: SortFunction = 'alphabetical',
customSort?: (a: SidebarLink | SidebarGroup, b: SidebarLink | SidebarGroup) => number,
entries?: any[]
entries?: any[],
locale: string
): (SidebarLink | SidebarGroup)[] {
const items: (SidebarLink | SidebarGroup)[] = [];
// Process root level files first
if (structure['']?.files) {
const rootFiles = structure[''].files
.filter(entry => !isPageHidden(entry))
.map(entry => createSidebarLink(entry, baseDirectory, currentPath));
.map(entry => createSidebarLink(entry, baseDirectory, locale, currentPath));
// Add root files without sorting (will be sorted at the end)
items.push(...rootFiles);
@ -201,7 +207,7 @@ function buildSidebarFromStructure(
if (dirData.files.length > 0) {
const subFiles = dirData.files
.filter(entry => !isPageHidden(entry))
.map(entry => createSidebarLink(entry, baseDirectory, currentPath));
.map(entry => createSidebarLink(entry, baseDirectory, locale, currentPath));
subItems.push(...subFiles);
}
@ -217,7 +223,8 @@ function buildSidebarFromStructure(
collapsedByDefault,
sortBy,
customSort,
entries
entries,
locale
);
subItems.push(...nestedItems);
}
@ -249,7 +256,7 @@ function isPageHidden(entry: any): boolean {
/**
* Create a sidebar link from an entry
*/
function createSidebarLink(entry: any, baseDirectory: string, currentPath?: string): SidebarLink {
function createSidebarLink(entry: any, baseDirectory: string, locale: string, currentPath?: string): SidebarLink {
// Handle different collection schemas
let label = entry.id;
if (entry.data.title) {
@ -268,9 +275,12 @@ function createSidebarLink(entry: any, baseDirectory: string, currentPath?: stri
// Remove file extension from entry.id for clean URLs
const cleanId = entry.id.replace(/\.(md|mdx)$/, '');
// Generate href with locale if provided
const href = locale ? `/${locale}/${baseDirectory}/${cleanId}/` : `/${baseDirectory}/${cleanId}/`;
return {
label,
href: `/${baseDirectory}/${cleanId}/`,
href,
isCurrent: currentPath?.includes(`/${baseDirectory}/${cleanId}`) || false,
};
}
@ -349,7 +359,7 @@ function applySorting(
/**
* Process a sidebar group and generate links
*/
export async function processSidebarGroup(group: SidebarGroup, currentPath?: string): Promise<SidebarGroup> {
export async function processSidebarGroup(group: SidebarGroup, currentPath?: string, locale?: string): Promise<SidebarGroup> {
const processedGroup: SidebarGroup = {
label: group.label,
collapsed: group.collapsed,
@ -368,7 +378,8 @@ export async function processSidebarGroup(group: SidebarGroup, currentPath?: str
collapsedByDefault: group.autogenerate.collapsed ?? false,
currentDepth: 0,
sortBy,
customSort: group.autogenerate.customSort
customSort: group.autogenerate.customSort,
locale
}
);
processedGroup.items = items;