WE GOT DROPDOWNS
This commit is contained in:
parent
f2cbe48d88
commit
fcb808fe63
6 changed files with 78 additions and 18 deletions
|
@ -29,11 +29,7 @@
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
>{{ version }} <span class="caret"></span></a>
|
>{{ version }} <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu" id="version-dropdown"></ul>
|
||||||
<li><a href="#">Action</a></li>
|
|
||||||
<li><a href="#">Another action</a></li>
|
|
||||||
<li><a href="#">Something else here</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
<a
|
<a
|
||||||
|
@ -44,11 +40,7 @@
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
>{{ lang }} <span class="caret"></span></a>
|
>{{ lang }} <span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu" id="lang-dropdown"></ul>
|
||||||
<li><a href="#">Action</a></li>
|
|
||||||
<li><a href="#">Another action</a></li>
|
|
||||||
<li><a href="#">Something else here</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -141,6 +141,12 @@ canvas.spell-viz {
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
background-color: #402a40;
|
background-color: #402a40;
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu-ltr {
|
||||||
|
left: 0;
|
||||||
|
right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu > li > a {
|
.dropdown-menu > li > a {
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
{% filter indent(6) %}
|
{% filter indent(6) %}
|
||||||
{%+ include_raw "main.js" %}
|
{%+ include "main.js.jinja" %}
|
||||||
{% endfilter %}
|
{% endfilter %}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -292,10 +292,62 @@ function hookSpoiler(elem) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// these are filled by Jinja
|
||||||
|
const ROOT_URL = "{{ props.url }}";
|
||||||
|
const PAGE_URL = "{{ page_url }}";
|
||||||
|
|
||||||
|
const VERSION = "{{ version }}";
|
||||||
|
const LANG = "{{ lang }}";
|
||||||
|
|
||||||
|
function dropdownItem(text, href) {
|
||||||
|
let a = document.createElement("a");
|
||||||
|
a.href = href;
|
||||||
|
a.textContent = text;
|
||||||
|
|
||||||
|
let li = document.createElement("li");
|
||||||
|
li.appendChild(a);
|
||||||
|
return li;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fillDropdowns(sitemap) {
|
||||||
|
let versionDropdown = document.getElementById("version-dropdown");
|
||||||
|
let langDropdown = document.getElementById("lang-dropdown");
|
||||||
|
|
||||||
|
// versions, linking to the current lang if possible
|
||||||
|
for (const version of Object.keys(sitemap).sort().reverse()) {
|
||||||
|
let {defaultPath, langPaths} = sitemap[version];
|
||||||
|
|
||||||
|
// link to the current language if available, else link to the default language
|
||||||
|
let path;
|
||||||
|
if (langPaths.hasOwnProperty(LANG)) {
|
||||||
|
path = langPaths[LANG];
|
||||||
|
} else {
|
||||||
|
path = defaultPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
let item = dropdownItem(version, ROOT_URL + path);
|
||||||
|
versionDropdown.appendChild(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// langs for the current version
|
||||||
|
let langPaths = sitemap[VERSION].langPaths;
|
||||||
|
for (const lang of Object.keys(langPaths).sort()) {
|
||||||
|
let item = dropdownItem(lang, ROOT_URL + langPaths[lang]);
|
||||||
|
langDropdown.appendChild(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
// fetch the sitemap from the root and use it to generate the navbar
|
||||||
|
fetch(`${ROOT_URL}/meta/sitemap.json`)
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(fillDropdowns)
|
||||||
|
.catch(e => console.error(e))
|
||||||
|
|
||||||
document.querySelectorAll("details.spell-collapsible").forEach(hookLoad);
|
document.querySelectorAll("details.spell-collapsible").forEach(hookLoad);
|
||||||
document.querySelectorAll("a.toggle-link").forEach(hookToggle);
|
document.querySelectorAll("a.toggle-link").forEach(hookToggle);
|
||||||
document.querySelectorAll(".spoilered").forEach(hookSpoiler);
|
document.querySelectorAll(".spoilered").forEach(hookSpoiler);
|
||||||
|
|
||||||
function tick(prevTime, time) {
|
function tick(prevTime, time) {
|
||||||
const dt = time - prevTime;
|
const dt = time - prevTime;
|
||||||
for (const q of rfaQueue) {
|
for (const q of rfaQueue) {
|
|
@ -105,7 +105,7 @@ class SitemapMarker(HexdocModel):
|
||||||
version: str
|
version: str
|
||||||
lang: str
|
lang: str
|
||||||
path: str
|
path: str
|
||||||
lang_in_path: bool
|
is_default_lang: bool
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def load(cls, path: Path):
|
def load(cls, path: Path):
|
||||||
|
@ -223,14 +223,13 @@ def main(args: Args | None = None) -> None:
|
||||||
for version in versions:
|
for version in versions:
|
||||||
for lang, book in books.items():
|
for lang, book in books.items():
|
||||||
is_default_lang = lang == props.default_lang
|
is_default_lang = lang == props.default_lang
|
||||||
lang_in_path = not is_default_lang
|
|
||||||
|
|
||||||
# /index.html
|
# /index.html
|
||||||
# /lang/index.html
|
# /lang/index.html
|
||||||
# /v/version/index.html
|
# /v/version/index.html
|
||||||
# /v/version/lang/index.html
|
# /v/version/lang/index.html
|
||||||
parts = ("v", version) if version else ()
|
parts = ("v", version) if version else ()
|
||||||
if lang_in_path:
|
if not is_default_lang:
|
||||||
parts += (lang,)
|
parts += (lang,)
|
||||||
|
|
||||||
output_dir = args.output_dir / Path(*parts)
|
output_dir = args.output_dir / Path(*parts)
|
||||||
|
@ -261,7 +260,7 @@ def main(args: Args | None = None) -> None:
|
||||||
version=version,
|
version=version,
|
||||||
lang=lang,
|
lang=lang,
|
||||||
path="/" + "/".join(parts),
|
path="/" + "/".join(parts),
|
||||||
lang_in_path=lang_in_path,
|
is_default_lang=is_default_lang,
|
||||||
)
|
)
|
||||||
(output_dir / MARKER_NAME).write_text(marker.model_dump_json())
|
(output_dir / MARKER_NAME).write_text(marker.model_dump_json())
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,18 @@ import shutil
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Self, Sequence
|
from typing import Self, Sequence, TypedDict
|
||||||
|
|
||||||
from hexdoc.hexdoc import MARKER_NAME, SitemapMarker
|
from hexdoc.hexdoc import MARKER_NAME, SitemapMarker
|
||||||
from hexdoc.utils import HexdocModel
|
from hexdoc.utils import HexdocModel
|
||||||
from hexdoc.utils.path import write_to_path
|
from hexdoc.utils.path import write_to_path
|
||||||
|
|
||||||
|
|
||||||
|
class SitemapItem(TypedDict):
|
||||||
|
defaultPath: str
|
||||||
|
langPaths: dict[str, str]
|
||||||
|
|
||||||
|
|
||||||
def strip_empty_lines(text: str) -> str:
|
def strip_empty_lines(text: str) -> str:
|
||||||
return "\n".join(s for s in text.splitlines() if s.strip())
|
return "\n".join(s for s in text.splitlines() if s.strip())
|
||||||
|
|
||||||
|
@ -63,11 +68,17 @@ def main():
|
||||||
shutil.copytree(args.src, args.dst, dirs_exist_ok=True)
|
shutil.copytree(args.src, args.dst, dirs_exist_ok=True)
|
||||||
|
|
||||||
# crawl the new tree to rebuild the sitemap
|
# crawl the new tree to rebuild the sitemap
|
||||||
sitemap = defaultdict[str, dict[str, bool]](dict)
|
sitemap = defaultdict[str, SitemapItem](
|
||||||
|
lambda: SitemapItem(defaultPath="", langPaths={})
|
||||||
|
)
|
||||||
|
|
||||||
for marker_path in args.dst.rglob(MARKER_NAME):
|
for marker_path in args.dst.rglob(MARKER_NAME):
|
||||||
marker = SitemapMarker.load(marker_path)
|
marker = SitemapMarker.load(marker_path)
|
||||||
sitemap[marker.version][marker.lang] = marker.lang_in_path
|
version_item = sitemap[marker.version]
|
||||||
|
|
||||||
|
version_item["langPaths"][marker.lang] = marker.path
|
||||||
|
if marker.is_default_lang:
|
||||||
|
version_item["defaultPath"] = marker.path
|
||||||
|
|
||||||
write_to_path(args.dst / "meta" / "sitemap.json", json.dumps(sitemap))
|
write_to_path(args.dst / "meta" / "sitemap.json", json.dumps(sitemap))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue