Here is how one could do a blogroll in Hugo:
We need a template dedicated to this particular blogroll page in layouts/blogroll.html
{{- define "main" }}
<h1>{{ .Title }}</h1>
{{ .Content -}}
{{- with hugo.Data.blogroll }}
<ul>
{{- range sort . "blog" -}}
<li>
<a href="{{ .url }}" rel="external" class="wt-500">{{ .blog }}</a>
{{ with .rss }}
<a href="{{ . }}" class="fgshade3">[RSS]</a>
{{ end }}
{{ with .atom }}
<a href="{{ . }}" class="fgshade3">[Atom]</a>
{{- end -}}
</li>
{{- end }}
</ul>
{{- end }}
{{- end }}
And then set the layout in the corresponding page frontmatter:
+++
title = "Blogroll"
description = "The awesome blogs I read"
date = "2025-04-04T00:00:00-03:00"
layout = "blogroll"
+++
Blogs I follow that one may want to visit.
And finally place the data file in data/blogroll.json:
[
{
"blog": "Example One",
"url": "https://example1.com/",
"rss": "https://example1.com/index.xml"
},
{
"blog": "Example Two",
"url": "https://example2.com/",
"rss": "https://example2.com/index.xml",
"atom": "https://example2.com/atom.xml"
},
{
"blog": "Example Three",
"url": "https://example3.com/",
"rss": "https://example3.com/index.xml"
}
]
To make a blogroll template in Zine we define a template for the specific page in layouts/blogroll.shtml:
<extend template="footer.shtml">
<head id="head"></head>
<header id="header"></header>
<main id="main">
<h1 :text="$page.title"></h1>
<ctx :html="$page.content()"></ctx>
<ul :loop="$page.asset('blogroll.json').ziggy()">
<li>
<a
class="wt-500"
href="$loop.it.get('url')"
:text="$loop.it.get('blog')">
</a>
<ctx :if="$loop.it.has('rss')">
<a class="fgshade3" href="$loop.it.get('rss')">[rss]</a>
</ctx>
<ctx :if="$loop.it.has('atom')">
<a class="fgshade3" href="$loop.it.get('atom')">[atom]</a>
</ctx>
</li>
</ul>
</main>
<footer id="footer"></footer>
This template chains through other common repeated elements footer -> header -> head(More on that on another post). Unfortunately I still haven't figured out how to sort the list.
And then set the layout in the corresponding's page (content/blogroll/index.smd frontmatter:
***
.title = "Blogroll",
.date = @date("2026-06-10T22:11:54-04:00"),
.author = "Alec Sargent",
.layout = "blogroll.shtml",
.tags = ["web", "blogroll"],
***
These are blog I actually read and I'm subscribed to.
We use the same data file from the previous Hugo example and place it in content/blogroll/blogroll.json
Optionally one could use $site.asset in favour of $page.asset and place the file in the assets directory.
Other formats like YAML and TOML may be used in Hugo as long as they have the same structure.
That is all, cheers.

