ui: Artikel-Fuß neu — zitieren als Link, Tags neben Dialog, Versionen-Liste

- zitieren: schlichter Link direkt unter den Quellen (statt Pill); klappt eine
  dezente, gesamthaft kopierbare Quellenangabe auf — wahlweise APA oder DIN
- Tags raus von unter den Quellen → in die Aktionsreihe, ganz rechts neben Dialog
- „Versionen" als Link eine Zeile darunter; Liste in voller Inhaltsbreite und
  normaler Schrift/Größe (statt mono-Box). Auswahl öffnet Diff/Fassung oben.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 02:19:27 +02:00
parent f2aef5c89a
commit 6aa88a07a6
4 changed files with 162 additions and 147 deletions
+82 -56
View File
@@ -1,74 +1,100 @@
{{/* Herkunft eines Beitrags: Version (→ Commit), Verlauf, Zitieren.
Version/Verlauf nur, wenn Git-Info da ist (enableGitInfo) und repoURL gesetzt.
„Zitieren" kopiert eine Quellenangabe in die Zwischenablage. */}}
{{/* Artikel-Fuß für Library-Beiträge: Quellenangabe (zitieren), Aktionsreihe
(Dialog links, Tags rechts) und der Versionsverlauf (eine Zeile darunter). */}}
{{ $author := .Params.author | default site.Params.author.name }}
<div class="provenance" aria-label="Herkunft">
{{/* Dialog: gleiche Pill-Reihe, sticht durch Pfeil + Akzentfarbe hervor. */}}
<a class="prov-dialog" id="dialog-link" data-thread="{{ .RelPermalink }}" href="/dialog/?thread={{ .RelPermalink }}">→ Dialog</a>
{{/* „Version vom <Datum>" öffnet den Verlauf direkt auf der Seite (Diff rot/grün). */}}
<button type="button" class="prov-version" id="version-badge" aria-expanded="false"
data-path="{{ .File.Path }}">Version vom {{ .Lastmod.Format "02.01.2006" }}</button>
<button type="button" class="prov-cite" aria-expanded="false"
{{/* Zitieren: schlichter Link direkt unter den Quellen. */}}
<div class="cite">
<button type="button" class="cite-toggle" aria-expanded="false">zitieren</button>
<div class="cite-box" hidden
data-title="{{ .Title }}"
data-author="{{ $author }}"
data-url="{{ .Permalink }}"
{{ with .GitInfo }}data-version="{{ .AbbreviatedHash }}"{{ end }}>Zitieren</button>
</div>
<div class="prov-citation" hidden>
<p class="prov-citation-text"></p>
<div class="prov-citation-actions">
<button type="button" class="prov-citation-copy">Kopieren</button>
<span class="prov-citation-status" role="status"></span>
data-year="{{ .Date.Format "2006" }}">
<p class="cite-text"></p>
<div class="cite-actions">
<button type="button" class="cite-fmt is-active" data-fmt="apa">APA</button>
<button type="button" class="cite-fmt" data-fmt="din">DIN</button>
<button type="button" class="cite-copy">kopieren</button>
<span class="cite-status" role="status"></span>
</div>
</div>
</div>
{{/* Aktionsreihe: Dialog links, Tags ganz rechts. */}}
<div class="article-actions">
<a class="prov-dialog" id="dialog-link" data-thread="{{ .RelPermalink }}" href="/dialog/?thread={{ .RelPermalink }}">→ Dialog</a>
{{ with .Params.tags }}
<ul class="tag-pills" aria-label="Tags">
{{- range . -}}<li><a href="/tags/{{ . | urlize }}/">{{ . }}</a></li>{{- end -}}
</ul>
{{ end }}
</div>
{{/* Versionen: eine Zeile darunter; öffnet den Verlauf direkt auf der Seite. */}}
<div class="article-versions">
<button type="button" class="versions-toggle" id="version-badge" aria-expanded="false"
data-path="{{ .File.Path }}">Versionen</button>
</div>
<script>
/* Zitieren: APA/DIN umschaltbar, gesamthaft kopierbar. */
(function () {
if (window.__provCite) return; window.__provCite = 1;
var btn = document.querySelector('.prov-cite');
var panel = document.querySelector('.prov-citation');
if (!btn || !panel) return;
var textEl = panel.querySelector('.prov-citation-text');
var copyBtn = panel.querySelector('.prov-citation-copy');
var statusEl = panel.querySelector('.prov-citation-status');
if (window.__cite) return; window.__cite = 1;
var toggle = document.querySelector('.cite-toggle');
var box = document.querySelector('.cite-box');
if (!toggle || !box) return;
var textEl = box.querySelector('.cite-text');
var statusEl = box.querySelector('.cite-status');
var d = box.dataset;
var fmt = 'apa';
var d = btn.dataset;
var today = new Date().toLocaleDateString('de-CH');
var v = d.version ? ', Version ' + d.version : '';
// Format: Autor: Titel. OPENBUREAU, Version xxx. Abgerufen am TT.MM.JJJJ, URL
var cite = d.author + ': ' + d.title + '. OPENBUREAU' + v + '. Abgerufen am ' + today + ', ' + d.url;
textEl.textContent = cite;
function selectText() {
var r = document.createRange(); r.selectNodeContents(textEl);
var sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(r);
function nameParts(n) {
var p = (n || '').trim().split(/\s+/);
var last = p.pop() || '';
return { last: last, first: p.join(' '), initials: p.map(function (w) { return w.charAt(0) + '.'; }).join(' ') };
}
function copy() {
if (navigator.clipboard && navigator.clipboard.writeText) {
return navigator.clipboard.writeText(cite);
function today() { return new Date().toLocaleDateString('de-CH'); }
function build() {
var n = nameParts(d.author);
if (fmt === 'din') {
return (n.last ? n.last.toUpperCase() + ', ' + n.first + ': ' : '')
+ d.title + '. OPENBUREAU. ' + d.url + ' (abgerufen am ' + today() + ').';
}
// Fallback für unsichere Kontexte (HTTP/LAN): execCommand auf Auswahl.
return new Promise(function (resolve, reject) {
return (n.last ? n.last + ', ' + n.initials + ' ' : '')
+ '(' + d.year + '). ' + d.title + '. OPENBUREAU. Abgerufen am ' + today() + ', von ' + d.url;
}
function render() { textEl.textContent = build(); }
function copy() {
var t = build();
if (navigator.clipboard && navigator.clipboard.writeText) return navigator.clipboard.writeText(t);
return new Promise(function (res, rej) {
try {
var ta = document.createElement('textarea');
ta.value = cite; ta.style.position = 'fixed'; ta.style.opacity = '0';
document.body.appendChild(ta); ta.focus(); ta.select();
var ok = document.execCommand('copy');
document.body.removeChild(ta);
ok ? resolve() : reject();
} catch (e) { reject(e); }
var ta = document.createElement('textarea'); ta.value = t; ta.style.position = 'fixed'; ta.style.opacity = '0';
document.body.appendChild(ta); ta.select();
var ok = document.execCommand('copy'); document.body.removeChild(ta); ok ? res() : rej();
} catch (e) { rej(e); }
});
}
btn.addEventListener('click', function () {
var open = panel.hasAttribute('hidden');
if (open) { panel.removeAttribute('hidden'); selectText(); }
else { panel.setAttribute('hidden', ''); }
btn.setAttribute('aria-expanded', String(open));
toggle.addEventListener('click', function () {
var open = box.hasAttribute('hidden');
if (open) { box.removeAttribute('hidden'); render(); } else { box.setAttribute('hidden', ''); }
toggle.setAttribute('aria-expanded', String(open));
});
copyBtn.addEventListener('click', function () {
copy().then(function () { statusEl.textContent = 'Kopiert ✓'; })
.catch(function () { statusEl.textContent = 'Markiert — bitte mit Strg/⌘+C kopieren.'; selectText(); });
setTimeout(function () { statusEl.textContent = ''; }, 3000);
box.querySelectorAll('.cite-fmt').forEach(function (b) {
b.addEventListener('click', function () {
fmt = b.dataset.fmt;
box.querySelectorAll('.cite-fmt').forEach(function (x) { x.classList.toggle('is-active', x === b); });
render();
});
});
box.querySelector('.cite-copy').addEventListener('click', function () {
copy().then(function () { statusEl.textContent = 'kopiert ✓'; })
.catch(function () {
statusEl.textContent = 'markieren & kopieren';
var r = document.createRange(); r.selectNodeContents(textEl);
var s = window.getSelection(); s.removeAllRanges(); s.addRange(r);
});
setTimeout(function () { statusEl.textContent = ''; }, 2500);
});
})();
</script>