Repository navigation
Top menu from pages - #2904
Top menu from pages#2904lmiq wants to merge 56 commits into
Conversation
Implements a new `top_menu` keyword argument for `makedocs` that enables upper-level organization of documentation with a horizontal navigation bar at the top of the page. ## New Features - **`top_menu` keyword**: Accepts a vector of section pairs, where each section has a title and a nested page structure identical to the `pages` argument format - **Section-based navigation**: Each section maintains its own navigation tree in the sidebar, switching automatically when clicking between sections - **Theme-aware styling**: Top menu bar uses sidebar theme variables for consistent appearance across all themes (light, dark, catppuccin variants) ## Implementation Details - Added `TopMenuSection` struct in documents.jl to hold section metadata - Extended `walk_navpages` to support section-specific navlist population - Added `render_top_menu` and helper functions in HTMLWriter.jl - Created new SCSS styles in _topmenu.scss with responsive mobile support - Active section highlighted with bottom border indicator ## Documentation & Tests - Added comprehensive documentation in makedocs.jl keyword docs - Added user guide section in docs/src/man/guide.md - Added unit tests for TopMenuSection and walk_navpages - Added example build in test/examples with multi-section structure ## Behavior Notes - First section in top_menu determines the landing page - Pages should be unique across sections (warns on duplicates) - Fully backward compatible - existing docs without top_menu unchanged
- Verify top_menu_sections are created correctly - Verify section titles and navlists - Verify first_page is set for each section - Verify HTML files are generated in correct locations - Verify redirect index.html is generated at root - Verify top menu elements appear in generated HTML - Verify has-top-menu class is applied
Use joinpath for cross-platform path comparison in first_page assertions
Done — top_menu is now a keyword argument of HTML (e.g. format = HTML(top_menu = true)) and has been removed from makedocs. The documentation and the example in test/examples/make.jl have been updated accordingly. 2. Removing top_menu logic from the builder pipeline Done — the builder pipeline now always follows the original code path, with no awareness of top_menu. TopMenuSection was moved to HTMLWriter.jl, and a build_top_menu_sections function derives the per-section navtrees and navlists directly from the already-built global doc.internal.navtree at render time. The navlist keyword argument that had been added to walk_navpages was also removed. 3. Removing the redirect index.html Done — the redirect generation has been removed entirely. The file structure is now unchanged when top_menu is enabled; the top bar is purely a per-page HTML addition. The landing page warning was also restored to its original unconditional form, and the redirect-related test assertions were dropped. 4. Accessing top_menu via ctx in render_html Done — the top_menu keyword argument has been removed from render_html. The function now takes navnode as a positional argument and calls render_top_menu(ctx, navnode) internally, so the top menu is derived from ctx rather than passed in from the call site.
|
Incorporated the changes suggested above. I'm still testing and fixing bugs. |
…g name and text via new(TEXT, text), leaving attributes and nodes as #undef. When navitem() returns DOM.Node("") (an empty text node because no nav items are visible), render_sidebar at line 1521 tries push!(menu.attributes, ...) and hits the uninitialized field.
The fix initializes all four fields: new(TEXT, text, Attributes(), Node[]).
…vtree (children) is empty — like "Home" => "index.md" which is a leaf node with no children — it now falls back to the full ctx.doc.internal.navtree instead of returning an empty list. This means the sidebar will show all top-level menu entries when viewing index.md, rather than being empty.
…s navtree will be [top_node] instead of []. This means: The top menu shows "Home", "Getting started", "Structure" as before When viewing index.md, the sidebar shows "Home" as a single entry with its in-page headings (h2s etc.) When viewing pages under "Getting started", the sidebar shows that section's pages The UndefRefError from the previous conversation is also gone since we no longer produce an empty text node for the menu
|
Seems to be working: Test pages: https://m3g.github.io/FundamentosDMC.jl/dev https://m3g.github.io/PDBTools.jl/dev/ https://m3g.github.io/ComplexMixtures.jl/dev/ When there is no index.md file at the top level, we are redirecting. The issue with avoiding the redirection is that relative paths might break if we move to the top level the index.md file - particularly those within raw html blocks. I think that if there is no root/index.md file, just creating one that redirects to the first "index.md" file found in the pages tree is a good alternative. If there is a root/index.md file, then no redirection occurs. |
Top menu from pages dev
# Conflicts: # assets/html/themes/catppuccin-frappe.css # assets/html/themes/catppuccin-latte.css # assets/html/themes/catppuccin-macchiato.css # assets/html/themes/catppuccin-mocha.css # assets/html/themes/documenter-dark.css # assets/html/themes/documenter-light.css
|
Claude AI and me just resolved the merge conflicts (by running Now the review. I built the example docs locally and poked at a few edge cases; findings below, roughly in order of severity. Blockers1. The docs describe the wrong API. Related design question: should it be on 2. The new tests don't run.
3. 4. pages = ["Sec A" => ["index.md"], hide("Sec B" => "other.md", ["hidden.md"])]"Sec B" shows up in the top bar and its dropdown lists the hidden page. 5. No validation of the 6. CI formatting. 7. CHANGELOG. The entry links Should fix8. The 9. Dead code: 10. Per-page linear scans. 11. The redirect 12. A section node that has both a page and children loses its own page. 13. Unrelated churn, worth dropping to keep the diff reviewable: the 14. The Minor
Overall the layout and CSS side looks solid and the generated markup is clean — most of what's above is documentation drift, missing validation, and tests that were never executed. |
* Document `top_menu` as an option of `Documenter.HTML` (guide and CHANGELOG), move the CHANGELOG entry to Unreleased and link JuliaDocs#2904. * Validate the shape of `pages`: every top-level entry must have a section title. * Respect `hide`: hidden sections are not shown in the top menu, and hidden pages are not listed in the dropdowns. * Keep the page of a section that is a page with sub-pages in the section's sidebar. * Keep the previous/next page links within each section. * Map pages to sections once, instead of scanning all sections for every rendered page; remove the unused `find_navnode_for_page`. * Drop the redirect `index.html` feature, to be discussed separately. * Use the icon font for the dropdown caret and add ARIA attributes. * Revert unrelated changes (DOM.jl, builder_pipeline.jl, documents.jl, docs/Project.toml) and fix the Biome formatting of sidebar.js. * Fix the tests: move the edge-case tests to unit tests in test/topmenu.jl, remove `warnonly` from the example build, and cover hidden sections, page + sub-pages sections and prev/next links. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
top_menu: address review of JuliaDocs#2904
The HTML docstring is also rendered in docs/src/lib/internals/writers.md, where a bare `makedocs` can not be resolved from the HTMLWriter module. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This PR now addresses the review of the Blockers
Should fix
Minor
Testing
AI disclosure: this change was prepared with the help of Claude Code (Claude Opus 5.5), and reviewed by me. 🤖 Generated with Claude Code |
This is a variation of #2866 where instead of adding a
top_menuvector that replaces thepagesvector, atop_menu=trueoption is added to
makedocs, which will interpret the first layer of the documentation menu as the top menu.if
top_menu=falsethe common (current - no top-menu) behavior is preserved.This is a nice alternative for the interface, indeed.
@mortenpi