Grosse refonte de ma page “Conférences” qui était un bazar sans nom, dans lequel j’avais aussi mélangé les podcasts, les publications écrites, etc. Maintenant tout est présenté avec des “cartes”, et bien séparé en 3 pages distinctes.
Tous les fichiers sources (YAML, layouts Hugo, CSS) sont disponibles dans /2026/03/conferences-refonte/ si vous voulez reproduire ou vous en inspirer.
Le problème
Ma page Conférences était un gros fichier Markdown monolithique. Talks, podcasts, publications, orga : tout mélangé dans des listes à puces, avec des doublons, et de plus en plus pénible à maintenir (surtout depuis le passage en multi-langue FR/EN).

L’approche : données + layouts + CSS
Plutôt que de continuer à maintenir du Markdown, je suis passé en data-driven, comme je l’ai fait pour mon side project “101 ways to deploy Kubernetes” :
- Données dans des fichiers YAML (
data/) - Présentation dans des layouts Hugo custom (
layouts/page/) - Style dans des CSS dédiés (
static/css/) - Pages Markdown réduites au strict minimum (front matter uniquement)
Et au passage, j’ai découpé une page fourre-tout en trois : Conférences, Podcasts & Lives, Publications.
Les données YAML
data/conferences.yaml
Le plus gros fichier. L’idée clé : un talk (sujet unique) peut être présenté à plusieurs events. Fini la duplication.
talks:
- id: k8s-scheduling
title:
fr: "Limits, Requests, QoS, PriorityClasses, ..."
en: "Limits, Requests, QoS, PriorityClasses: ..."
cospeaker: "Quentin Joly"
slides: "/talks/2025-lrqppobcqvpsslsdk/..."
events:
- talk: k8s-scheduling # référence l'id du talk
event: "DevoxxFR 2026"
date: 2026-03-22
type: conference
- talk: k8s-scheduling
event: "TNT 26"
date: 2026-02-12
type: conference
video: "https://www.youtube.com/watch?v=..."
organizer:
- description:
fr: "Membre de l'équipe d'organisation du Meetup CNCF Bordeaux"
current: true
Les titres sont bilingues (FR/EN), Hugo sélectionne la bonne langue automatiquement. Les fichiers data/podcasts.yaml et data/publications.yaml suivent le même principe (voir les fichiers sources).
Les pages Markdown minimalistes
L’ancienne page content/page/conferences.md faisait 100+ lignes avec le contenu complet. Voici la nouvelle :
---
title: 'Conférences'
authors:
- zwindler
type: page
layout: conferences
date: 2022-03-14T18:00:00+00:00
menu:
main:
weight: -40
params:
icon: messages
toc: false
---
Le point important, c’est layout: conferences dit à Hugo d’utiliser layouts/page/conferences.html au lieu du layout par défaut. Même chose pour podcasts et publications.
Le layout Hugo (l’essentiel)
Le layout charge les données YAML, calcule des stats, et génère du HTML. Si vous avez déjà manipulé du GoTemplate (helm notamment), ça vous semblera facile à comprendre.
Chargement et indexation des talks :
{{- $data := .Site.Data.conferences -}}
{{- $talks := dict -}}
{{- range $data.talks -}}
{{- $talks = merge $talks (dict .id .) -}}
{{- end -}}
Compteur dynamique - combien de fois un talk a été présenté :
{{- $count := 0 -}}
{{- $talkId := .id -}}
{{- range $data.events -}}
{{- if eq .talk $talkId -}}
{{- $count = add $count 1 -}}
{{- end -}}
{{- end -}}
<p class="talk-card-count">Présenté {{ $count }}x</p>
Événements groupés par année, les 2 plus récentes dépliées, le reste en archive pliable via <details> :
{{- range $i, $year := $sortedYears -}}
{{- if lt $i 2 -}}
<details class="year-group" open>
{{- else -}}
<details class="year-group">
{{- end -}}
Les événements à venir (date dans le futur) reçoivent automatiquement un badge “à venir”. Les layouts complets sont dans les fichiers sources.
Le CSS : des cartes partout
Le design repose sur des cartes CSS grid, avec des badges colorés par type (conf, meetup, BBL), du responsive, et un support dark mode. L’essentiel :
.talks-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 1.2rem;
}
.talk-card {
background: var(--card-background);
border-radius: 10px;
padding: 1.2rem;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.type-conference { background: #dbeafe; color: #1e40af; }
.type-meetup { background: #dcfce7; color: #166534; }
.type-bbl { background: #fef9c3; color: #854d0e; }
.type-upcoming { background: #fee2e2; color: #991b1b; }
Les CSS complets (585 + 266 + 274 lignes) gèrent aussi le dark mode et les breakpoints mobile. Ils sont dans les fichiers sources.
Bilan
| Aspect | Avant | Après |
|---|---|---|
| Pages | 1 fourre-tout | 3 spécialisées |
| Données | Markdown libre | YAML structuré |
| Duplication | Oui | Non (relation talk → events) |
| Stats | Aucune | Automatiques |
| Design | Listes à puces | Cartes + badges |
| Multi-langue | Copier-coller | Titres FR/EN dans le YAML |
| Archives | Tout d’un bloc | Années pliables |
Le commit fait 19 fichiers et ~2400 lignes (une grosse partie du taf, en particulier la traduction markdown => YAML, a été faite par un LLM), mais la logique est simple : données dans YAML, présentation dans les layouts, style dans le CSS. Hugo fait le lien au build, sans JavaScript.
Pour ajouter un nouveau talk maintenant, il me suffit d’ajouter une entrée dans data/conferences.yaml et les stats se mettent à jour toutes seules. C’est quand même plus propre qu’un copier-coller dans plusieurs fichiers Markdown :).
