Add GoatCounter analytics, Miniflux, and update CLAUDE.md
- Add self-hosted GoatCounter via systemd binary service (stats.monotrope.au) - Add Miniflux RSS reader via Docker Compose (reader.monotrope.au) - Extend Ansible playbook with goatcounter and miniflux tags; all provisioning is idempotent - Add Caddy reverse proxy blocks for both new services - Inject GoatCounter script in baseof.html (production builds only) - Add goatcounter and miniflux Makefile targets - Rewrite CLAUDE.md to reflect actual project state Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,10 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ if not .IsHome }}{{ .Title }} · {{ end }}{{ .Site.Title }}</title>
|
||||
<meta name="description" content="{{ with .Description }}{{ . }}{{ else }}{{ .Site.Params.description }}{{ end }}">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,300;0,400;0,500;1,400&family=Spectral:ital,wght@0,400;0,600;1,400&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
{{ printf `
|
||||
<link rel="%s" type="%s" href="%s" title="%s">` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
|
||||
{{ printf `<link rel="%s" type="%s" href="%s" title="%s">` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }}
|
||||
{{ end -}}
|
||||
{{ if hugo.IsProduction }}
|
||||
<script data-goatcounter="https://stats.monotrope.au/count" async src="https://stats.monotrope.au/count.js"></script>
|
||||
{{ end -}}
|
||||
</head>
|
||||
|
||||
@@ -18,7 +23,9 @@
|
||||
<header class="site-header">
|
||||
<a class="site-title" href="/">{{ .Site.Title }}</a>
|
||||
<nav class="site-nav">
|
||||
<a href="/posts/">Writing</a>
|
||||
<a href="/about/"{{ if hasPrefix .RelPermalink "/about" }} class="active"{{ end }}>about</a>
|
||||
<a href="/posts/"{{ if hasPrefix .RelPermalink "/posts" }} class="active"{{ end }}>writing</a>
|
||||
<a href="/reviews/"{{ if hasPrefix .RelPermalink "/reviews" }} class="active"{{ end }}>reading</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
@@ -27,9 +34,10 @@
|
||||
</main>
|
||||
|
||||
<footer class="site-footer">
|
||||
<p>© {{ now.Year }} Monotrope. Built with <a href="https://gohugo.io">Hugo</a>.</p>
|
||||
<span>monotrope.au</span>
|
||||
<span>© {{ now.Year }}</span>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
{{ define "main" }}
|
||||
<h2 class="page-heading">{{ .Title }}</h2>
|
||||
<p class="section-label">{{ .Title | lower }}</p>
|
||||
<ul class="post-list">
|
||||
{{ range .Pages.ByDate.Reverse }}
|
||||
<li>
|
||||
<time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "2006-01-02" }}</time>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
<div class="post-entry">
|
||||
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||
{{ with .Params.tags }}
|
||||
<div class="tags">
|
||||
{{ range . }}<a class="tag" href="/tags/{{ . | urlize }}/">{{ . }}</a>{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
39
site/layouts/_default/rss.xml
Normal file
39
site/layouts/_default/rss.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
{{- $pctx := . -}}
|
||||
{{- if .IsHome -}}{{ $pctx = .Site }}{{- end -}}
|
||||
{{- $pages := slice -}}
|
||||
{{- if or $.IsHome $.IsSection -}}
|
||||
{{- $pages = $pctx.RegularPages -}}
|
||||
{{- else -}}
|
||||
{{- $pages = $pctx.Pages -}}
|
||||
{{- end -}}
|
||||
{{- $pages = where $pages "Type" "ne" "page" -}}
|
||||
{{- $limit := .Site.Config.Services.RSS.Limit -}}
|
||||
{{- if ge $limit 1 -}}
|
||||
{{- $pages = $pages | first $limit -}}
|
||||
{{- end -}}
|
||||
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{ . }} on {{ end }}{{ .Site.Title }}{{ end }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<description>Recent content {{ if ne .Title .Site.Title }}in {{ .Title }} {{ end }}on {{ .Site.Title }}</description>
|
||||
<generator>Hugo</generator>
|
||||
<language>{{ site.Language.LanguageCode }}</language>
|
||||
{{ with .Site.Copyright }}<copyright>{{ . }}</copyright>{{ end }}
|
||||
{{- if not .Date.IsZero -}}
|
||||
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>
|
||||
{{- end -}}
|
||||
{{- with .OutputFormats.Get "RSS" -}}
|
||||
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
|
||||
{{- end -}}
|
||||
{{ range $pages }}
|
||||
<item>
|
||||
<title>{{ .Title }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
|
||||
<guid>{{ .Permalink }}</guid>
|
||||
<description>{{ with .Description }}{{ . | html }}{{ else }}{{ .Summary | html }}{{ end }}</description>
|
||||
</item>
|
||||
{{ end }}
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,9 +1,17 @@
|
||||
{{ define "main" }}
|
||||
<article>
|
||||
<h1>{{ .Title }}</h1>
|
||||
<p class="post-meta">
|
||||
<div class="post-meta">
|
||||
<time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "2 January 2006" }}</time>
|
||||
</p>
|
||||
{{ with .ReadingTime }}<span>{{ . }} min read</span>{{ end }}
|
||||
</div>
|
||||
{{ .Content }}
|
||||
{{ with .Params.tags }}
|
||||
<div class="post-footer">
|
||||
<div class="tags">
|
||||
{{ range . }}<a class="tag" href="/tags/{{ . | urlize }}/">{{ . }}</a>{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</article>
|
||||
{{ end }}
|
||||
|
||||
@@ -1,10 +1,56 @@
|
||||
{{ define "main" }}
|
||||
<ul class="post-list">
|
||||
{{ range (where .Site.RegularPages "Type" "posts").ByDate.Reverse }}
|
||||
<li>
|
||||
<time datetime="{{ .Date.Format "2006-01-02" }}">{{ .Date.Format "2006-01-02" }}</time>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
<div class="home-prompt">
|
||||
<span class="prompt-line">whoami</span>
|
||||
<span class="prompt-response">{{ .Site.Params.description | default "writing on technology, books, and ideas."
|
||||
}}</span>
|
||||
<span class="prompt-line"><span class="cursor"></span></span>
|
||||
</div>
|
||||
|
||||
<div class="home-sections">
|
||||
|
||||
<section>
|
||||
<div class="home-section-head">
|
||||
<h2>writing</h2>
|
||||
<a class="see-all" href="/posts/">all posts</a>
|
||||
</div>
|
||||
<ul class="post-list">
|
||||
{{ range first 5 (where .Site.RegularPages "Section" "posts").ByDate.Reverse }}
|
||||
<li>
|
||||
<time datetime="{{ .Date.Format " 2006-01-02" }}">{{ .Date.Format "2006-01-02" }}</time>
|
||||
<div class="post-entry">
|
||||
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||
{{ with .Params.tags }}
|
||||
<div class="tags">
|
||||
{{ range . }}<a class="tag" href="/tags/{{ . | urlize }}/">{{ . }}</a>{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="home-section-head">
|
||||
<h2>reading</h2>
|
||||
<a class="see-all" href="/reviews/">all reviews</a>
|
||||
</div>
|
||||
<ul class="review-list">
|
||||
{{ range first 3 (where .Site.RegularPages "Section" "reviews").ByDate.Reverse }}
|
||||
{{ $rating := .Params.rating | default 0 }}
|
||||
<li>
|
||||
<span class="review-date">{{ .Params.date_read | default (.Date.Format "2006-01") }}</span>
|
||||
<div class="review-entry">
|
||||
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||
{{ with .Params.book_author }}<span class="review-author">{{ . }}</span>{{ end }}
|
||||
<span class="review-rating">
|
||||
{{- strings.Repeat $rating "▓" -}}{{- strings.Repeat (sub 5 $rating) "░" -}}
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
{{ end }}
|
||||
6
site/layouts/page/single.html
Normal file
6
site/layouts/page/single.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{{ define "main" }}
|
||||
<article>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{ .Content }}
|
||||
</article>
|
||||
{{ end }}
|
||||
24
site/layouts/reviews/list.html
Normal file
24
site/layouts/reviews/list.html
Normal file
@@ -0,0 +1,24 @@
|
||||
{{ define "main" }}
|
||||
<p class="section-label">reading</p>
|
||||
<ul class="review-list">
|
||||
{{ range .Pages.ByDate.Reverse }}
|
||||
{{ $rating := .Params.rating | default 0 }}
|
||||
<li>
|
||||
<span class="review-date">{{ .Params.date_read | default (.Date.Format "2006-01") }}</span>
|
||||
<div class="review-entry">
|
||||
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
|
||||
{{ with .Params.book_author }}<span class="review-author">{{ . }}</span>{{ end }}
|
||||
<span class="review-rating">
|
||||
{{- strings.Repeat $rating "▓" -}}{{- strings.Repeat (sub 5 $rating) "░" -}}
|
||||
<span style="color: var(--muted); font-size: 0.8em; margin-left: 0.4rem;">{{ $rating }}/5</span>
|
||||
</span>
|
||||
{{ with .Params.tags }}
|
||||
<div class="tags">
|
||||
{{ range . }}<a class="tag" href="/tags/{{ . | urlize }}/">{{ . }}</a>{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
32
site/layouts/reviews/single.html
Normal file
32
site/layouts/reviews/single.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{{ define "main" }}
|
||||
{{ $rating := .Params.rating | default 0 }}
|
||||
<article>
|
||||
<h1>{{ .Title }}</h1>
|
||||
|
||||
<div class="book-meta">
|
||||
{{ with .Params.book_author }}
|
||||
<span class="meta-key">author</span>
|
||||
<span class="meta-val author">{{ . }}</span>
|
||||
{{ end }}
|
||||
|
||||
<span class="meta-key">read</span>
|
||||
<span class="meta-val">{{ .Params.date_read | default (.Date.Format "January 2006") }}</span>
|
||||
|
||||
<span class="meta-key">rating</span>
|
||||
<span class="meta-val">
|
||||
<span class="rating-blocks">{{- strings.Repeat $rating "▓" -}}{{- strings.Repeat (sub 5 $rating) "░" -}}</span>
|
||||
<span class="rating-num">{{ $rating }}/5</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{{ .Content }}
|
||||
|
||||
{{ with .Params.tags }}
|
||||
<div class="post-footer">
|
||||
<div class="tags">
|
||||
{{ range . }}<a class="tag" href="/tags/{{ . | urlize }}/">{{ . }}</a>{{ end }}
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
</article>
|
||||
{{ end }}
|
||||
Reference in New Issue
Block a user