Files
bible/assets/base.njk
T
2026-09-03 17:24:22 -04:00

103 lines
4.4 KiB
Plaintext

{# The shell every page is wrapped in. Rendered by sw.js, not by the build,
so editing this file changes every page without regenerating any of them.
Context: title, content (safe HTML fragment), mark (bookmark or null).
Bootstrap is the whole stylesheet. The fragments carry semantic USFM
classes and no Bootstrap ones, so the body text is styled by Reboot; the
chrome here is what uses the framework. #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>{% block title %}{{ title | safe }}{% endblock %}</title>
{# Vendored rather than linked from a CDN: sw.js only caches same-origin
responses, so a CDN stylesheet would leave the app unstyled offline. #}
<link rel="stylesheet" href="bootstrap.min.css">
{# History entries are whole books, and htmx keeps its history cache in
localStorage -- a couple of them would blow the quota. Turned off: going
back re-requests the fragment, which the worker answers from its cache. #}
<meta name="htmx-config" content='{"historyCacheSize":0}'>
{# The bundle carries Popper, which the navbar collapse and the modal do not
need -- but a dropdown or tooltip added later would, and this is one file
in the precache either way. Deferred scripts run in order, so `bootstrap`
is defined by the time app.js runs. #}
<script src="bootstrap.bundle.min.js" defer></script>
{# htmx is not deferred: hx-boost has to be in place before the first click. #}
<script src="htmx.min.js"></script>
<script src="app.js" defer></script>
<link rel="manifest" href="manifest.webmanifest">
<meta name="theme-color" content="#1a202c">
<link rel="apple-touch-icon" href="icons/apple-touch-icon.png">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="Bible">
</head>
{# Boosted links swap only the fragment, so the navbar, the modal and the
scripts above survive navigation and never reload. #}
<body class="{% block body_class %}{% endblock %} bg-body-tertiary"
hx-boost="true" hx-target="#content" hx-swap="innerHTML show:top">
<nav class="site-header navbar navbar-expand-lg bg-dark sticky-top"
data-bs-theme="dark">
<div class="container-xl">
<a class="navbar-brand" href="index.html">Bible</a>
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-target="#site-nav"
aria-controls="site-nav" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="site-nav">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
{% block navbar_nav %}
{% endblock %}
</ul>
{% include "bookmark.njk" %}
</div>
</div>
</nav>
{# col-xl-8 keeps a line of verse near a readable measure instead of running
the full width of a desktop window. #}
<main class="container-xl my-4">
<div class="row justify-content-center">
<div id="content" class="col-12 col-xl-8 bg-body rounded-3 shadow-sm p-3 p-md-5">
{% block content %}{% endblock %}
</div>
</div>
</main>
{# Chrome, so it is written once here instead of built in JavaScript on every
page. app.js only fills in the reference and shows it. #}
<div class="modal fade" id="verse-dialog" tabindex="-1"
aria-labelledby="verse-dialog-ref" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5 verse-dialog-ref" id="verse-dialog-ref"></h2>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
{% include "status.njk" %}
</div>
<div class="modal-footer">
<form class="verse-dialog-actions d-flex flex-wrap gap-2 m-0"
hx-post="api/bookmark" hx-target="#bookmark" hx-swap="outerHTML">
<input type="hidden" name="ref" value="">
<input type="hidden" name="href" value="">
<button class="btn btn-outline-secondary" type="button"
data-action="copy">Copy link</button>
<button class="btn btn-primary" type="submit">Set bookmark</button>
</form>
</div>
</div>
</div>
</div>
</body>
</html>