Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sites/ainsley-clark/archetypes/conference-bundle/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ event:
# - text: View attendee sites
# url: https://showcase.ainsleyclark.com/{{ .Name }}/
# title: See what attendees built in the workshop
# colour: black # Optional, defaults to white.
slides:
path: files/slides.pdf
name: {{ .Name }}-ainsley-clark.pdf
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "//go:embed: From Comment to Binary"
description: How //go:embed turns a comment into bytes in your binary, from the lexer to the linker, plus the tradeoffs and patterns for using it in production.
heading: GopherCon Africa 2026
heading: GopherCon Africa 2026 - Talk
talkTitle: "//go:embed: From Comment to Binary - Linker Internals, Tradeoffs and Production Patterns"
lead: This talk follows a single //go:embed directive through go build, the compiler and the linker, then looks at what embedding costs you and how to test it.
weight: 1
Expand All @@ -18,15 +18,10 @@ event:
date: 2026-10-17
# location: Venue, City
url: https://gophercon.africa/
links:
- text: View workshop
url: /conferences/gophercon-africa-2026-workshop/
title: View the full-stack Go workshop with sqlc and templ
# Uncomment once files/slides.pdf has been added.
# slides:
# path: files/slides.pdf
# name: gophercon-africa-2026-ainsley-clark.pdf
# text: Download slides
slides:
path: files/slides.pdf
name: go-embed-from-comment-to-binary-ainsley-clark.pdf
text: Download slides
sources:
- title: 1. Mastering Embed in Go 1.16
url: https://lakefs.io/blog/working-with-embed-in-go/
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Full-Stack Go Workshop at GopherCon Africa 2026
description: A full-day workshop at GopherCon Africa 2026 in Nairobi on building domain-driven, full-stack Go apps with sqlc and templ, and the sites attendees shipped.
heading: GopherCon Africa 2026 Workshop
heading: GopherCon Africa 2026 - Workshop
talkTitle: "Full-Stack Go: Domain-Driven Applications with sqlc and templ"
lead: A full-day, intermediate workshop building a complete Go application, from data ingestion through a type-safe sqlc data layer to a server-rendered templ UI, finishing with a theming block where every attendee shipped their own site.
weight: 1
Expand All @@ -19,14 +19,11 @@ event:
date: 2026-10-15
location: Nairobi, Kenya
url: https://gophercon.africa/
slides:
path: files/slides.pdf
name: full-stack-go-sqlc-templ-workshop-ainsley-clark.pdf
text: Download slides
links:
- text: View attendee sites
url: https://showcase.ainsleyclark.com/gophercon-africa-2026/
title: See every website built in the workshop
colour: black
sources:
- title: 1. sqlc
url: https://sqlc.dev/
Expand Down Expand Up @@ -58,19 +55,6 @@ Build a complete full-stack application in Go, from data ingestion through persi

We started from a working application built on a real public API: an animal-sightings site fed by GBIF records, stored in SQLite and enriched with Open-Meteo weather. From there we walked through five different architectures for the same feature (flat, layered, onion, hexagonal and feature-based) to see what domain-driven design actually buys you, then looked at how the app is built: a type-safe data layer with sqlc and a front-end written with templ. The build is a guided walkthrough of real, finished code, so the time goes on the decisions rather than the typing.

## Agenda

| Block | Minutes |
| --- | --- |
| Welcome and setup | 10 |
| App intro | 20 |
| Architecture and DDD practices | 50 |
| Querying with sqlc | 40 |
| Intro to templ | 40 |
| Profiling | 20 |
| Theming | 80 |
| Wrapping up | 10 |

## What attendees built

