99 lines
4.2 KiB
HTML
99 lines
4.2 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>{{.Title}} – Wiki</title>
|
||
<link rel="stylesheet" href="/static/style.css">
|
||
</head>
|
||
<body>
|
||
{{/* Fest positionierte Kopfzeile — bleibt sichtbar unabhängig davon ob die
|
||
Sidebar gerade ein- oder ausgeklappt ist. sidebar.js hängt sich am Button ein. */}}
|
||
<div class="topbar">
|
||
<button id="sidebar-toggle" class="sidebar-toggle" type="button" aria-label="Navigation ein-/ausblenden" aria-controls="sidebar">☰</button>
|
||
<span class="topbar-title">Wiki</span>
|
||
</div>
|
||
|
||
{{/* Nur auf schmalen Bildschirmen sichtbar (siehe style.css) — schließt die
|
||
Sidebar per Klick daneben, wie man es von mobilen Menüs kennt. */}}
|
||
<div id="sidebar-backdrop" class="sidebar-backdrop"></div>
|
||
|
||
<div class="layout">
|
||
<nav class="sidebar" id="sidebar">
|
||
{{/* Menü-Links (für Admins zusätzlich Team-Verwaltung, die auch die
|
||
Team-Umschaltung übernimmt, + Audit-Log), dann eine Trennlinie
|
||
und darunter das aktive Team. */}}
|
||
<div class="sidebar-menu">
|
||
{{if .IsAdmin}}
|
||
<a href="/admin/teams">Teams verwalten</a>
|
||
<a href="/admin/audit">Audit-Log</a>
|
||
{{end}}
|
||
<a href="/logout">Logout</a>
|
||
</div>
|
||
|
||
<div class="team-bar">
|
||
<span class="team-name">{{.TeamName}}</span>
|
||
</div>
|
||
|
||
{{/* Suchfeld — sendet GET /search?q=... */}}
|
||
<form action="/search" method="get" class="search-form">
|
||
<input type="search" name="q" placeholder="Suchen…" value="{{.Query}}" autocomplete="off">
|
||
</form>
|
||
|
||
{{/* Ein benanntes Template das sich selbst aufrufen kann — das ermöglicht
|
||
die rekursive Darstellung von beliebig tiefen Ordnerstrukturen.
|
||
"define" legt den Namen fest, "template" ruft ihn auf. */}}
|
||
{{define "navItems"}}
|
||
<ul>
|
||
{{range .}}
|
||
{{if .Children}}
|
||
{{/* Dieser Eintrag ist ein Ordner: <details> klappt auf/zu */}}
|
||
<li>
|
||
<details open>
|
||
<summary>{{.Title}}</summary>
|
||
{{/* Rekursiver Aufruf: die Kinder des Ordners rendern */}}
|
||
{{template "navItems" .Children}}
|
||
</details>
|
||
</li>
|
||
{{else}}
|
||
{{/* Dieser Eintrag ist eine Seite: normaler Link */}}
|
||
<li><a href="{{.URL}}">{{.Title}}</a></li>
|
||
{{end}}
|
||
{{end}}
|
||
</ul>
|
||
{{end}}
|
||
|
||
{{/* Das Template mit der obersten Nav-Ebene starten */}}
|
||
{{template "navItems" .Nav}}
|
||
</nav>
|
||
|
||
<main class="content">
|
||
{{if .NoResults}}
|
||
{{/* Suche durchgeführt, aber kein Treffer */}}
|
||
<h1>Keine Ergebnisse</h1>
|
||
<p class="search-empty">Keine Seiten gefunden für <strong>„{{.Query}}"</strong>.</p>
|
||
{{else if .SearchResults}}
|
||
{{/* Suchergebnisse anzeigen */}}
|
||
<h1>Suchergebnisse <span class="search-query">„{{.Query}}"</span></h1>
|
||
<p class="search-count">{{len .SearchResults}} Treffer</p>
|
||
<ul class="search-results">
|
||
{{range .SearchResults}}
|
||
<li class="search-result">
|
||
<a href="{{.URL}}" class="search-result-title">{{.Title}}</a>
|
||
<span class="search-result-url">{{.URL}}</span>
|
||
{{if .Snippet}}
|
||
<p class="search-result-snippet">{{.Snippet}}</p>
|
||
{{end}}
|
||
</li>
|
||
{{end}}
|
||
</ul>
|
||
{{else}}
|
||
{{/* Normaler Seiteninhalt — .Body enthält bereits fertiges HTML */}}
|
||
{{.Body}}
|
||
{{end}}
|
||
</main>
|
||
</div>
|
||
|
||
<script src="/static/sidebar.js"></script>
|
||
</body>
|
||
</html>
|