Towards a more flexible `pages` interface
In makedocs, the way to specify pages is currently pretty rigid - you can only pass in a very rigid nested array of strings (and indicate title / page path).
I, and many others, would like to have a more flexible way to define pages for the sidebar, so that we can e.g. define a section header that is also a page / clickable, and has sub-pages associated with it. This is already possible in DocumenterVitepress although you have to define the sidebar manually in the config.mts. The basic DimensionalData docs is a good example - the "Getting started" is a page, but is also the section header for that section of the docs. There are also subsidiary pages.
Another example is choosing which subsections of the sidebar to expand on a more granular level. At the moment, we only have the ability to set a global threshold for the nesting level at which things collapse. But I may want a top level section to be collapsed by default, and a lower level section to not be collapsed.
There is some current functionality that is slightly similar, and that's hide - which takes any pages-compatible structure / type, and returns a 4-tuple of (hidden::Bool, title::String, path::String, children::Vector) (I think). So my first thought is that we should make this a struct that people can instantiate, and include some more metadata. A basic prototype might be (borrowing from Documenter.NavNode):
struct PageNode
# page contents
page::Union{String, Nothing}
children::Vector{PageNode}
# metadata
title_override::Union{String, Nothing}
visible::Union{Bool, Nothing}
collapsed::Union{Bool, Nothing} # nothing here indicates that we follow the global spec
end
Constructor
PageNode(input::Pair; kw...) = PageNode(input[1], input[2]; kw...)
PageNode(input::String; visible = nothing, collapsed = nothing) = PageNode(input, PageNode[], nothing, visible, collapsed)
function PageNode(input::Vector; kw...)
children = PageNode.(input; kw...)
return PageNode(nothing, children, nothing, visible, collapsed)
end
function PageNode(titlechildren::Pair{String, Vector}; kw...)
children = PageNode.(titlechildren[2]; kw...)
return PageNode(nothing, children, titlechildren[1], visible, collapsed)
end
function PageNode(original_page, children::Vector; kw...)
pn1 = PageNode(original_page; kw...)
@assert isempty(pn1.children) "You can't specify multiple children! Look at the type of the first argument to this function."
return PageNode(pn1.page, PageNode.(children; kw...), pn1.title_override, pn1.visible, pn1.collapsed)
end
and then we can recursively parse all input to pages into PageNodes.
@mortenpi mentioned that we could initially disallow collapsing pagenodes that have a non-nothing page but non-empty children, pending a section collapser element in the UI.
The main parser is in walk_navpages so that's where we have to inject the override.
https://github.com/JuliaDocs/Documenter.jl/blob/6abd8288164285ac58e4234f36c64b13029792e1/src/builder_pipeline.jl#L181
cc: @mortenpi @fredrikekre
x-ref https://github.com/JuliaDocs/Documenter.jl/issues/344
Thanks! That seems to be incompatible with the current NavNode structure, see here:
https://github.com/JuliaDocs/Documenter.jl/blob/6abd8288164285ac58e4234f36c64b13029792e1/src/documents.jl#L236-L241
but I'm sure that with some effort we could fix that...
Yeah if you're thinking about making it more flexible, this is something that people keep asking for.
See also https://github.com/JuliaDocs/Documenter.jl/issues/701.
Initial prototype up and running (pages but no external links or collapsing spec yet) - it just worked!!
https://github.com/asinghvi17/DocumenterPages.jl
https://github.com/JuliaDocs/Documenter.jl/blob/6abd8288164285ac58e4234f36c64b13029792e1/src/html/HTMLWriter.jl#L1237 is where the collapsing logic goes
Please add the collapsing logic. Our docs organize pages into folders and now the navbar is way too long for an easy overview. It would be nice to have the folders collapsed with an arrow (>) that expands to show the pages.
For example, I would like the Tutorials folder to be collapsed until they click on it. From what I've seen of 'hide', it doesn't work for this case because the pages would never become visible.