A document's own address — where it is read when its admin gives it one, /chelekom/docs — and
where each of its pages is read under it.
A document with no address is read under the documentation's base by its slug, as it always was:
/docs/<slug>, its pages /docs/<slug>/<page>. One with an address is read there and nowhere
else: /chelekom/docs, its pages /chelekom/docs/<page>, and /docs/chelekom is a missing
page, as any slug that names no document there is.
A page's own part of the address is the slugs of the pages it is filed under, then its own:
headless/switch is the page switch filed under headless. A slug is unique among the pages
that share its parent, so the same name may be used under two parents — /chelekom/docs/tabs and
/chelekom/docs/headless/tabs are two pages.
A version's front page (front_page, a page at the top) is drawn at the document's own address:
its own part of the address is empty, so /chelekom/docs is that page, /chelekom/docs/<its slug>
is a missing page, and the pages filed under it sit directly under the document's address.
A group (group_heading) is only a heading in the contents: it has no address at all, and the
pages filed under it are addressed as if it were not there — breadcrumb under the group
navigation is /chelekom/docs/breadcrumb, and /chelekom/docs/navigation is a missing page.
A group with a page of its own (group_page) is read at its own slug — /chelekom/docs/navigation
— as any page is, and the pages filed under it still leave its slug out: breadcrumb stays
/chelekom/docs/breadcrumb. group_page on a page that is not a group changes nothing.
An address is a site path: segments of lower-case letters, digits and dashes, and :lang at most
once, where the site's language goes, as in a page's path. The rules live here because the
document, its pages, the head and the sitemap all read them, and must agree.
Summary
Functions
Whether a page has an address: any page but a group with no page of its own.
:ok for a stored address the site can answer, else {:error, reason}: :not_a_path, or
:in_docs_base for one under the base the documents with no address are read in.
Whether a page is its version's front page, drawn at its document's own address.
Whether a page is a group: a heading in the contents whose slug the pages under it leave out of their address.
Whether a page is a group with a page of its own, read at its own slug.
Whether an address holds the site's language.
The address as it is stored: trimmed, lower case, one leading slash and no trailing one. nil for
nothing at all, and a value that is not a path is handed back as it was, for check/1 to refuse.
The address a page at page_path serves — the page path itself, or the path a *section capture
closes — and nil for any other kind of path.
Whether one address holds the other — the same, or one under the other — so one document's pages
would answer at the other's: /chelekom/docs and /chelekom/docs/headless overlap.
The page among sections whose own part of the address is segments — ["headless", "switch"],
or the "headless/switch" a *section capture holds — or nil. Nothing asked, [] or "", is
the front page, when they hold one. A group is the page at an address only when it has a page of
its own.
The two page paths a document at address is read at: its front page, and every page of it.
Every page's own part of its address among sections — the pages of one version a reader is
shown, each with its id, slug, parent_section_id, front_page, group_heading and
group_page — as %{id => ["headless", "switch"]}, and [] for the front page. A group with no
page of its own has none, and is not in it.
A page's own part of its address, root first: the slugs of the pages it is drawn under, then its
own, a front page's and a group's left out — [] for the front page itself. A group with a page of
its own keeps its own slug in its own address, and only there. parent_of answers the parent each
page is drawn under, or nil at the top — which may not be the parent it names, when that one is
not published. A parent chain deeper than twenty, which only a loop makes, stops there.
The segments of an address, :lang among them.
The query a reader reaches version at among its document's published versions
(version_shown/2): %{} for the one shown when none is asked, %{"v" => version_number} for
another, and nil for one no ?v= reaches — not among them, or sharing its number with a newer
one. Versions are told apart by their id.
The version a reader is shown among a document's published versions, each with its
version_number, is_latest_for_version, published_at and inserted_at: the one asked names
(?v=), else the one marked latest, else the newest published. nil when there is none.
Functions
Whether a page has an address: any page but a group with no page of its own.
@spec check(String.t()) :: :ok | {:error, :not_a_path | :in_docs_base}
:ok for a stored address the site can answer, else {:error, reason}: :not_a_path, or
:in_docs_base for one under the base the documents with no address are read in.
Whether a page is its version's front page, drawn at its document's own address.
Whether a page is a group: a heading in the contents whose slug the pages under it leave out of their address.
Whether a page is a group with a page of its own, read at its own slug.
Whether an address holds the site's language.
The address as it is stored: trimmed, lower case, one leading slash and no trailing one. nil for
nothing at all, and a value that is not a path is handed back as it was, for check/1 to refuse.
normalize(" /Chelekom/Docs/ ") #=> "/chelekom/docs"
normalize("") #=> nil
The address a page at page_path serves — the page path itself, or the path a *section capture
closes — and nil for any other kind of path.
of_page("/chelekom/docs/*section") #=> "/chelekom/docs"
Whether one address holds the other — the same, or one under the other — so one document's pages
would answer at the other's: /chelekom/docs and /chelekom/docs/headless overlap.
The page among sections whose own part of the address is segments — ["headless", "switch"],
or the "headless/switch" a *section capture holds — or nil. Nothing asked, [] or "", is
the front page, when they hold one. A group is the page at an address only when it has a page of
its own.
The two page paths a document at address is read at: its front page, and every page of it.
Every page's own part of its address among sections — the pages of one version a reader is
shown, each with its id, slug, parent_section_id, front_page, group_heading and
group_page — as %{id => ["headless", "switch"]}, and [] for the front page. A group with no
page of its own has none, and is not in it.
A page is under its parent when that parent is among them and walking up from it reaches the top; otherwise it is at the top. That is the rule the documentation's blocks draw the contents by, so a page's address is where the reader finds it.
A page's own part of its address, root first: the slugs of the pages it is drawn under, then its
own, a front page's and a group's left out — [] for the front page itself. A group with a page of
its own keeps its own slug in its own address, and only there. parent_of answers the parent each
page is drawn under, or nil at the top — which may not be the parent it names, when that one is
not published. A parent chain deeper than twenty, which only a loop makes, stops there.
The segments of an address, :lang among them.
The query a reader reaches version at among its document's published versions
(version_shown/2): %{} for the one shown when none is asked, %{"v" => version_number} for
another, and nil for one no ?v= reaches — not among them, or sharing its number with a newer
one. Versions are told apart by their id.
The version a reader is shown among a document's published versions, each with its
version_number, is_latest_for_version, published_at and inserted_at: the one asked names
(?v=), else the one marked latest, else the newest published. nil when there is none.