diff options
| author | Eltrac <hi@guhub.cn> | 2025-08-20 20:19:32 +0800 |
|---|---|---|
| committer | Eltrac <hi@guhub.cn> | 2025-08-20 20:19:32 +0800 |
| commit | 0f09e731e753a03f0b002d5a64a48a8e233207e7 (patch) | |
| tree | 1c8eed9f82b5534e78d17fe1758a0a04a62e05fd | |
| parent | c0fa9df648ebfb5b69d610bca5ff1261c8164235 (diff) | |
feat: add filters to term page
- refactor term page structure with partials
- add "reverse order" button
- add "hide weekly posts" button
- i18n support
Former-commit-id: f312afd11e292b6ccd5cc3767b1be08aaf4f1495
| -rw-r--r-- | i18n/en.yml | 3 | ||||
| -rw-r--r-- | i18n/zh.yml | 3 | ||||
| -rw-r--r-- | layouts/_partials/items/post-small.html | 4 | ||||
| -rw-r--r-- | layouts/_partials/term/term-books.html | 9 | ||||
| -rw-r--r-- | layouts/_partials/term/term-cards.html | 11 | ||||
| -rw-r--r-- | layouts/_partials/term/term-header.html | 34 | ||||
| -rw-r--r-- | layouts/_partials/term/term-posts.html | 6 | ||||
| -rw-r--r-- | layouts/_partials/term/term-scripts.html | 69 | ||||
| -rw-r--r-- | layouts/term.html | 58 | ||||
| -rw-r--r-- | static/img/clockwork.svg | 6 | ||||
| -rw-r--r-- | static/img/crow.svg | 6 |
11 files changed, 158 insertions, 51 deletions
diff --git a/i18n/en.yml b/i18n/en.yml index 69174498..8c49e8ec 100644 --- a/i18n/en.yml +++ b/i18n/en.yml @@ -29,3 +29,6 @@ library: viewAllThisYear: All Books This Year back2top: I'll take you up! emailMe: If you prefer one-on-one communication, or just want to say hello, feel free to email me at +termFilterButton: + hideWeekly: I'll deal with scarecrows. + reverseOrder: Push to reverse time. diff --git a/i18n/zh.yml b/i18n/zh.yml index b0147949..718e131f 100644 --- a/i18n/zh.yml +++ b/i18n/zh.yml @@ -30,3 +30,6 @@ library: viewAllThisYear: 查看今年完整书单 back2top: 我带你上去! emailMe: 如果你偏好一对一的沟通,或者只是想打个招呼,欢迎发邮件到 +termFilterButton: + hideWeekly: 我帮你解决稻草人 + reverseOrder: 按下以逆转时间 diff --git a/layouts/_partials/items/post-small.html b/layouts/_partials/items/post-small.html index 644cb106..3113ba2b 100644 --- a/layouts/_partials/items/post-small.html +++ b/layouts/_partials/items/post-small.html @@ -1,4 +1,6 @@ -<li class="flex justify-between text-size-lg"> +{{ $isWeekly := (eq .Params.categories "稻草人周刊") }} +<li class="flex justify-between text-size-lg + {{ if $isWeekly }} weekly animate-duration-500 transition-opacity{{ end }}"> <a href="{{ .RelPermalink }}" data-umami-event="🗃️ Click Post Link from Category Page"> {{ .Title }}{{ with .Params.subtitle }}:<span class="text-secondary">{{. }}</span> {{ end }} diff --git a/layouts/_partials/term/term-books.html b/layouts/_partials/term/term-books.html new file mode 100644 index 00000000..5af0a77a --- /dev/null +++ b/layouts/_partials/term/term-books.html @@ -0,0 +1,9 @@ +{{ $books := where .Pages "Section" "eq" "library" }} +{{ if gt (len $books) 0 }} +<h2>{{ T "termPage.books" }}</h2> +<div class="grid grid-cols-4 md:grid-cols-6 items-center gap-4 my-4"> + {{ range $books }} + {{ partial "items/book" . }} + {{ end }} +</div> +{{ end }} diff --git a/layouts/_partials/term/term-cards.html b/layouts/_partials/term/term-cards.html new file mode 100644 index 00000000..f9cd4c1a --- /dev/null +++ b/layouts/_partials/term/term-cards.html @@ -0,0 +1,11 @@ +{{ $cards := where .Pages "Section" "eq" "cards" }} +{{ if gt (len $cards) 0 }} +<h2>{{ T "termPage.cards" }}</h2> +<div class="outbox small"> + <div class="grid grid-cols-2 gap-4"> + {{ range $cards }} + {{ partial "items/card" (dict "context" . "summary" true) }} + {{ end }} + </div> +</div> +{{ end }} diff --git a/layouts/_partials/term/term-header.html b/layouts/_partials/term/term-header.html new file mode 100644 index 00000000..e0501b65 --- /dev/null +++ b/layouts/_partials/term/term-header.html @@ -0,0 +1,34 @@ +<div class="term-header"> + <h1 class="flex items-center justify-between" + style="view-transition-name: category-{{ .Title }}"> + <!-- Tag/Category icon and name --> + <div> + {{ if or (hasPrefix .Page.Params.icon "http://") (hasPrefix .Page.Params.icon "https://") }} + <img src="{{ .Page.Params.icon }}" alt="{{ .Page.LinkTitle }}" + style="height:1em;width:1em"> + {{ else }} + {{ .Page.Params.icon }} + {{ end }} + {{ if and (eq .Data.Singular "tag") (not .Params.icon) }}#{{ end }} + {{ .Title }} + </div> + <!-- Filter buttons --> + <div> + {{ if eq .Data.Singular "tag" }} + <button class="bg-transparent dark:invert" id="hide-weekly" + data-tooltip='{{ T "termFilterButton.hideWeekly" . }}'> + <img src="/img/crow.svg" alt="Hide Weekly" + class="w-6 h-6 block hover:animate-swing" /> + </button> + {{ end }} + <button class="bg-transparent dark:invert" id="reverse-order" + data-tooltip='{{ T "termFilterButton.reverseOrder" . }}'> + <img src="/img/clockwork.svg" alt="Reverse Order" + class="w-6 h-6 block hover:rotate-180 transition-transform" /> + </button> + </div> + </h1> + {{ with .Params.description | markdownify }} + <p class="term-description">{{ . }}</p> + {{ end }} +</div> diff --git a/layouts/_partials/term/term-posts.html b/layouts/_partials/term/term-posts.html new file mode 100644 index 00000000..86e1b350 --- /dev/null +++ b/layouts/_partials/term/term-posts.html @@ -0,0 +1,6 @@ +<ul id="term-posts" + class="animate-duration-100 ps-0 flex flex-col gap-2 list-none leading-relaxed"> + {{ range where .Pages "Section" "not in" (slice "cards" "library") }} + {{ partial "items/post-small" . }} + {{ end }} +</ul> diff --git a/layouts/_partials/term/term-scripts.html b/layouts/_partials/term/term-scripts.html new file mode 100644 index 00000000..b061794a --- /dev/null +++ b/layouts/_partials/term/term-scripts.html @@ -0,0 +1,69 @@ +<script> + const postList = document.getElementById("term-posts") + const reverseButton = document.getElementById("reverse-order") + const reverseOrder = () => { + // play exit animation + postList.classList.remove("animate-fade-in") + postList.classList.add("animate-fade-out") + setTimeout(() => { + // reverse order + postList.classList.toggle("flex-col") + postList.classList.toggle("flex-col-reverse") + + // play entrance animation + postList.classList.remove("animate-fade-out") + postList.classList.add("animate-fade-in") + }, 100) + } + reverseButton.addEventListener('click', reverseOrder) +</script> + +{{ if eq .Data.Singular "tag" }} +<script> + const hideWeeklyButton = document.getElementById("hide-weekly") + const weeklies = postList.querySelectorAll(".weekly") + + const entranceAnimation = "animate-flip-in-x" + const exitAnimation = "animate-flip-out-x" + const animationDuration = 500 + + const toggleWeekly = () => { + if (postList.classList.contains("weekly-hidden")) { + // show weekly posts + postList.classList.remove("weekly-hidden") + weeklies.forEach(weekly => { + weekly.classList.remove("hidden!") + weekly.classList.add(entranceAnimation) + setTimeout(() => { + weekly.classList.remove(entranceAnimation) + }, animationDuration) + }) + } else { + // hide weekly posts + postList.classList.add("weekly-hidden") + weeklies.forEach(weekly => { + weekly.classList.add(exitAnimation) + setTimeout(() => { + weekly.classList.add("hidden!") + weekly.classList.remove(exitAnimation) + }, animationDuration) + }) + } + } + + const highlightClasses = ["animate-flash", "opacity-50"] + + const highlightWeekly = () => { + if (weeklies[0].classList.contains(highlightClasses[0])) return; + weeklies.forEach(e => e.classList.add(...highlightClasses)) + } + + const unhighlightWeekly = () => { + weeklies.forEach(e => e.classList.remove(...highlightClasses)) + } + + hideWeeklyButton.addEventListener("click", toggleWeekly) + hideWeeklyButton.addEventListener("mouseover", highlightWeekly) + hideWeeklyButton.addEventListener("mouseout", unhighlightWeekly) +</script> +{{ end }} diff --git a/layouts/term.html b/layouts/term.html index ffdbdf95..ca87a2a2 100644 --- a/layouts/term.html +++ b/layouts/term.html @@ -2,55 +2,13 @@ <article> {{ partial "header" . }} {{ partial "home/home-nav" . }} - <div class="term-header"> - <h1 class="term-title" - style="view-transition-name: category-{{ .Title }}"> - {{ if or (hasPrefix .Page.Params.icon "http://") (hasPrefix .Page.Params.icon "https://") }} - <span> - <img src="{{ .Page.Params.icon }}" alt="{{ .Page.LinkTitle }}" - style="height:1em;width:1em"> - </span> - {{ else }} - <span>{{ .Page.Params.icon }}</span> - {{ end }} - {{ if and (eq .Data.Singular "tag") (not .Params.icon) }}#{{ end }}{{ .Title }} - </h1> - {{ with .Params.description | markdownify }} - <p class="term-description">{{ . }}</p> - {{ end }} - </div> - <div> - <!-- Posts under this Term --> - <ul class="ps-0 flex flex-col gap-2 list-none leading-relaxed"> - {{ range where .Pages "Section" "not in" (slice "cards" "library") }} - {{ partial "items/post-small" . }} - {{ end }} - </ul> - - <!-- Cards under this Term --> - {{ $cards := where .Pages "Section" "eq" "cards" }} - {{ if gt (len $cards) 0 }} - <h2>{{ T "termPage.cards" }}</h2> - <div class="outbox small"> - <div class="grid grid-cols-2 gap-4"> - {{ range $cards }} - {{ partial "items/card" (dict "context" . "summary" true) }} - {{ end }} - </div> - </div> - {{ end }} - - <!-- Books under this Term --> - {{ $books := where .Pages "Section" "eq" "library" }} - {{ if gt (len $books) 0 }} - <h2>{{ T "termPage.books" }}</h2> - <div class="grid grid-cols-4 md:grid-cols-6 items-center gap-4 my-4"> - {{ range $books }} - {{ partial "items/book" . }} - {{ end }} - </div> - {{ end }} - </div> + {{ partial "term/term-header" . }} + <section> + {{ partial "term/term-posts" . }} + {{ partial "term/term-cards" . }} + {{ partial "term/term-books" . }} + </section> </article> - {{ partial "footer.html" . }} + {{ partial "term/term-scripts" . }} + {{ partial "footer" . }} {{ end }} diff --git a/static/img/clockwork.svg b/static/img/clockwork.svg new file mode 100644 index 00000000..5c3db302 --- /dev/null +++ b/static/img/clockwork.svg @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?>
+<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
+<svg fill="#000000" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
+<title>clockwork</title>
+<path d="M21.393 21.232l-2.949-3.925c0.2-0.375 0.313-0.803 0.313-1.257 0-0.978-0.524-1.834-1.307-2.302v-3.077h1.421l-2.806-8.071-2.842 8.071h1.421v3.114c-0.749 0.475-1.246 1.311-1.246 2.264 0 1.48 1.2 2.68 2.68 2.68 0.046 0 0.091-0.001 0.136-0.003l3.060 4.073-1.082 0.815 7.117 5.045-2.872-8.213-1.043 0.786zM29.447 16.055c0-1.761-0.34-3.442-0.957-4.983l2.449-2.449-7.478-7.478-2.448 2.448c-1.373-0.55-2.857-0.88-4.41-0.945l1.189 2.98c0.345 0.058 0.684 0.133 1.016 0.224 0.085 0.023 0.171 0.048 0.255 0.073 0.021 0.006 0.043 0.013 0.064 0.019 0.098 0.030 0.196 0.062 0.293 0.094 0.020 0.007 0.039 0.014 0.059 0.020 0.084 0.029 0.168 0.059 0.251 0.090 0.019 0.007 0.039 0.014 0.058 0.022 0.096 0.037 0.191 0.074 0.286 0.114 0.018 0.008 0.037 0.016 0.055 0.023 0.083 0.035 0.165 0.071 0.247 0.108 0.017 0.008 0.034 0.015 0.052 0.023 0.094 0.043 0.186 0.087 0.279 0.133 0.017 0.008 0.034 0.017 0.051 0.026 0.082 0.041 0.163 0.083 0.243 0.126 0.015 0.008 0.030 0.016 0.045 0.024 0.091 0.049 0.181 0.1 0.271 0.151 0.016 0.009 0.031 0.018 0.047 0.027 0.081 0.047 0.161 0.095 0.24 0.145 0.012 0.008 0.024 0.015 0.037 0.022 0.088 0.056 0.176 0.112 0.263 0.17 0.014 0.009 0.027 0.019 0.041 0.028 0.080 0.054 0.159 0.109 0.237 0.165 0.009 0.007 0.019 0.013 0.028 0.020 0.086 0.062 0.17 0.125 0.254 0.189 0.012 0.009 0.023 0.018 0.035 0.027 0.079 0.061 0.156 0.123 0.233 0.186 0.006 0.005 0.013 0.010 0.019 0.015 0.083 0.068 0.164 0.138 0.245 0.208 0.010 0.008 0.019 0.017 0.029 0.025 0.077 0.068 0.154 0.138 0.229 0.208 0.003 0.003 0.007 0.006 0.010 0.009 0.079 0.075 0.157 0.15 0.235 0.227 0.008 0.008 0.015 0.015 0.023 0.023 0.076 0.076 0.151 0.153 0.224 0.232 0 0 0.001 0.001 0.001 0.001 0.076 0.081 0.15 0.163 0.223 0.246 0.006 0.006 0.011 0.013 0.017 0.019 0.146 0.166 0.286 0.337 0.421 0.512 0.004 0.005 0.007 0.010 0.011 0.015 0.136 0.177 0.267 0.359 0.392 0.545 0.002 0.003 0.005 0.007 0.007 0.010 0.126 0.188 0.246 0.38 0.36 0.576 0.001 0.002 0.002 0.004 0.003 0.006 0.115 0.198 0.223 0.399 0.325 0.605 0 0 0 0.001 0.001 0.001 0.308 0.62 0.557 1.275 0.739 1.957l0-0c0.233 0.873 0.358 1.79 0.358 2.737s-0.125 1.865-0.358 2.738l-0-0c-0.438 1.639-1.261 3.12-2.364 4.342l1.998 5.415 5.062-5.062-2.449-2.449c0.617-1.541 0.957-3.223 0.957-4.985zM22.965 27.544l-2.622-1.833c-0.37 0.166-0.751 0.311-1.141 0.434-0.017 0.005-0.034 0.011-0.050 0.016-0.053 0.016-0.106 0.032-0.159 0.048-0.023 0.007-0.046 0.013-0.070 0.020-0.052 0.015-0.104 0.030-0.157 0.044l0 0c-0.874 0.234-1.792 0.359-2.739 0.359s-1.864-0.125-2.737-0.358v0c-0.682-0.182-1.337-0.431-1.958-0.739-0.001-0-0.001-0.001-0.002-0.001-0.31-0.154-0.611-0.322-0.902-0.504-0.001-0-0.002-0.001-0.002-0.001-0.291-0.182-0.573-0.379-0.845-0.588-0-0-0.001-0.001-0.001-0.001-0.725-0.558-1.376-1.209-1.935-1.934-0-0-0-0-0-0-0.209-0.272-0.406-0.554-0.588-0.846-0-0.001-0.001-0.001-0.001-0.002-0.182-0.291-0.351-0.592-0.505-0.902-0-0.001-0.001-0.001-0.001-0.002-0.154-0.31-0.293-0.628-0.417-0.955-0-0-0-0-0-0.001-0.124-0.327-0.231-0.661-0.323-1.002v0c-0.234-0.874-0.359-1.793-0.359-2.74s0.125-1.865 0.359-2.739l0 0c0.395-1.476 1.101-2.826 2.045-3.973 0.002-0.002 0.004-0.005 0.006-0.007 0.142-0.173 0.29-0.341 0.443-0.504 0.004-0.005 0.009-0.009 0.013-0.014 0.151-0.161 0.307-0.316 0.467-0.468 0.007-0.007 0.014-0.013 0.021-0.020 0.159-0.149 0.323-0.293 0.491-0.431 0.009-0.008 0.019-0.016 0.028-0.023 0.167-0.137 0.338-0.268 0.513-0.395 0.012-0.008 0.023-0.017 0.035-0.025 0.174-0.125 0.352-0.244 0.533-0.358 0.014-0.009 0.027-0.017 0.041-0.026 0.181-0.113 0.365-0.22 0.553-0.322 0.016-0.008 0.031-0.017 0.047-0.025 0.187-0.1 0.378-0.195 0.572-0.284 0.017-0.008 0.034-0.016 0.052-0.024 0.194-0.088 0.39-0.17 0.59-0.246 0.019-0.007 0.037-0.014 0.056-0.021 0.199-0.075 0.402-0.144 0.607-0.207 0.020-0.006 0.040-0.012 0.060-0.018 0.099-0.030 0.199-0.058 0.299-0.085 0.391-0.105 0.791-0.188 1.198-0.248l1.106-2.95c-1.601 0.052-3.131 0.385-4.543 0.95l-2.45-2.45-7.478 7.478 2.449 2.449c-0.617 1.541-0.957 3.223-0.957 4.985s0.34 3.445 0.958 4.987l-2.449 2.449 7.478 7.478 2.451-2.451c1.541 0.617 3.222 0.956 4.983 0.956s3.444-0.34 4.985-0.957l2.449 2.449 1.81-1.81-2.306-1.612c0 0 0 0 0 0z"></path>
+</svg>
\ No newline at end of file diff --git a/static/img/crow.svg b/static/img/crow.svg new file mode 100644 index 00000000..dca15f56 --- /dev/null +++ b/static/img/crow.svg @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?>
+<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
+<svg fill="#000000" width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
+<title>raven</title>
+<path d="M25.247 3.718c-0.552-1.358-2.036-2.332-3.826-2.332-3.577 0-3.821 2.257-5.685 3.425-6.078-2.157-7.43 9.009-5.138 15.779-0.961 1.992-1.917 4.736-2.733 8.418 3.546 1.913 7.433 2.413 11.37 0.619-0.387-2.353-0.885-4.297-1.371-5.952 1.561-0.788 3.719-0.91 5.398 0.898 0.016-1.916-1.369-2.662-2.824-2.643l-1.291-2.726c2.763-2.851 4.877-6.378 3.822-10.020-0.643-2.399 3.633-3.882 7.635-3.354-1.53-1.321-3.494-1.902-5.357-2.114zM17.077 21.137c0.547-0.465 1.092-0.959 1.62-1.478l1.102 2.329c-0.838 0.135-1.634 0.507-2.13 1.037-0.206-0.677-0.406-1.303-0.592-1.888zM23.139 4.292c-0.228 0-0.413-0.185-0.413-0.413s0.185-0.413 0.413-0.413 0.413 0.185 0.413 0.413c0 0.228-0.185 0.413-0.413 0.413z"></path>
+</svg>
\ No newline at end of file |