The hands-on part came last. Every attendee forked the workshop repository, profiled it under load with pprof and themed their own copy of the site using the `/design-site` skill in Claude Code or JetBrains Air, with two competitions running alongside: Best Website and Best Social Post. Thirty-three themed sites made it into the [showcase](https://showcase.ainsleyclark.com/gophercon-africa-2026/), each served exactly as its author shipped it.
38 changes: 8 additions & 30 deletions sites/ainsley-clark/layouts/conferences/single.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,14 @@
===================== -->
<header class="insight-intro">
<!-- Crumbs -->
<!-- Hand rolled as the media archive is not an ancestor of the conferences section. -->
<!-- The conferences section doesn't render, so the media archive is the parent. -->
<div class="insight-intro-crumbs">
<nav class="breadcrumbs mb-0" aria-label="breadcrumb">
<ul class="breadcrumbs-list"
itemscope itemtype="https://schema.org/BreadcrumbList">
<!-- Home -->
<li class="breadcrumbs-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a class="breadcrumbs-link" href="/" itemprop="item">
<span itemprop="name">Home</span>
<meta itemprop="position" content="1" />
</a>
</li>
<!-- Media -->
<li class="breadcrumbs-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a class="breadcrumbs-link" href="/media/" itemprop="item">
<span itemprop="name">Media</span>
<meta itemprop="position" content="2" />
</a>
</li>
<!-- Current -->
<li class="breadcrumbs-item breadcrumbs-active"
itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"
aria-current="page">
<a class="breadcrumbs-link" href="{{ .RelPermalink }}" itemprop="item">
<span itemprop="name">{{ .Params.heading }}</span>
<meta itemprop="position" content="3" />
</a>
</li>
</ul>
</nav>
{{ partial "components/breadcrumbs.html" (dict
"ctx" .
"margin" false
"parent" (site.GetPage "/media")
"title" .Params.heading
)}}
</div>
<!-- Tags -->
{{ with .Params.tags }}
Expand Down Expand Up @@ -147,7 +125,7 @@ <h1 class="heading-1 heading-1-small margin">
{{ partial "components/button.html" (dict
"text" .text
"link" .url
"colour" "white"
"colour" (.colour | default "white")
"size" "small"
"arrow" true
"title" (.title | default .text)
Expand Down
13 changes: 11 additions & 2 deletions themes/shared/layouts/partials/components/breadcrumbs.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
partial "components/breadcrumbs.html" (dict
"ctx" .
"margin" false
"parent" (site.GetPage "/media")
"title" .Params.heading
)
- ctx: The current Hugo context
- margin: If margin should be outputted.
- parent: Optional page to use as the parent instead of the ctx's ancestors,
for sections that don't render, such as conferences under /media/.
- title: Optional title for the current page, defaults to breadcrumbs or Title.
===================== -->
<nav class="breadcrumbs {{ if and (isset . "margin") (not .margin) -}} mb-0 {{- end }}"
aria-label="breadcrumb">
Expand Down Expand Up @@ -43,8 +48,12 @@
{{- end }}

{{ $index := 2 }} <!-- Start index at 2 since Home is 1 -->
{{ $ancestors := .ctx.Ancestors.Reverse }}
{{ with .parent }}
{{ $ancestors = .Ancestors.Reverse | append . }}
{{ end }}
<!-- Ancestor Breadcrumbs -->
{{ range .ctx.Ancestors.Reverse }}
{{ range $ancestors }}
{{ if not (eq .RelPermalink "/") }}
{{ partial "breadcrumbs-item.html" (dict
"title" (partial "breadcrumbs-title.html" .)
Expand All @@ -57,7 +66,7 @@
{{ end }}
<!-- Current Page Breadcrumb -->
{{ partial "breadcrumbs-item.html" (dict
"title" (partial "breadcrumbs-title.html" .ctx)
"title" (.title | default (partial "breadcrumbs-title.html" .ctx))
"link" .ctx.RelPermalink
"index" $index
"current" true
Expand Down
6 changes: 6 additions & 0 deletions vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@
"permanent": true,
"has": [{"type": "host", "value": "ainsleyclark\\.com"}]
},
{
"source": "/conferences/gophercon-africa-2026/",
"destination": "/conferences/gophercon-africa-2026-talk/",
"permanent": true,
"has": [{"type": "host", "value": "ainsleyclark\\.com"}]
},
{
"source": "/workshop-gophercon-africa-2026/",
"destination": "/gophercon-africa-2026/",
Expand Down
Loading