Add list styles: Podium, Spotlight, Grid, List
- Each list picks a style in List settings (new lists default to Podium); existing lists keep Grid or List - Podium: top 3 on medal-colored steps (#1 center and raised), the rest behind a native <details> "Show N more"; stacks #1 over #2/#3 on phones - Spotlight: #1 as a feature card (art, why-note or description, play button), the rest as a numbered list - Visitors can switch styles on a list page (?style=), preserved across pages; later pages fall back to a plain list since they don't start at #1 - Entries' detail data now lives on a wrapper per list, so featured and collapsed entries all open the detail view Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b09533cc00
commit
ddf2157e63
15 files changed
+286
-65
No files matched your search
@@ -30,7 +30,7 @@
|
||||
</div>
|
||||
<a class="see-all" href="/l/{{.List.Slug}}">{{if .More}}All {{num .List.ItemCount}}{{else}}Open{{end}}{{icon "arrow-right"}}</a>
|
||||
</header>
|
||||
{{if .Items}}{{template "items" (dict "Items" .Items "Category" .Category "Layout" .List.Layout "Title" .List.Title)}}{{end}}
|
||||
{{if .Items}}{{template "ranked" (dict "Items" .Items "Category" .Category "Style" .List.Layout "Title" .List.Title "AllLink" (and (gt .More 0) (print "/l/" .List.Slug)) "Total" .List.ItemCount)}}{{end}}
|
||||
</section>
|
||||
{{end}}
|
||||
{{else}}
|
||||
|
||||
@@ -18,10 +18,11 @@
|
||||
<div class="list-actions">
|
||||
{{if $.LoggedIn}}<a class="btn btn--ghost" href="/admin/lists/{{.List.ID}}">{{icon "pencil"}}Edit</a>{{if .Items}}{{template "export" .List.Slug}}{{end}}{{end}}
|
||||
{{if .Items}}
|
||||
<div class="segmented" role="group" aria-label="Layout" data-layout-toggle data-default="{{.List.Layout}}" data-key="{{.List.Slug}}">
|
||||
<button type="button" data-layout="grid" title="Grid">{{icon "grid"}}<span class="sr-only">Grid</span></button>
|
||||
<button type="button" data-layout="rows" title="List">{{icon "rows"}}<span class="sr-only">List</span></button>
|
||||
</div>
|
||||
<nav class="segmented" aria-label="Style">
|
||||
{{- range .Styles}}
|
||||
<a href="?style={{.Key}}" title="{{.Label}}"{{if eq .Key $.Data.Style}} aria-current="true"{{end}}>{{icon .Icon}}<span class="sr-only">{{.Label}}</span></a>
|
||||
{{- end}}
|
||||
</nav>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -30,16 +31,16 @@
|
||||
|
||||
<div class="container list-body">
|
||||
{{if .Items}}
|
||||
{{template "items" (dict "Items" .Items "Category" .Category "Layout" .List.Layout "Title" .List.Title)}}
|
||||
{{template "ranked" (dict "Items" .Items "Category" .Category "Style" .Style "Title" .List.Title)}}
|
||||
{{if .PageNums}}
|
||||
<nav class="pager" aria-label="Pages">
|
||||
{{if gt .Page 1}}<a class="pager-btn" href="?page={{add .Page -1}}" rel="prev">{{icon "chevron-left"}}<span class="sr-only">Previous</span></a>{{end}}
|
||||
{{if gt .Page 1}}<a class="pager-btn" href="?page={{add .Page -1}}{{.PageQS}}" rel="prev">{{icon "chevron-left"}}<span class="sr-only">Previous</span></a>{{end}}
|
||||
{{range .PageNums}}
|
||||
{{if eq . 0}}<span class="pager-gap">…</span>
|
||||
{{else if eq . $.Data.Page}}<span class="pager-btn is-current" aria-current="page">{{.}}</span>
|
||||
{{else}}<a class="pager-btn" href="?page={{.}}">{{.}}</a>{{end}}
|
||||
{{else}}<a class="pager-btn" href="?page={{.}}{{$.Data.PageQS}}">{{.}}</a>{{end}}
|
||||
{{end}}
|
||||
{{if lt .Page .Pages}}<a class="pager-btn" href="?page={{add .Page 1}}" rel="next">{{icon "chevron-right"}}<span class="sr-only">Next</span></a>{{end}}
|
||||
{{if lt .Page .Pages}}<a class="pager-btn" href="?page={{add .Page 1}}{{.PageQS}}" rel="next">{{icon "chevron-right"}}<span class="sr-only">Next</span></a>{{end}}
|
||||
</nav>
|
||||
{{end}}
|
||||
{{else}}
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
{{define "items"}}
|
||||
<ol class="items items--{{.Layout}} aspect-{{.Category.Aspect}}" data-items data-list-title="{{.Title}}" start="{{with index .Items 0}}{{.Rank}}{{end}}">
|
||||
<ol class="items items--{{.Layout}}" start="{{with index .Items 0}}{{.Rank}}{{end}}">
|
||||
{{- range .Items}}
|
||||
<li class="item{{if le .Rank 3}} item--top item--top{{.Rank}}{{end}}">
|
||||
<button type="button" class="item-btn" data-item="{{.ID}}">
|
||||
<span class="item-art">
|
||||
{{- if .Image}}<img src="{{.Image}}" alt="" loading="lazy" decoding="async">{{else}}<span class="art-fallback">{{icon $.Category.Icon}}</span>{{end -}}
|
||||
{{- template "art" (dict "Item" . "Icon" $.Category.Icon)}}
|
||||
<span class="rank-badge" aria-hidden="true">{{.Rank}}</span>
|
||||
</span>
|
||||
<span class="item-rank" aria-hidden="true">{{.Rank}}</span>
|
||||
<span class="item-body">
|
||||
<span class="item-title"><span class="sr-only">#{{.Rank}}: </span>{{.Title}}</span>
|
||||
{{- if .Badge}}
|
||||
{{- with .Subtitle}}<span class="item-sub">{{.}}</span>{{end}}
|
||||
<span class="item-tags"><span class="badge">{{.Badge}}</span>{{with .Year}}<span class="item-year">{{.}}</span>{{end}}</span>
|
||||
{{- else if or .Subtitle .Year}}
|
||||
<span class="item-sub">{{.Subtitle}}{{if and .Subtitle .Year}}<span class="dot" aria-hidden="true">·</span>{{end}}{{.Year}}</span>
|
||||
{{- end}}
|
||||
{{- template "itemsub" .}}
|
||||
{{- with .Note}}<span class="item-note">{{.}}</span>{{end}}
|
||||
</span>
|
||||
</button>
|
||||
{{- if .Preview}}
|
||||
<button type="button" class="play-btn" data-preview-src="/preview/{{.ID}}" aria-pressed="false" aria-label="Play a preview of {{.Title}}" title="Play 30-second preview">{{icon "play"}}{{icon "pause"}}</button>
|
||||
{{- end}}
|
||||
{{- template "playbtn" .}}
|
||||
</li>
|
||||
{{- end}}
|
||||
</ol>
|
||||
<script type="application/json" class="items-data">{{.Items}}</script>
|
||||
{{end}}
|
||||
|
||||
{{/* Shared bits of an entry. */}}
|
||||
{{define "art"}}{{if .Item.Image}}<img src="{{.Item.Image}}" alt="" loading="lazy" decoding="async">{{else}}<span class="art-fallback">{{icon .Icon}}</span>{{end}}{{end}}
|
||||
|
||||
{{define "itemsub"}}
|
||||
{{- if .Badge}}
|
||||
{{- with .Subtitle}}<span class="item-sub">{{.}}</span>{{end}}
|
||||
<span class="item-tags"><span class="badge">{{.Badge}}</span>{{with .Year}}<span class="item-year">{{.}}</span>{{end}}</span>
|
||||
{{- else if or .Subtitle .Year}}
|
||||
<span class="item-sub">{{.Subtitle}}{{if and .Subtitle .Year}}<span class="dot" aria-hidden="true">·</span>{{end}}{{.Year}}</span>
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
{{define "playbtn"}}{{if .Preview}}<button type="button" class="play-btn" data-preview-src="/preview/{{.ID}}" aria-pressed="false" aria-label="Play a preview of {{.Title}}" title="Play 30-second preview">{{icon "play"}}{{icon "pause"}}</button>{{end}}{{end}}
|
||||
@@ -0,0 +1,72 @@
|
||||
{{/*
|
||||
ranked draws a list in its style. Takes: Items, Category, Style, Title,
|
||||
and optionally AllLink/Total (home page: link to the full list).
|
||||
Podium and Spotlight feature #1, so a page that doesn't start at #1 falls
|
||||
back to a plain list.
|
||||
*/}}
|
||||
{{define "ranked"}}
|
||||
{{- $featured := and (or (eq .Style "podium") (eq .Style "spotlight")) (eq (index .Items 0).Rank 1)}}
|
||||
<div class="ranked ranked--{{if $featured}}{{.Style}}{{else}}{{flatLayout .Style}}{{end}} aspect-{{.Category.Aspect}}" data-items data-list-title="{{.Title}}">
|
||||
{{- if and $featured (eq .Style "podium")}}{{template "podium" .}}
|
||||
{{- else if $featured}}{{template "spotlight" .}}
|
||||
{{- else}}{{template "items" (dict "Items" .Items "Category" .Category "Layout" (flatLayout .Style))}}
|
||||
{{- end}}
|
||||
<script type="application/json" class="items-data">{{.Items}}</script>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{define "podium"}}
|
||||
{{- $c := .Category}}
|
||||
{{- $top := first 3 .Items}}
|
||||
<ol class="podium podium--{{len $top}}">
|
||||
{{- range $top}}
|
||||
<li class="podium-spot podium-spot--{{.Rank}}">
|
||||
<button type="button" class="item-btn podium-card" data-item="{{.ID}}">
|
||||
<span class="item-art">{{template "art" (dict "Item" . "Icon" $c.Icon)}}</span>
|
||||
<span class="item-body">
|
||||
<span class="item-title"><span class="sr-only">#{{.Rank}}: </span>{{.Title}}</span>
|
||||
{{- template "itemsub" .}}
|
||||
</span>
|
||||
</button>
|
||||
{{- template "playbtn" .}}
|
||||
<span class="podium-step" aria-hidden="true"><span>{{.Rank}}</span></span>
|
||||
</li>
|
||||
{{- end}}
|
||||
</ol>
|
||||
{{- $rest := after 3 .Items}}
|
||||
{{- if $rest}}
|
||||
<details class="more">
|
||||
<summary class="more-btn"><span class="more-closed">Show {{len $rest}} more</span><span class="more-open">Show less</span>{{icon "chevron-down"}}</summary>
|
||||
{{template "items" (dict "Items" $rest "Category" $c "Layout" "rows")}}
|
||||
{{- if .AllLink}}<a class="more-all" href="{{.AllLink}}">See all {{num .Total}}{{icon "arrow-right"}}</a>{{end}}
|
||||
</details>
|
||||
{{- else if .AllLink}}
|
||||
<a class="more-all" href="{{.AllLink}}">See all {{num .Total}}{{icon "arrow-right"}}</a>
|
||||
{{- end}}
|
||||
{{end}}
|
||||
|
||||
{{define "spotlight"}}
|
||||
{{- $c := .Category}}
|
||||
{{- with index .Items 0}}
|
||||
<article class="spotlight">
|
||||
{{- if .Image}}<div class="spotlight-bg" aria-hidden="true"><img src="{{.Image}}" alt=""></div>{{end}}
|
||||
<div class="spotlight-art">
|
||||
<button type="button" class="item-btn" data-item="{{.ID}}" aria-label="#1: {{.Title}}">
|
||||
<span class="item-art">{{template "art" (dict "Item" . "Icon" $c.Icon)}}</span>
|
||||
</button>
|
||||
{{- template "playbtn" .}}
|
||||
</div>
|
||||
<div class="spotlight-body">
|
||||
<p class="spotlight-rank">#1</p>
|
||||
<h3 class="spotlight-title">{{.Title}}</h3>
|
||||
{{- template "itemsub" .}}
|
||||
{{- with .Note}}<blockquote class="spotlight-note">{{.}}</blockquote>
|
||||
{{- else}}{{with .Description}}<p class="spotlight-desc">{{.}}</p>{{end}}{{end}}
|
||||
<button type="button" class="btn btn--sm spotlight-more" data-item="{{.ID}}">More about it{{icon "arrow-right"}}</button>
|
||||
</div>
|
||||
</article>
|
||||
{{- end}}
|
||||
{{- $rest := after 1 .Items}}
|
||||
{{- if $rest}}{{template "items" (dict "Items" $rest "Category" $c "Layout" "rows")}}{{end}}
|
||||
{{- if .AllLink}}<a class="more-all" href="{{.AllLink}}">See all {{num .Total}}{{icon "arrow-right"}}</a>{{end}}
|
||||
{{end}}
|
||||
Reference in new issue
Block a user