diff --git a/lib/web/docusaurus/dsite_generate_docs.v b/lib/web/docusaurus/dsite_generate_docs.v index 8e81fa3f..930227d8 100644 --- a/lib/web/docusaurus/dsite_generate_docs.v +++ b/lib/web/docusaurus/dsite_generate_docs.v @@ -117,6 +117,9 @@ fn (mut generator SiteGenerator) page_generate(args_ Page) ! { page_content = markdowntools.set_titles(page_content, args.title_nr) } + // Fix links to account for nested categories + page_content = generator.fix_links(page_content) + c += '\n${page_content}\n' if args.path.ends_with('/') || args.path.trim_space() == '' { @@ -155,3 +158,48 @@ fn (mut generator SiteGenerator) section_generate(args_ Section) ! { catfile.write(c)! } + +// Fix links to account for nested categories in Docusaurus +// Doctree exports links as ../collection/page.md but Docusaurus may have nested paths +fn (generator SiteGenerator) fix_links(content string) string { + mut result := content + + // Build a map of collection name to actual directory path + mut collection_paths := map[string]string{} + for page in generator.site.pages { + parts := page.src.split(':') + if parts.len != 2 { + continue + } + collection := parts[0] + + // Extract directory path from page.path + // page.path can be like "appendix/internet_today/" or "appendix/internet_today/page.md" + mut dir_path := page.path.trim('/') + + // If path ends with a filename, remove it to get just the directory + if dir_path.contains('/') && !dir_path.ends_with('/') { + // Check if last part looks like a filename (has extension or is a page name) + last_part := dir_path.all_after_last('/') + if last_part.contains('.') || last_part == parts[1] { + dir_path = dir_path.all_before_last('/') + } + } + + // If the directory path is different from collection name, store the mapping + // This handles nested categories like appendix/internet_today + if dir_path != collection && dir_path != '' { + collection_paths[collection] = dir_path + } + } + + // Replace ../collection/ with ../actual/nested/path/ for nested collections + for collection, actual_path in collection_paths { + result = result.replace('../${collection}/', '../${actual_path}/') + } + + // Remove .md extensions from all links (Docusaurus doesn't use them in URLs) + result = result.replace('.md)', ')') + + return result +} diff --git a/lib/web/site/play_page.v b/lib/web/site/play_page.v index 011d0250..535ea5b2 100644 --- a/lib/web/site/play_page.v +++ b/lib/web/site/play_page.v @@ -91,7 +91,11 @@ fn play_pages(mut plbook PlayBook, mut site Site) ! { section_current.name)!)!)! mut pagepath := p.get_default('path', section_current.path)! pagepath = pagepath.trim_space().trim('/') - pagepath = texttools.name_fix(pagepath) + // Only apply name_fix if it's a simple name (no path separators) + // For paths like 'appendix/internet_today', preserve the structure + if !pagepath.contains('/') { + pagepath = texttools.name_fix(pagepath) + } // Ensure pagepath ends with / to indicate it's a directory path if pagepath.len > 0 && !pagepath.ends_with('/') { pagepath += '/'