asw-v01: archive deferred content (packs, site, lab, legacy examples)
- 2.1: packs/ -> archive/packs/ - 2.2: site/ -> archive/site/ - 2.3: src/lab/ -> archive/lab/ - 2.4: examples/ -> archive/examples-legacy/ (SSI-based)
This commit is contained in:
parent
416fe2f180
commit
e47a9f4401
173 changed files with 11 additions and 5 deletions
13
archive/site/layouts/_default/_markup/render-footnotes.html
Normal file
13
archive/site/layouts/_default/_markup/render-footnotes.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{{- /* render-footnotes.html
|
||||
Replace Hugo's default <div class="footnotes"> with ASW-semantic markup.
|
||||
Hugo v0.123.0+ render hook for the footnote block.
|
||||
Ref: https://gohugo.io/render-hooks/footnotes/
|
||||
*/ -}}
|
||||
<footer data-role="footnotes">
|
||||
<hr>
|
||||
<ol>
|
||||
{{- range .Items }}
|
||||
<li id="{{ .ID }}">{{ .Content }}{{ .Return }}</li>
|
||||
{{- end }}
|
||||
</ol>
|
||||
</footer>
|
||||
43
archive/site/layouts/_default/baseof.html
Normal file
43
archive/site/layouts/_default/baseof.html
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ .Site.LanguageCode | default "en" }}">
|
||||
<head>
|
||||
{{- partial "head.html" . -}}
|
||||
</head>
|
||||
<body>
|
||||
{{ partial "nav.html" . }}
|
||||
{{ block "content" . }}{{ end }}
|
||||
<footer>
|
||||
<header>
|
||||
<strong>Agentic Semantic Web</strong>
|
||||
<p>Semantic HTML for the agentic era.</p>
|
||||
</header>
|
||||
<nav aria-label="Framework">
|
||||
<h3>Framework</h3>
|
||||
<ul>
|
||||
<li><a href="/docs/getting-started/introduction/">Getting Started</a></li>
|
||||
<li><a href="/docs/core/tokens/">Token System</a></li>
|
||||
<li><a href="/docs/core/data-attributes/">Data Attributes</a></li>
|
||||
<li><a href="/layouts/">Layouts</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav aria-label="Resources">
|
||||
<h3>Resources</h3>
|
||||
<ul>
|
||||
<li><a href="/docs/packs/overview/">Packs</a></li>
|
||||
<li><a href="/docs/reference/vocabulary/">Vocabulary</a></li>
|
||||
<li><a href="/docs/reference/charts/">Charts</a></li>
|
||||
<li><a href="/lab/">Lab</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav aria-label="Project">
|
||||
<h3>Project</h3>
|
||||
<ul>
|
||||
<li><a href="https://git.trentuna.com/trentuna/asw">Source</a></li>
|
||||
<li><a href="/docs/llms.txt">llms.txt</a></li>
|
||||
<li><a href="https://trentuna.com">trentuna.com</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<p>Built by <a href="https://trentuna.com">Trentuna</a> · Styled by ASW · {{ now.Format "2006" }}</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
26
archive/site/layouts/_default/list.html
Normal file
26
archive/site/layouts/_default/list.html
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{{ define "content" }}
|
||||
<article>
|
||||
<header>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{- with .Description }}
|
||||
<p>{{ . }}</p>
|
||||
{{- end }}
|
||||
</header>
|
||||
|
||||
{{ .Content }}
|
||||
|
||||
{{ range .Pages }}
|
||||
<article>
|
||||
<header>
|
||||
<h2><a href="{{ .Permalink }}">{{ .Title }}</a></h2>
|
||||
{{- if not .Date.IsZero }}
|
||||
<p data-text="dim">
|
||||
<time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "January 2006" }}</time>
|
||||
</p>
|
||||
{{- end }}
|
||||
</header>
|
||||
{{- with .Description }}<p>{{ . }}</p>{{ end }}
|
||||
</article>
|
||||
{{ end }}
|
||||
</article>
|
||||
{{ end }}
|
||||
39
archive/site/layouts/_default/single.html
Normal file
39
archive/site/layouts/_default/single.html
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{{ define "content" }}
|
||||
<article>
|
||||
<header>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{- with .Description }}
|
||||
<p>{{ . }}</p>
|
||||
{{- end }}
|
||||
{{- if or (not .Date.IsZero) .Params.author }}
|
||||
<p data-text="dim">
|
||||
{{- if not .Date.IsZero -}}
|
||||
<time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "January 2, 2006" }}</time>
|
||||
{{- end -}}
|
||||
{{- if and (not .Date.IsZero) .Params.author }} · {{ end -}}
|
||||
{{- with .Params.author }}{{ . }}{{ end -}}
|
||||
</p>
|
||||
{{- end }}
|
||||
{{- with .GetTerms "tags" }}
|
||||
<nav aria-label="Tags">
|
||||
{{- range . }}
|
||||
<a href="{{ .Permalink }}">#{{ .Name }}</a>
|
||||
{{- end }}
|
||||
</nav>
|
||||
{{- end }}
|
||||
</header>
|
||||
|
||||
{{ .Content }}
|
||||
|
||||
{{- if or .PrevInSection .NextInSection }}
|
||||
<footer data-role="prev-next">
|
||||
{{- with .PrevInSection }}
|
||||
<a href="{{ .RelPermalink }}" rel="prev"><span aria-hidden="true">←</span> {{ .LinkTitle }}</a>
|
||||
{{- end }}
|
||||
{{- with .NextInSection }}
|
||||
<a href="{{ .RelPermalink }}" rel="next">{{ .LinkTitle }} <span aria-hidden="true">→</span></a>
|
||||
{{- end }}
|
||||
</footer>
|
||||
{{- end }}
|
||||
</article>
|
||||
{{ end }}
|
||||
40
archive/site/layouts/console/single.html
Normal file
40
archive/site/layouts/console/single.html
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{{ define "content" }}
|
||||
<section data-layout="console">
|
||||
|
||||
<nav aria-label="Documentation" data-nav="sidebar">
|
||||
{{- $top := .FirstSection -}}
|
||||
{{- range $top.Sections.ByWeight -}}
|
||||
<h3>{{ .Title }}</h3>
|
||||
<ul>
|
||||
{{- range .RegularPages.ByWeight -}}
|
||||
<li>
|
||||
<a href="{{ .RelPermalink }}"
|
||||
{{- if eq .RelPermalink $.RelPermalink }} aria-current="page"{{ end -}}>
|
||||
{{- .LinkTitle -}}
|
||||
</a>
|
||||
</li>
|
||||
{{- end -}}
|
||||
</ul>
|
||||
{{- end -}}
|
||||
</nav>
|
||||
|
||||
<article>
|
||||
<header>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{- with .Description }}
|
||||
<p>{{ . }}</p>
|
||||
{{- end }}
|
||||
</header>
|
||||
|
||||
{{ .Content }}
|
||||
</article>
|
||||
|
||||
{{- with .TableOfContents -}}
|
||||
<aside data-toc>
|
||||
<h3>{{ i18n "onThisPage" | default "On this page" }}</h3>
|
||||
{{ . }}
|
||||
</aside>
|
||||
{{- end -}}
|
||||
|
||||
</section>
|
||||
{{ end }}
|
||||
84
archive/site/layouts/docs/single.html
Normal file
84
archive/site/layouts/docs/single.html
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
{{ define "content" }}
|
||||
<section data-layout="docs">
|
||||
|
||||
<nav aria-label="Documentation" data-nav="sidebar">
|
||||
{{- $top := .FirstSection -}}
|
||||
{{- range $top.Sections.ByWeight -}}
|
||||
<h3>{{ .Title }}</h3>
|
||||
<ul>
|
||||
{{- range .RegularPages.ByWeight -}}
|
||||
<li>
|
||||
<a href="{{ .RelPermalink }}"
|
||||
{{- if eq .RelPermalink $.RelPermalink }} aria-current="page"{{ end -}}>
|
||||
{{- .LinkTitle -}}
|
||||
</a>
|
||||
</li>
|
||||
{{- end -}}
|
||||
</ul>
|
||||
{{- end -}}
|
||||
</nav>
|
||||
|
||||
<article>
|
||||
<header>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{- with .Description }}
|
||||
<p>{{ . }}</p>
|
||||
{{- end }}
|
||||
</header>
|
||||
|
||||
{{ .Content }}
|
||||
|
||||
{{- if or .PrevInSection .NextInSection -}}
|
||||
<footer data-role="prev-next">
|
||||
{{- with .NextInSection -}}
|
||||
<a href="{{ .RelPermalink }}" rel="prev">
|
||||
<span aria-hidden="true">←</span> {{ .LinkTitle }}
|
||||
</a>
|
||||
{{- end -}}
|
||||
{{- with .PrevInSection -}}
|
||||
<a href="{{ .RelPermalink }}" rel="next">
|
||||
{{ .LinkTitle }} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
{{- end -}}
|
||||
</footer>
|
||||
{{- end -}}
|
||||
</article>
|
||||
|
||||
{{- with .TableOfContents -}}
|
||||
<aside data-toc>
|
||||
<h3>{{ i18n "onThisPage" | default "On this page" }}</h3>
|
||||
{{ . }}
|
||||
</aside>
|
||||
{{- end -}}
|
||||
|
||||
</section>
|
||||
<script>
|
||||
// TOC scroll spy — highlights current section in the aside
|
||||
(function(){
|
||||
var toc = document.querySelector('[data-toc]');
|
||||
if (!toc) return;
|
||||
var links = toc.querySelectorAll('a');
|
||||
if (!links.length) return;
|
||||
var headings = [];
|
||||
links.forEach(function(a) {
|
||||
var id = a.getAttribute('href');
|
||||
if (id && id.startsWith('#')) {
|
||||
var el = document.getElementById(id.slice(1));
|
||||
if (el) headings.push({ el: el, link: a });
|
||||
}
|
||||
});
|
||||
if (!headings.length) return;
|
||||
var observer = new IntersectionObserver(function(entries) {
|
||||
entries.forEach(function(entry) {
|
||||
if (entry.isIntersecting) {
|
||||
links.forEach(function(a) { a.removeAttribute('aria-current'); });
|
||||
headings.forEach(function(h) {
|
||||
if (h.el === entry.target) h.link.setAttribute('aria-current', 'true');
|
||||
});
|
||||
}
|
||||
});
|
||||
}, { rootMargin: '0px 0px -70% 0px' });
|
||||
headings.forEach(function(h) { observer.observe(h.el); });
|
||||
})();
|
||||
</script>
|
||||
{{ end }}
|
||||
40
archive/site/layouts/essay/single.html
Normal file
40
archive/site/layouts/essay/single.html
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{{ define "content" }}
|
||||
<article data-paper>
|
||||
<header>
|
||||
{{- with .Params.eyebrow }}<p data-text="eyebrow">{{ . }}</p>{{ end }}
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{- with .Params.abstract }}
|
||||
<p data-abstract>{{ . }}</p>
|
||||
{{- end }}
|
||||
{{- if or (not .Date.IsZero) .Params.author }}
|
||||
<p data-byline>
|
||||
{{- if not .Date.IsZero -}}
|
||||
<time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "January 2, 2006" }}</time>
|
||||
{{- end -}}
|
||||
{{- if and (not .Date.IsZero) .Params.author }} · {{ end -}}
|
||||
{{- with .Params.author }}{{ . }}{{ end -}}
|
||||
</p>
|
||||
{{- end }}
|
||||
{{- with .GetTerms "tags" }}
|
||||
<nav data-role="tag-cloud" aria-label="Tags">
|
||||
{{- range . }}
|
||||
<a href="{{ .Permalink }}">{{ .Name }}</a>
|
||||
{{- end }}
|
||||
</nav>
|
||||
{{- end }}
|
||||
</header>
|
||||
|
||||
{{ .Content }}
|
||||
|
||||
{{- if or .PrevInSection .NextInSection }}
|
||||
<footer data-role="prev-next">
|
||||
{{- with .PrevInSection }}
|
||||
<a href="{{ .RelPermalink }}" rel="prev"><span aria-hidden="true">←</span> {{ .LinkTitle }}</a>
|
||||
{{- end }}
|
||||
{{- with .NextInSection }}
|
||||
<a href="{{ .RelPermalink }}" rel="next">{{ .LinkTitle }} <span aria-hidden="true">→</span></a>
|
||||
{{- end }}
|
||||
</footer>
|
||||
{{- end }}
|
||||
</article>
|
||||
{{ end }}
|
||||
5
archive/site/layouts/index.html
Normal file
5
archive/site/layouts/index.html
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{{ define "content" }}
|
||||
<main data-landing>
|
||||
{{ .Content }}
|
||||
</main>
|
||||
{{ end }}
|
||||
11
archive/site/layouts/layouts/list.html
Normal file
11
archive/site/layouts/layouts/list.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{{ define "content" }}
|
||||
<article>
|
||||
<header>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{- with .Description }}
|
||||
<p>{{ . }}</p>
|
||||
{{- end }}
|
||||
</header>
|
||||
{{ .Content }}
|
||||
</article>
|
||||
{{ end }}
|
||||
39
archive/site/layouts/notes/single.html
Normal file
39
archive/site/layouts/notes/single.html
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{{ define "content" }}
|
||||
<section data-layout="docs">
|
||||
|
||||
<nav aria-label="Notes" data-nav="sidebar">
|
||||
{{- with .CurrentSection -}}
|
||||
<h3>{{ .Title }}</h3>
|
||||
<ul>
|
||||
{{- range .RegularPages.ByWeight -}}
|
||||
<li>
|
||||
<a href="{{ .RelPermalink }}"
|
||||
{{- if eq .RelPermalink $.RelPermalink }} aria-current="page"{{ end -}}>
|
||||
{{- .LinkTitle -}}
|
||||
</a>
|
||||
</li>
|
||||
{{- end -}}
|
||||
</ul>
|
||||
{{- end -}}
|
||||
</nav>
|
||||
|
||||
<article>
|
||||
<header>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{- with .Description }}
|
||||
<p>{{ . }}</p>
|
||||
{{- end }}
|
||||
</header>
|
||||
|
||||
{{ .Content }}
|
||||
</article>
|
||||
|
||||
{{- with .TableOfContents -}}
|
||||
<aside data-toc>
|
||||
<h3>{{ i18n "onThisPage" | default "On this page" }}</h3>
|
||||
{{ . }}
|
||||
</aside>
|
||||
{{- end -}}
|
||||
|
||||
</section>
|
||||
{{ end }}
|
||||
11
archive/site/layouts/page/single.html
Normal file
11
archive/site/layouts/page/single.html
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{{ define "content" }}
|
||||
<article>
|
||||
<header>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{- with .Description }}
|
||||
<p>{{ . }}</p>
|
||||
{{- end }}
|
||||
</header>
|
||||
{{ .Content }}
|
||||
</article>
|
||||
{{ end }}
|
||||
62
archive/site/layouts/partials/head.html
Normal file
62
archive/site/layouts/partials/head.html
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="color-scheme" content="dark">
|
||||
<title>
|
||||
{{- if .IsHome -}}
|
||||
{{ .Site.Title }}
|
||||
{{- else -}}
|
||||
{{ .Title }} · {{ .Site.Title }}
|
||||
{{- end -}}
|
||||
</title>
|
||||
{{- with .Description }}<meta name="description" content="{{ . }}">{{- end }}
|
||||
{{- if not .Description }}{{- with .Site.Params.description }}<meta name="description" content="{{ . }}">{{- end }}{{- end }}
|
||||
|
||||
{{- /* ── Meta partials ─────────────────────────────────────────── */}}
|
||||
{{- partial "meta/seo.html" . -}}
|
||||
{{- partial "meta/og.html" . -}}
|
||||
{{- partial "meta/ai-disclosure.html" . -}}
|
||||
{{- partial "meta/json-ld.html" . -}}
|
||||
|
||||
{{- /* ── CSS ────────────────────────────────────────────────────── */}}
|
||||
{{- if hugo.IsDevelopment }}
|
||||
<link rel="stylesheet" href="/vendor/open-props.min.css">
|
||||
<link rel="stylesheet" href="/vendor/media.min.css">
|
||||
<link rel="stylesheet" href="/css/layers/00-reset.css">
|
||||
<link rel="stylesheet" href="/css/layers/01-tokens.css">
|
||||
<link rel="stylesheet" href="/css/layers/02-typography.css">
|
||||
<link rel="stylesheet" href="/css/layers/03-landmarks.css">
|
||||
<link rel="stylesheet" href="/css/layers/04-forms.css">
|
||||
<link rel="stylesheet" href="/css/layers/05-components.css">
|
||||
<link rel="stylesheet" href="/css/layers/06-navigation.css">
|
||||
<link rel="stylesheet" href="/css/layers/07-data-attrs.css">
|
||||
<link rel="stylesheet" href="/css/layers/08-utilities.css">
|
||||
<link rel="stylesheet" href="/css/layers/09-charts.css">
|
||||
<link rel="stylesheet" href="/css/layers/10-chroma.css">
|
||||
<link rel="stylesheet" href="/css/layers/11-layout.css">
|
||||
<link rel="stylesheet" href="/css/layers/12-landing.css">
|
||||
{{- else }}
|
||||
<link rel="stylesheet" href="/asw.css">
|
||||
{{- end }}
|
||||
|
||||
{{- range .AlternativeOutputFormats -}}
|
||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
|
||||
{{- end }}
|
||||
<script>
|
||||
// Theme toggle — respects OS preference, persists choice
|
||||
(function(){
|
||||
var s = localStorage.getItem('theme');
|
||||
if (s) document.documentElement.setAttribute('data-theme', s);
|
||||
document.addEventListener('click', function(e) {
|
||||
var b = e.target.closest('[data-theme-toggle]');
|
||||
if (!b) return;
|
||||
var current = document.documentElement.getAttribute('data-theme')
|
||||
|| (matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark');
|
||||
var next = current === 'light' ? 'dark' : 'light';
|
||||
document.documentElement.setAttribute('data-theme', next);
|
||||
localStorage.setItem('theme', next);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- Umami analytics — estate dashboard -->
|
||||
<script defer src="https://analytics.trentuna.com/script.js" data-website-id="9546a046-b901-471f-bfed-88c874786435"></script>
|
||||
25
archive/site/layouts/partials/meta/ai-disclosure.html
Normal file
25
archive/site/layouts/partials/meta/ai-disclosure.html
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{{- /*
|
||||
partials/meta/ai-disclosure.html — AI-generated content disclosure
|
||||
|
||||
Emits the proposed W3C/WHATWG AI content disclosure meta tag and the
|
||||
corresponding HTTP-equiv header that satisfies EU AI Act Article 50
|
||||
obligations for AI-generated/AI-assisted web content.
|
||||
|
||||
The disclosure level is controlled per-page via front matter:
|
||||
ai_content: "generated" — fully AI-generated content
|
||||
ai_content: "assisted" — human-written with AI assistance (default)
|
||||
ai_content: "reviewed" — AI-generated, human-reviewed and edited
|
||||
ai_content: "none" — no AI involvement (suppresses the tag)
|
||||
|
||||
Site-wide default in hugo.toml:
|
||||
[params]
|
||||
ai_content = "assisted" # default for all pages
|
||||
|
||||
Reference:
|
||||
https://github.com/nickvdyck/ai-content-disclosure
|
||||
EU AI Act Article 50 (transparency obligations, Chapter IV)
|
||||
*/ -}}
|
||||
{{- $level := or .Params.ai_content .Site.Params.ai_content "assisted" -}}
|
||||
{{- if ne $level "none" -}}
|
||||
<meta name="ai-content-disclosure" content="{{ $level }}">
|
||||
{{- end }}
|
||||
101
archive/site/layouts/partials/meta/json-ld.html
Normal file
101
archive/site/layouts/partials/meta/json-ld.html
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
{{- /*
|
||||
partials/meta/json-ld.html — JSON-LD structured data (Schema.org)
|
||||
|
||||
Emits one <script type="application/ld+json"> block per page.
|
||||
Uses dict → jsonify → safeHTML to avoid Hugo's JS-context escaping.
|
||||
|
||||
Schema selection:
|
||||
Home page → WebSite (with SearchAction if params.search_url set)
|
||||
Docs pages → TechArticle (front matter: type = "docs")
|
||||
Dated pages → Article
|
||||
Everything else → WebPage
|
||||
|
||||
BreadcrumbList appended when .Ancestors is non-empty.
|
||||
|
||||
Configure in hugo.toml:
|
||||
[params]
|
||||
author = "Trentuna" # publisher/author name
|
||||
logo = "/images/logo.png" # site logo for publisher
|
||||
search_url = "/search/?q={q}" # enables SearchAction on WebSite
|
||||
*/ -}}
|
||||
{{- $author := or .Site.Params.author .Site.Title -}}
|
||||
{{- $logo := .Site.Params.logo | default "" -}}
|
||||
{{- $desc := or .Description .Site.Params.description "" -}}
|
||||
{{- $image := or .Params.image .Site.Params.og_image "" -}}
|
||||
|
||||
{{- if .IsHome -}}
|
||||
|
||||
{{- /* ── WebSite ──────────────────────────────────────────────────── */}}
|
||||
{{- $data := dict
|
||||
"@context" "https://schema.org"
|
||||
"@type" "WebSite"
|
||||
"name" .Site.Title
|
||||
"url" .Site.BaseURL
|
||||
"description" $desc
|
||||
-}}
|
||||
{{- with .Site.Params.search_url -}}
|
||||
{{- $action := dict
|
||||
"@type" "SearchAction"
|
||||
"target" (dict "@type" "EntryPoint" "urlTemplate" (printf "%s%s" $.Site.BaseURL .))
|
||||
"query-input" "required name=q"
|
||||
-}}
|
||||
{{- $data = merge $data (dict "potentialAction" $action) -}}
|
||||
{{- end -}}
|
||||
{{- printf "<script type=\"application/ld+json\">%s</script>" ($data | jsonify) | safeHTML -}}
|
||||
|
||||
{{- else -}}
|
||||
|
||||
{{- /* ── Article / TechArticle / WebPage ─────────────────────────── */}}
|
||||
{{- $schemaType := "WebPage" -}}
|
||||
{{- if and .IsPage (not .IsSection) -}}
|
||||
{{- if eq .Params.type "docs" -}}
|
||||
{{- $schemaType = "TechArticle" -}}
|
||||
{{- else if .Date -}}
|
||||
{{- $schemaType = "Article" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $publisher := dict "@type" "Organization" "name" $author -}}
|
||||
{{- with $logo -}}
|
||||
{{- $publisher = merge $publisher (dict "logo" (dict "@type" "ImageObject" "url" (. | absURL))) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $data := dict
|
||||
"@context" "https://schema.org"
|
||||
"@type" $schemaType
|
||||
"headline" .Title
|
||||
"description" $desc
|
||||
"url" .Permalink
|
||||
"author" $publisher
|
||||
"publisher" $publisher
|
||||
-}}
|
||||
|
||||
{{- with $image -}}
|
||||
{{- $data = merge $data (dict "image" (. | absURL)) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if and .Date (not .IsSection) -}}
|
||||
{{- $data = merge $data (dict
|
||||
"datePublished" (.Date.Format "2006-01-02T15:04:05Z07:00")
|
||||
"dateModified" (.Lastmod.Format "2006-01-02T15:04:05Z07:00")
|
||||
) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* BreadcrumbList: .Ancestors is nearest→root; iterate by index to reverse */}}
|
||||
{{- with .Ancestors -}}
|
||||
{{- $ancs := . -}}
|
||||
{{- $len := len $ancs -}}
|
||||
{{- $items := slice -}}
|
||||
{{- range $i := seq $len -}}
|
||||
{{- $a := index $ancs (sub $len $i) -}}
|
||||
{{- $item := dict "@type" "ListItem" "position" $i "name" $a.Title "item" $a.Permalink -}}
|
||||
{{- $items = $items | append $item -}}
|
||||
{{- end -}}
|
||||
{{- $last := dict "@type" "ListItem" "position" (add $len 1) "name" $.Title "item" $.Permalink -}}
|
||||
{{- $items = $items | append $last -}}
|
||||
{{- $crumb := dict "@type" "BreadcrumbList" "itemListElement" $items -}}
|
||||
{{- $data = merge $data (dict "breadcrumb" $crumb) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- printf "<script type=\"application/ld+json\">%s</script>" ($data | jsonify) | safeHTML -}}
|
||||
{{- end }}
|
||||
41
archive/site/layouts/partials/meta/og.html
Normal file
41
archive/site/layouts/partials/meta/og.html
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{{- /*
|
||||
partials/meta/og.html — Open Graph + Twitter Card meta tags
|
||||
|
||||
og:title Page title (site title for home page)
|
||||
og:description .Description → .Site.Params.description → ""
|
||||
og:url .Permalink
|
||||
og:type "website" (home) | "article" (everything else)
|
||||
og:site_name .Site.Title
|
||||
og:image .Params.image → .Site.Params.og_image → absent
|
||||
twitter:card "summary_large_image" when image present, else "summary"
|
||||
twitter:site .Site.Params.twitter (optional @handle)
|
||||
|
||||
Configure in hugo.toml:
|
||||
[params]
|
||||
og_image = "/images/og-default.png" # fallback OG image
|
||||
twitter = "@yourhandle" # omit if not on Twitter/X
|
||||
*/ -}}
|
||||
{{- $title := cond .IsHome .Site.Title (printf "%s · %s" .Title .Site.Title) -}}
|
||||
{{- $desc := or .Description .Site.Params.description "" -}}
|
||||
{{- $image := or .Params.image .Site.Params.og_image "" -}}
|
||||
{{- $type := cond .IsHome "website" "article" -}}
|
||||
|
||||
<meta property="og:title" content="{{ $title }}">
|
||||
<meta property="og:description" content="{{ $desc }}">
|
||||
<meta property="og:url" content="{{ .Permalink }}">
|
||||
<meta property="og:type" content="{{ $type }}">
|
||||
<meta property="og:site_name" content="{{ .Site.Title }}">
|
||||
{{- with $image }}
|
||||
<meta property="og:image" content="{{ . | absURL }}">
|
||||
{{- end }}
|
||||
|
||||
{{- /* Twitter / X Card */}}
|
||||
<meta name="twitter:card" content="{{ if $image }}summary_large_image{{ else }}summary{{ end }}">
|
||||
<meta name="twitter:title" content="{{ $title }}">
|
||||
<meta name="twitter:description" content="{{ $desc }}">
|
||||
{{- with $image }}
|
||||
<meta name="twitter:image" content="{{ . | absURL }}">
|
||||
{{- end }}
|
||||
{{- with .Site.Params.twitter }}
|
||||
<meta name="twitter:site" content="{{ . }}">
|
||||
{{- end }}
|
||||
16
archive/site/layouts/partials/meta/seo.html
Normal file
16
archive/site/layouts/partials/meta/seo.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{{- /*
|
||||
partials/meta/seo.html — canonical URL + robots directives
|
||||
|
||||
Outputs:
|
||||
<link rel="canonical"> Always emitted; uses .Permalink (absolute).
|
||||
<meta name="robots"> "noindex, nofollow" on draft/future pages,
|
||||
"index, follow" otherwise.
|
||||
|
||||
No params required. Works from any page context.
|
||||
*/ -}}
|
||||
<link rel="canonical" href="{{ .Permalink }}">
|
||||
{{- if or .Draft (gt .Date now) }}
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
{{- else }}
|
||||
<meta name="robots" content="index, follow">
|
||||
{{- end }}
|
||||
29
archive/site/layouts/partials/nav.html
Normal file
29
archive/site/layouts/partials/nav.html
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<nav>
|
||||
<ul><li><a href="/"><strong>{{ .Site.Title }}</strong></a></li></ul>
|
||||
<ul data-nav-links>
|
||||
{{- range sort .Site.Data.nav.items "weight" }}
|
||||
<li><a href="{{ .url }}"{{ if eq (relURL .url) $.RelPermalink }} aria-current="page"{{ end }}>{{ .name }}</a></li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
<button data-nav-toggle aria-label="Menu" hidden></button>
|
||||
<button data-theme-toggle aria-label="Toggle theme"></button>
|
||||
</nav>
|
||||
<script>
|
||||
// Hamburger — toggle nav links on mobile
|
||||
(function(){
|
||||
var btn = document.querySelector('[data-nav-toggle]');
|
||||
var links = document.querySelector('[data-nav-links]');
|
||||
if (!btn || !links) return;
|
||||
// Show button only when JS is available
|
||||
if (matchMedia('(max-width:767.98px)').matches) btn.hidden = false;
|
||||
matchMedia('(max-width:767.98px)').addEventListener('change', function(e) {
|
||||
btn.hidden = !e.matches;
|
||||
if (!e.matches) links.removeAttribute('data-collapsed');
|
||||
});
|
||||
btn.addEventListener('click', function() {
|
||||
var open = links.hasAttribute('data-collapsed');
|
||||
if (open) links.removeAttribute('data-collapsed');
|
||||
else links.setAttribute('data-collapsed', '');
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
21
archive/site/layouts/partials/tag-nav.html
Normal file
21
archive/site/layouts/partials/tag-nav.html
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{{- /*
|
||||
tag-nav.html — renders all site tags as a navigable tag cloud.
|
||||
|
||||
Usage in a layout:
|
||||
{{ partial "tag-nav.html" . }}
|
||||
|
||||
Outputs: <nav data-role="tag-cloud"> with links to each tag page.
|
||||
The (N) count shows how many pages have each tag.
|
||||
*/ -}}
|
||||
{{- $tags := .Site.Taxonomies.tags -}}
|
||||
{{- if $tags }}
|
||||
<nav data-role="tag-cloud" aria-label="Browse by tag">
|
||||
{{- range $name, $pages := $tags }}
|
||||
{{- $tagPage := site.GetPage (printf "/tags/%s" ($name | urlize)) }}
|
||||
<a href="{{ if $tagPage }}{{ $tagPage.Permalink }}{{ else }}{{ print site.BaseURL "tags/" ($name | urlize) "/" }}{{ end }}" data-tag="{{ $name }}">
|
||||
{{ $name -}}
|
||||
<small>({{ len $pages }})</small>
|
||||
</a>
|
||||
{{- end }}
|
||||
</nav>
|
||||
{{- end }}
|
||||
16
archive/site/layouts/shortcodes/callout.html
Normal file
16
archive/site/layouts/shortcodes/callout.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{{- /*
|
||||
callout shortcode — wraps content in an ASW callout block.
|
||||
|
||||
Usage:
|
||||
{{< callout note >}}
|
||||
Content here. Markdown is rendered.
|
||||
{{< /callout >}}
|
||||
|
||||
First positional param: callout type.
|
||||
Valid types: note, warning, tip, info (maps to ASW data-callout attribute).
|
||||
Default: note
|
||||
*/ -}}
|
||||
{{- $type := .Get 0 | default "note" -}}
|
||||
<aside data-callout="{{ $type }}">
|
||||
{{ .Inner | markdownify }}
|
||||
</aside>
|
||||
20
archive/site/layouts/shortcodes/wikilink.html
Normal file
20
archive/site/layouts/shortcodes/wikilink.html
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{{- /*
|
||||
wikilink shortcode — renders an internal link with ASW data-wikilink attribute.
|
||||
|
||||
Usage:
|
||||
{{< wikilink "Display Text" "/path/to/page/" >}}
|
||||
|
||||
Param 0 (required): display text
|
||||
Param 1 (optional): href path. Defaults to /display-text-slugified/
|
||||
|
||||
Examples:
|
||||
{{< wikilink "My Note" >}}
|
||||
→ <a href="/my-note/" data-wikilink>My Note</a>
|
||||
|
||||
{{< wikilink "My Note" "/vault/my-note/" >}}
|
||||
→ <a href="/vault/my-note/" data-wikilink>My Note</a>
|
||||
*/ -}}
|
||||
{{- $text := .Get 0 -}}
|
||||
{{- $slug := $text | lower | replace " " "-" -}}
|
||||
{{- $href := .Get 1 | default (printf "/%s/" $slug) -}}
|
||||
<a href="{{ $href | relURL }}" data-wikilink>{{ $text }}</a>
|
||||
Loading…
Add table
Add a link
Reference in a new issue