feat(publications): improve structure + awards/funding/license metadata

Restructure `publication` frontmatter from a flat Markdown string into a
structured object (name, short_name, volume, issue, pages, publisher),
resolved through a new `functions/resolve_publication.html` partial that
also emits a per-page warning pointing legacy sites at `hugoblox migrate
publications`. APA/MLA citation rendering and the publication metadata
row both consume the resolver - no parsing of conventional Markdown
strings at render time.

Add work-level metadata fields surfaced via a new reusable
`components/award_badge.html` partial (variants: pill, card-corner,
inline, row; level-driven icon + colour tokens; pagefind filter):

- `awards[]` - name, level (winner/runner_up/honorable_mention/nominee/
  selected/featured), issuer, date, note, url; skim-row pills above the
  featured image, full row in the metadata grid, corner badges on card
  and slides-gallery views, inline marker on citation views, pill on
  date-title-summary
- `funding[]` - funder + grant + url, rendered as a metadata grid row
- `license` - SPDX-friendly string, metadata grid row
- `peer_reviewed`, `open_access` - status pills, decoupled from
  the publication block so preprints can surface them

Demo content updated in academic-cv (and the same shape in research-lab).
This commit is contained in:
George Cushen committed 2026-05-27 03:53:21 +01:00
1 parent 64cdb4a81a
commit 26c336eb6d
12 files changed
+439 -27

No files matched your search

+50 -2
View File
@@ -142,6 +142,15 @@
<div class="mt-3">
{{ partial "page_links_div.html" . }}
</div>
{{/* Awards skim row — visible badges above any featured image */}}
{{ with .Params.awards }}
<div class="mt-4 flex flex-wrap gap-2">
{{ range . }}
{{ partial "components/award_badge.html" (dict "award" . "page" $ "variant" "pill") }}
{{ end }}
</div>
{{ end }}
</div>
@@ -227,6 +236,7 @@
{{end}}
{{/* EVENT / PUBLICATION METADATA */}}
{{ $pub := partial "functions/resolve_publication.html" . }}
{{ if .Params.abstract | or (eq .Type "publications") | or (eq .Type "events") }}
<div class="max-w-prose grid grid-cols-1 md:grid-cols-[200px_auto] gap-4 my-6">
@@ -247,9 +257,47 @@
</div>
{{ end }}
{{ if .Params.publication }}
{{ if not $pub.is_empty }}
<div class="font-bold text-2xl">{{ i18n "publication" }}</div>
<div>{{ .Params.publication | markdownify }}</div>
<div>{{ $pub.display | markdownify }}{{ with $pub.publisher }}. {{ . | markdownify }}{{ end }}</div>
{{ end }}
{{/* Work-level flags — independent of whether a venue is set, so preprints can still surface OA/peer-review status. */}}
{{ $flags := slice }}
{{ if eq .Params.peer_reviewed true }}{{ $flags = $flags | append (i18n "peer_reviewed") }}{{ end }}
{{ if eq .Params.open_access true }}{{ $flags = $flags | append (i18n "open_access") }}{{ end }}
{{ with $flags }}
<div class="font-bold text-2xl">{{ i18n "status" | default "Status" }}</div>
<div class="flex flex-wrap gap-2">
{{ range . }}
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-[11px] font-medium bg-emerald-100 text-emerald-900 dark:bg-emerald-900/40 dark:text-emerald-200 ring-1 ring-emerald-500/30">{{ . }}</span>
{{ end }}
</div>
{{ end }}
{{ with .Params.awards }}
<div class="font-bold text-2xl">{{ i18n "awards" }}</div>
<div class="space-y-3">
{{ range . }}
{{ partial "components/award_badge.html" (dict "award" . "page" $ "variant" "row") }}
{{ end }}
</div>
{{ end }}
{{ with .Params.funding }}
<div class="font-bold text-2xl">{{ i18n "funding" }}</div>
<div class="space-y-1">
{{ range . }}
<div>
{{ if .url }}<a href="{{ .url }}" target="_blank" rel="noopener" class="hover:underline">{{ .funder }}</a>{{ else }}{{ .funder }}{{ end }}{{ with .grant }} <span class="text-gray-500 dark:text-gray-400">({{ . }})</span>{{ end }}
</div>
{{ end }}
</div>
{{ end }}
{{ with .Params.license }}
<div class="font-bold text-2xl">{{ i18n "license" }}</div>
<div>{{ . }}</div>
{{ end }}
{{ if eq .Type "events" }}