Rework Notes page: balanced two columns, filter, bibliography section, drop prev/next links

This commit is contained in:
tdehaeze committed 2026-10-17 21:49:47 +02:00
1 parent 0699938cd5
commit 2490e8bbb1
10 files changed
+363 -29

No files matched your search

+4
View File
@@ -0,0 +1,4 @@
+++
title = "Bibliography"
build = { render = "never", list = "never" }
+++
+5 -2
View File
@@ -1,8 +1,11 @@
+++
title = "Zettels"
title = "Notes"
author = ["Thomas Dehaeze"]
type = "zettels"
url = "/notes/"
draft = false
+++
Here is the list of subjects I took note about.
Technical notes on control, mechatronics, instrumentation and related topics.
This is a living personal wiki, so some notes are still incomplete.
Further down, there is a list of notes on books, theses and articles I have read and found interesting.
+34
View File
@@ -0,0 +1,34 @@
{{ define "content" -}}
<article class="post">
<!-- post-header -->
<header class="post-header">
<h1 class="post-title">{{ .Title | title }}</h1>
</header>
<!-- TOC -->
{{- partial "post/toc.html" . -}}
<!-- Content -->
<div class="post-content">
{{ .Content }}
</div>
<!-- Backlinks -->
{{ partial "backlinks" . }}
<footer class="post-footer">
{{ with .Params.tags -}}
<div class="post-tags">
{{ range . -}}
<a href="{{ "tags" | relLangURL }}/{{ . | urlize }}/">{{ . }}</a>
{{ end -}}
</div>
{{- end -}}
<!-- Post Pagination -->
</footer>
</article>
<div id="comments">
{{ partial "comments.html" $ }}
</div>
{{- end }}
+34
View File
@@ -0,0 +1,34 @@
{{ define "content" -}}
<article class="post">
<!-- post-header -->
<header class="post-header">
<h1 class="post-title">{{ .Title | title }}</h1>
</header>
<!-- TOC -->
{{- partial "post/toc.html" . -}}
<!-- Content -->
<div class="post-content">
{{ .Content }}
</div>
<!-- Backlinks -->
{{ partial "backlinks" . }}
<footer class="post-footer">
{{ with .Params.tags -}}
<div class="post-tags">
{{ range . -}}
<a href="{{ "tags" | relLangURL }}/{{ . | urlize }}/">{{ . }}</a>
{{ end -}}
</div>
{{- end -}}
<!-- Post Pagination -->
</footer>
</article>
<div id="comments">
{{ partial "comments.html" $ }}
</div>
{{- end }}
+34
View File
@@ -0,0 +1,34 @@
{{ define "content" -}}
<article class="post">
<!-- post-header -->
<header class="post-header">
<h1 class="post-title">{{ .Title | title }}</h1>
</header>
<!-- TOC -->
{{- partial "post/toc.html" . -}}
<!-- Content -->
<div class="post-content">
{{ .Content }}
</div>
<!-- Backlinks -->
{{ partial "backlinks" . }}
<footer class="post-footer">
{{ with .Params.tags -}}
<div class="post-tags">
{{ range . -}}
<a href="{{ "tags" | relLangURL }}/{{ . | urlize }}/">{{ . }}</a>
{{ end -}}
</div>
{{- end -}}
<!-- Post Pagination -->
</footer>
</article>
<div id="comments">
{{ partial "comments.html" $ }}
</div>
{{- end }}
+13
View File
@@ -0,0 +1,13 @@
{{- $p := . -}}
{{- $raw := $p.RawContent -}}
{{- $author := $p.Params.ref_author | default "" -}}
{{- if not $author }}{{ with findRE `(?m)^Author\(s\)\r?\n: (.+)$` $raw 1 }}{{ $author = replaceRE `^Author\(s\)\r?\n: ` "" (index . 0) }}{{ end }}{{ end -}}
{{- $author = $author | replaceRE `&amp;` "&" | strings.TrimSpace -}}
{{- $year := $p.Params.ref_year | default "" -}}
{{- if not $year }}{{ with findRE `(?m)^Year\r?\n: (\d{4})` $raw 1 }}{{ $year = replaceRE `^Year\r?\n: ` "" (index . 0) }}{{ end }}{{ end -}}
{{- $notes := slice -}}
{{- range findRE `relref "[^"]+\.md"` $raw -}}
{{- $base := . | replaceRE `^relref "(?:.*/)?([^"/]+)\.md"$` "$1" -}}
{{- with site.GetPage (printf "/zettels/%s" $base) }}{{ $notes = $notes | append . }}{{ end -}}
{{- end -}}
{{- return (dict "author" $author "year" (string $year) "notes" $notes) -}}
+68
View File
@@ -0,0 +1,68 @@
<style>
.notes-intro { max-width: 42em; }
.notes-bar { position: sticky; top: 0; z-index: 5; background: #fff; border-bottom: 1px solid #e5e5e5; padding: .6em 0; margin: 1.2em 0; }
.notes-filter { display: none; align-items: center; gap: .8em; margin-bottom: .5em; }
.notes-filter.is-on { display: flex; }
.notes-filter input { flex: 1; max-width: 22em; padding: .4em .6em; border: 1px solid #ccc; border-radius: 4px; font: inherit; }
.notes-filter input:focus { outline: 2px solid hsl(232, 61%, 64%); outline-offset: 1px; }
.notes-count { color: #777; font-size: .85em; }
.notes-block { margin-top: 2em; }
.notes-block > h2 { font-size: 1.4em; margin: 0 0 .6em; padding-bottom: .3em; border-bottom: 1px solid #e5e5e5; }
.notes-block > h2 span { font-size: .6em; font-weight: normal; color: #888; }
.notes-block-bib { margin-top: 3.5em; scroll-margin-top: 4em; }
.notes-cols { display: flex; gap: 1.2em; align-items: flex-start; }
.notes-col { flex: 1 1 0; min-width: 0; }
@media (max-width: 699px) { .notes-cols { flex-direction: column; align-items: stretch; } }
.notes-single { max-width: 50em; }
.note-references { margin-top: 2em; }
.notes-card { break-inside: avoid; display: inline-block; width: 100%; box-sizing: border-box; margin: 0 0 1.2em; border: 1px solid #e5e5e5; border-radius: 6px; padding: .9em 1.1em 1em; min-width: 0; }
.notes-card h3 { margin: 0 0 .5em; font-size: 1.1em; display: flex; justify-content: space-between; align-items: baseline; gap: .5em; }
.notes-card h3 span { font-size: .75em; font-weight: normal; color: #888; }
.notes-card ul { list-style: none; margin: 0; padding: 0; }
.notes-card li { margin: .3em 0; line-height: 1.35; }
.notes-card .keywords { color: #888; font-size: .8em; margin-left: .3em; }
.notes-card .description { color: #666; font-size: .85em; }
.notes-sub { margin-top: .9em; }
.notes-sub h4 { margin: 0 0 .2em; font-size: .95em; }
.notes-sub h4 span { font-weight: normal; color: #888; font-size: .85em; }
.notes-sub ul { padding-left: 1em; border-left: 2px solid #eee; }
.notes-card li > a { color: #2a6ebb; }
.notes-block-bib .notes-card .description a { color: #c05b4d; }
.notes-card [hidden], .notes-sub[hidden], .notes-block[hidden], .notes-empty[hidden] { display: none; }
.notes-card-flow { break-inside: auto; display: block; }
.notes-card-flow h3 { break-after: avoid; }
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
var input = document.getElementById('notes-filter');
if (!input) return;
input.parentNode.classList.add('is-on');
var items = [].slice.call(document.querySelectorAll('.notes-card li[data-text]'));
var cards = [].slice.call(document.querySelectorAll('.notes-card'));
var count = document.getElementById('notes-count');
var empty = document.getElementById('notes-empty');
var total = items.length;
function run() {
var q = input.value.trim().toLowerCase(), shown = 0;
items.forEach(function (li) {
var ok = !q || li.getAttribute('data-text').indexOf(q) !== -1;
li.hidden = !ok;
if (ok) shown++;
});
[].forEach.call(document.querySelectorAll('.notes-sub'), function (d) {
d.hidden = !d.querySelector('li:not([hidden])');
});
cards.forEach(function (c) {
var hide = !c.querySelector('li:not([hidden])');
c.hidden = hide;
});
[].forEach.call(document.querySelectorAll('.notes-block'), function (b) {
b.hidden = !b.querySelector('li:not([hidden])');
});
count.textContent = q ? shown + ' of ' + total + ' entries' : total + ' entries';
empty.hidden = shown !== 0;
}
input.addEventListener('input', run);
run();
});
</script>
+34
View File
@@ -0,0 +1,34 @@
{{ define "content" -}}
<article class="post">
<!-- post-header -->
<header class="post-header">
<h1 class="post-title">{{ .Title | title }}</h1>
</header>
<!-- TOC -->
{{- partial "post/toc.html" . -}}
<!-- Content -->
<div class="post-content">
{{ .Content }}
</div>
<!-- Backlinks -->
{{ partial "backlinks" . }}
<footer class="post-footer">
{{ with .Params.tags -}}
<div class="post-tags">
{{ range . -}}
<a href="{{ "tags" | relLangURL }}/{{ . | urlize }}/">{{ . }}</a>
{{ end -}}
</div>
{{- end -}}
<!-- Post Pagination -->
</footer>
</article>
<div id="comments">
{{ partial "comments.html" $ }}
</div>
{{- end }}
+92 -27
View File
@@ -1,44 +1,109 @@
{{- define "title" }}{{ T "archive" }} - {{ .Site.Title }}{{ end -}}
{{- define "title" }}{{ .Title }} - {{ .Site.Title }}{{ end -}}
{{- define "item" -}}
<li>
<li data-text="{{ printf "%s %s %s" .Title (delimit (.Params.keywords | default slice) " ") (.Description | default "") | lower }}">
<a href="{{ .Permalink }}">{{ .Title | title }}</a>
{{ with .Keywords }}<span class="keywords">{{ . }}</span>{{ end }}
{{ with .Keywords }}<span class="keywords">{{ delimit . ", " }}</span>{{ end }}
{{ with .Description }}<div class="description">{{ . }}</div>{{ end }}
</li>
{{- end }}
{{- define "content" }}
{{- range .Pages.GroupByParam "category" }}
<section class="list-zettels">
<span class="list-title">{{ .Key | title }}:</span>
{{- define "card" -}}
{{- $id := .Key | urlize }}
<section class="notes-card" id="{{ $id }}" aria-labelledby="{{ $id }}-h">
<h3 id="{{ $id }}-h">{{ .Key | title }} <span>{{ len .Pages }}</span></h3>
{{- $plain := where .Pages "Params.subcategory" "eq" nil }}
{{- if $plain }}
<ul>
{{- range (where .Pages "Params.subcategory" "eq" nil).ByTitle }}
{{ template "item" . }}
{{- end }}
{{- range .Pages.GroupByParam "subcategory" }}
<li class="subcategory">
<span class="list-subtitle">{{ .Key | title }}:</span>
<ul>
{{- range .Pages.ByTitle }}
{{ template "item" . }}
{{- end }}
{{- range $plain.ByTitle }}{{ template "item" . }}{{ end }}
</ul>
</li>
{{- end }}
{{- range (where .Pages "Params.subcategory" "ne" nil).GroupByParam "subcategory" }}
<div class="notes-sub">
<h4>{{ .Key | title }} <span>({{ len .Pages }})</span></h4>
<ul>
{{- range .Pages.ByTitle }}{{ template "item" . }}{{ end }}
</ul>
</div>
{{- end }}
</section>
{{- end }}
{{- define "bibcard" -}}
{{- $label := .label }}
<section class="notes-card notes-card-flow" id="bib-{{ $label | urlize }}" aria-labelledby="bib-{{ $label | urlize }}-h">
<h3 id="bib-{{ $label | urlize }}-h">{{ $label }} <span>{{ len .pages }}</span></h3>
{{- $rows := slice }}
{{- range .pages }}{{ $m := partial "notes/bibmeta.html" . }}{{ $rows = $rows | append (dict "page" . "m" $m "year" (or $m.year "0")) }}{{ end }}
<ul>
{{- range sort $rows "year" "desc" }}
{{- $m := .m }}{{ with .page }}
<li data-text="{{ printf "%s %s %s %s %s" .Title $m.author $m.year (delimit (.Params.keywords | default slice) " ") (.Description | default "") | lower }}">
<a href="{{ .Permalink }}">{{ .Title }}</a>
{{ with .Keywords }}<span class="keywords">{{ delimit . ", " }}</span>{{ end }}
{{- if or $m.author $m.year }}
<div class="description">{{ $m.author }}{{ if and $m.author $m.year }}, {{ end }}{{ $m.year }}</div>
{{- end }}
{{- with $m.notes }}
<div class="description">Notes: {{ range $i, $n := . }}{{ if $i }}, {{ end }}<a href="{{ $n.Permalink }}">{{ $n.Title | title }}</a>{{ end }}</div>
{{- end }}
</li>
{{- end }}{{ end }}
</ul>
</section>
{{- end }}
{{- define "content" }}
{{- partial "notes/styles.html" . }}
{{- $cats := .Pages.GroupByParam "category" }}
{{- $uncat := where .Pages "Params.category" "eq" nil }}
{{- if $uncat }}
<section class="list-zettels">
<span class="list-title">Other:</span>
<ul>
{{- range $uncat.ByTitle }}
{{ template "item" . }}
{{- $bibTypes := slice
(dict "label" "Books" "pages" (where site.RegularPages "Section" "book"))
(dict "label" "PhD theses" "pages" (where site.RegularPages "Section" "phdthesis"))
(dict "label" "Journal articles" "pages" (where site.RegularPages "Section" "article"))
(dict "label" "Conference papers" "pages" (where site.RegularPages "Section" "inproceedings"))
(dict "label" "Book chapters" "pages" (where site.RegularPages "Section" "inbook"))
(dict "label" "Reports" "pages" (where site.RegularPages "Section" "techreport"))
(dict "label" "Websites" "pages" (where site.RegularPages "Section" "websites")) }}
{{- $bibCount := 0 }}
{{- range $bibTypes }}{{ $bibCount = add $bibCount (len .pages) }}{{ end }}
<article class="post">
<div class="post-content notes-intro">{{ .Content }}</div>
<div class="notes-bar">
<div class="notes-filter">
<label for="notes-filter">Filter</label>
<input type="search" id="notes-filter" placeholder="Title, keyword, author, year…" autocomplete="off">
<span class="notes-count" id="notes-count" aria-live="polite">{{ add (len .Pages) $bibCount }} entries</span>
</div>
</div>
<section class="notes-block" aria-labelledby="notes-h">
<h2 id="notes-h">Notes <span>{{ len .Pages }}</span></h2>
{{- $groups := slice }}
{{- range $cats }}
{{- $subs := len ((where .Pages "Params.subcategory" "ne" nil).GroupByParam "subcategory") }}
{{- $groups = $groups | append (dict "Key" .Key "Pages" .Pages "w" (add (len .Pages) (mul 2 $subs) 3)) }}
{{- end }}
</ul>
</section>
{{- end }}
{{- if $uncat }}{{ $groups = $groups | append (dict "Key" "Other" "Pages" $uncat "w" (add (len $uncat) 3)) }}{{ end }}
{{- $colA := slice }}{{ $colB := slice }}{{ $wA := 0 }}{{ $wB := 0 }}
{{- range sort $groups "w" "desc" }}
{{- if le $wA $wB }}{{ $colA = $colA | append . }}{{ $wA = add $wA .w }}
{{- else }}{{ $colB = $colB | append . }}{{ $wB = add $wB .w }}{{ end }}
{{- end }}
<div class="notes-cols">
<div class="notes-col">{{ range sort $colA "Key" }}{{ template "card" . }}{{ end }}</div>
<div class="notes-col">{{ range sort $colB "Key" }}{{ template "card" . }}{{ end }}</div>
</div>
</section>
<section class="notes-block notes-block-bib" id="bibliography" aria-labelledby="bibliography-h">
<h2 id="bibliography-h">Bibliography <span>{{ $bibCount }}</span></h2>
<div class="notes-single">
{{- range $bibTypes }}{{ if .pages }}{{ template "bibcard" (dict "label" .label "pages" .pages.ByTitle) }}{{ end }}{{ end }}
</div>
</section>
<p class="notes-empty" id="notes-empty" hidden>Nothing matches this filter.</p>
</article>
{{- end }}
+45
View File
@@ -0,0 +1,45 @@
{{ define "content" -}}
<article class="post">
<header class="post-header">
<h1 class="post-title">{{ .Title }}</h1>
</header>
{{- partial "post/toc.html" . -}}
<div class="post-content">
{{ .Content }}
</div>
{{- $base := .File.BaseFileName }}
{{- $needle := printf `/%s.md"` $base }}
{{- $needle2 := printf `"%s.md"` $base }}
{{- $refs := slice }}
{{- range where site.RegularPages "Section" "in" (slice "book" "article" "phdthesis" "inproceedings" "inbook" "techreport") }}
{{- if or (strings.Contains .RawContent (printf `relref "%s.md"` $base)) (strings.Contains .RawContent (printf `/%s.md"` $base)) }}{{ $refs = $refs | append . }}{{ end }}
{{- end }}
{{- with $refs }}
<section class="note-references">
<h2>References</h2>
<ul>
{{- range sort . "Title" }}<li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>{{ end }}
</ul>
</section>
{{- end }}
{{ partial "backlinks" . }}
<footer class="post-footer">
{{ with .Params.tags -}}
<div class="post-tags">
{{ range . -}}
<a href="{{ "tags" | relLangURL }}/{{ . | urlize }}/">{{ . }}</a>
{{ end -}}
</div>
{{- end -}}
</footer>
</article>
<div id="comments">
{{ partial "comments.html" $ }}
</div>
{{- end }}