Add interactive navigation controls

This commit is contained in:
Juno Takano 2026-01-06 03:52:08 -03:00
commit 435cf4d18f
7 changed files with 125 additions and 45 deletions

View file

@ -64,10 +64,16 @@ fn mkversion() -> (u8, u8, u8) {
pub struct Config { pub struct Config {
#[serde(default)] #[serde(default)]
_private: bool, _private: bool,
#[serde(default = "mktrue")]
pub about: bool,
#[serde(default)] #[serde(default)]
pub site_title: String, pub about_text: String,
#[serde(default = "mkfalse")]
pub ascii_dom_ids: bool,
#[serde(default)] #[serde(default)]
pub site_description: String, pub content_language: String,
#[serde(default = "mkfalse")]
error_poem: bool,
#[serde(default = "mktrue")] #[serde(default = "mktrue")]
pub footer: bool, pub footer: bool,
#[serde(default = "mktrue")] #[serde(default = "mktrue")]
@ -76,32 +82,32 @@ pub struct Config {
pub footer_date: bool, pub footer_date: bool,
#[serde(default)] #[serde(default)]
pub footer_text: String, pub footer_text: String,
#[serde(default = "mktrue")]
pub about: bool,
#[serde(default)]
pub about_text: String,
#[serde(default = "mktrue")]
pub tree: bool,
#[serde(default = "mktrue")]
pub raw: bool,
#[serde(default = "mktrue")]
pub raw_toml: bool,
#[serde(default = "mktrue")]
pub raw_json: bool,
#[serde(default = "mktrue")]
pub index_search: bool,
#[serde(default = "mktrue")]
pub index_node_list: bool,
#[serde(default = "mk8")] #[serde(default = "mk8")]
pub index_node_count: u16, pub index_node_count: u16,
#[serde(default = "mktrue")] #[serde(default = "mktrue")]
pub index_node_list: bool,
#[serde(default = "mktrue")]
pub index_root_node: bool, pub index_root_node: bool,
#[serde(default = "mktrue")]
pub index_search: bool,
#[serde(default)]
node_selector: bool,
#[serde(default)]
navbar_search: bool,
#[serde(default = "mktrue")]
pub raw: bool,
#[serde(default = "mktrue")]
pub raw_json: bool,
#[serde(default = "mktrue")]
pub raw_toml: bool,
#[serde(default)]
pub site_description: String,
#[serde(default)]
pub site_title: String,
#[serde(default = "mktrue")]
pub tree: bool,
#[serde(default = "mkfalse")] #[serde(default = "mkfalse")]
pub tree_node_text: bool, pub tree_node_text: bool,
#[serde(default = "mkfalse")]
pub ascii_dom_ids: bool,
#[serde(default)]
pub content_language: String,
} }
// See: https://github.com/serde-rs/serde/issues/368 // See: https://github.com/serde-rs/serde/issues/368
@ -181,25 +187,28 @@ impl Default for Config {
fn default() -> Config { fn default() -> Config {
Config { Config {
_private: true, _private: true,
site_title: String::default(), about: true,
site_description: String::default(), about_text: String::default(),
ascii_dom_ids: false,
content_language: String::default(),
error_poem: false,
footer: true, footer: true,
footer_credits: true, footer_credits: true,
footer_date: true, footer_date: true,
footer_text: String::default(), footer_text: String::default(),
about: true,
about_text: String::default(),
tree: true,
raw: true,
raw_toml: true,
raw_json: true,
index_search: true,
index_node_list: true,
index_node_count: 8, index_node_count: 8,
index_node_list: true,
index_root_node: true, index_root_node: true,
index_search: true,
node_selector: true,
navbar_search: true,
raw: true,
raw_json: true,
raw_toml: true,
site_description: String::default(),
site_title: String::default(),
tree: true,
tree_node_text: false, tree_node_text: false,
ascii_dom_ids: false,
content_language: String::default(),
} }
} }
} }

View file

@ -581,6 +581,9 @@ Syntax|syntax|
[meta.config] [meta.config]
content_language = "en" content_language = "en"
footer_credits = false footer_credits = false
error_poem = true
node_selector = true
navbar_search = true
footer_text = """ footer_text = """
made by jutty|https://jutty.dev acknowledgments|Acknowledgments |source code|https://codeberg.org/jutty/en made by jutty|https://jutty.dev acknowledgments|Acknowledgments |source code|https://codeberg.org/jutty/en
""" """

View file

@ -107,20 +107,46 @@ span.detached-connection {
filter: opacity(60%); filter: opacity(60%);
} }
nav#main-menu { nav#nav-main {
text-align: center; text-align: center;
} }
nav#main-menu ul { #nav-main-spread {
display: inline; display: flex;
padding-left: 0; justify-content: space-between;
align-items: center;
margin: 0 10px;
} }
nav#main-menu li { nav#nav-main ul {
display: inline;
padding-left: 0;
margin: 0;
}
nav#nav-main li {
margin-right: 10px; margin-right: 10px;
display: inline; display: inline;
} }
.nav-inputs div {
margin-right: 10px;
display: flex;
align-items: right;
}
form.node-selector, form.navbar-search {
display: inline;
}
.node-selector select {
width: 100px;
}
.navbar-search input[type="text"] {
width: 100px;
}
div#error-poem { div#error-poem {
text-align: right; text-align: right;
margin-top: 8em; margin-top: 8em;
@ -174,4 +200,9 @@ em#index-node-count {
div.header-row { div.header-row {
display: block; display: block;
} }
#nav-main-spread {
display: inline;
margin: 0;
}
} }

View file

@ -18,8 +18,9 @@
{% endblock head %} {% endblock head %}
</head> </head>
<body> <body>
<nav id="main-menu"> <nav id="nav-main">
<ul> <div {% if config.node_selector or config.navbar_search %}id="nav-main-spread"{% endif %}>
<ul id="nav-anchors">
<li><a href="/">Index</a></li> <li><a href="/">Index</a></li>
{% if config.about %} {% if config.about %}
<li><a href="/about">About</a></li> <li><a href="/about">About</a></li>
@ -28,14 +29,31 @@
<li><a href="/tree">Tree</a></li> <li><a href="/tree">Tree</a></li>
{% endif %} {% endif %}
{% if config.raw %} {% if config.raw %}
{% if config.raw_toml %} <li><a href="/data">Data</a></li>
<li><a href="/graph/toml">TOML Graph</a></li>
{% endif %}
{% if config.raw_json %}
<li><a href="/graph/json">JSON Graph</a></li>
{% endif %}
{% endif %} {% endif %}
</ul> </ul>
{% if config.node_selector or config.navbar_search %}
<div class="nav-inputs">
{% if nodes and config.node_selector %}
<form class="node-selector" method="get" action="/redirect">
<select class="node-selector" name="node">
<option value="">Nodes</option>
{% for node in nodes | filter(attribute="hidden", value=false) %}
<option value="{{node.id}}">{{node.title}}</option>
{% endfor %}
</select>
<button type="submit">Go</button>
</form>
{% endif %}
{% if config.navbar_search %}
<form class="navbar-search" method="post">
<input type="text" name="node" required/>
<input type="submit" value="Find"/>
</form>
{% endif %}
</div>
{% endif %}
</div>
<hr> <hr>
</nav> </nav>
<main> <main>

19
templates/data.html Normal file
View file

@ -0,0 +1,19 @@
{% extends "base.html" %}
{% block title %}Data{% endblock title %}
{%- block body %}
<h1>Data</h1>
<p>The raw data used to render this graph is available in the following formats:</p>
<ul>
{% if config.raw_toml %}
<li><a href="/graph/toml">TOML</a></li>
{% endif %}
{% if config.raw_json %}
<li><a href="/graph/json">JSON</a></li>
{% endif %}
</ul>
{%- endblock body %}

View file

@ -4,7 +4,8 @@
<h1> <h1>
{{ title | default(value="Unknown error") }} {{ title | default(value="Unknown error") }}
</h1> </h1>
{{ message | default(value="This error has not been described in detail.") | linebreaksbr | safe }} {{ message | default(value="Unexpected error") | linebreaksbr | safe }}
{% if config.error_poem %}
<hr> <hr>
<div id="error-poem"> <div id="error-poem">
<em> <em>
@ -14,5 +15,5 @@
back onto the {% if config.tree %}<a href="/tree">tree</a>{% else %}tree{% endif %} back onto the {% if config.tree %}<a href="/tree">tree</a>{% else %}tree{% endif %}
</em> </em>
</div> </div>
</p> {% endif %}
{%- endblock body %} {%- endblock body %}

View file

@ -13,11 +13,10 @@
{% endif %} {% endif %}
</i> </i>
{% if nodes %} {% if nodes %}
{% if config.index_search %} {% if config.navbar_search %}
<form method="post"> <form method="post">
<label for="node">Find by ID:</label>
<input type="text" name="node" required/> <input type="text" name="node" required/>
<input type="submit" value="Submit"/> <input type="submit" value="Find"/>
</form> </form>
{% endif %} {% endif %}
{% if config.index_node_list or config.index_root_node %} {% if config.index_node_list or config.index_root_node %}