VT-100 Hybrid Redesign Implementation Plan
VT-100 Hybrid Redesign Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Replace the current mixed aesthetic with a cohesive VT-100 hybrid terminal theme — amber monospace chrome (header, sidebar, nav) with readable Monda sans-serif article bodies.
Architecture: Split-pane layout (sidebar 20% / content 80%), flat #0A0A0A background, amber/white dual phosphor color system, Unicode box-drawing article cards, filesystem-metaphor navigation (/dev/java, /dev/retro, /dev/blanka). All existing URLs preserved unchanged for SEO.
Tech Stack: Jekyll, SCSS, Liquid templates, TypewriterJS (existing), Docker for local build/serve
Spec: docs/superpowers/specs/2026-04-18-vt100-redesign-design.md
Verify commands:
# Local serve
docker run --rm -p 4000:4000 -v $(pwd):/srv/jekyll \
jekyll/builder:latest jekyll serve --future --livereload
# Build only
docker run -v $(pwd):/srv/jekyll -v $(pwd)/_site:/srv/jekyll/_site \
jekyll/builder:latest /bin/bash -c "chmod 777 /srv/jekyll && jekyll build --future"
File Map
Create
| File | Responsibility |
|—|—|
| _sass/_header.scss | Header strip, scanlines, site-name, language toggle |
| _sass/_sidebar.scss | Sidebar layout, nav, search, tags, recent posts |
| _sass/_cards.scss | Article card Unicode box component |
| _sass/_article.scss | Article page breadcrumb, heading ::before, blockquote, TOC |
| _sass/_footer.scss | Footer bar, text social links |
Rewrite (full)
| File | Change |
|—|—|
| _sass/_variables.scss | New color tokens, keep font vars |
| _sass/_base-rules.scss | #0A0A0A bg, cyan links, remove bg-image |
| _sass/_nav.scss | Directory-style sidebar nav |
| _sass/_post.scss | ##/### ::before, amber h2, new blockquote |
| _sass/_fx.scss | Remove glitch/chrome/street, keep .preformatted |
Modify (partial)
| File | Change |
|—|—|
| style.scss | New imports, move inline layout to partials |
| _layouts/default.html | Remove CDN deps, new header/sidebar/footer HTML |
| _layouts/post.html | Breadcrumb, new header structure |
| _includes/full-index-page.html | Split-pane layout with sidebar + cards |
| _includes/post-aside.html | § TOC prefix, [gh][li][tw] share links |
| _includes/search.html | Terminal prompt $ grep -r "" style |
| _config.yml | Nav labels → /dev/* display text |
Delete
| File | Reason |
|—|—|
| _sass/_article-list-post-footer.scss | Replaced by _cards.scss |
Task 1: CSS Variables + Base Rules
Files:
- Rewrite:
_sass/_variables.scss - Rewrite:
_sass/_base-rules.scss
Expected state before starting
Body has photo background (3132.jpg), links are #4183C4 blue, background is white/image.
- Step 1: Rewrite
_sass/_variables.scss
// Colors
$amber: #FFB000;
$amber-dim: #996600;
$body-text: #E0E0E0;
$code-green: #33FF33;
$link: #5BC8FF;
$link-visited: #FFB000;
$border: #333333;
$bg-card: #111111;
$bg-body: #0A0A0A;
// Legacy aliases (used by other partials not yet rewritten)
$blue: #5BC8FF;
$black: #000;
$darkerGray: $amber;
$darkGray: $body-text;
$gray: $amber-dim;
$lightGray: #222222;
$white: $body-text;
// Font stacks
$mono: "Share Tech Mono", "coders-crux", monospace;
$helvetica: "Monda", Helvetica, Arial, sans-serif;
$helveticaNeue: "Monda", "Helvetica Neue", Helvetica, Arial, sans-serif;
$georgia: Georgia, serif;
$codeFont: "coders-crux", "Share Tech Mono", monospace;
$articleFont: "Monda", Helvetica, Arial, sans-serif;
// Mobile breakpoints
@mixin mobile {
@media screen and (max-width: 800px) {
@content;
}
}
- Step 2: Rewrite
_sass/_base-rules.scss
html { font-size: 100%; }
body {
background: $bg-body;
font: 1em $helvetica;
color: $body-text;
cursor: url("/images/atari-st-mouse-pointer.png"), auto;
@include mobile {
font-size: 0.8em;
line-height: 1.4;
}
}
h1, h2, h3, h4, h5, h6 {
font-family: $mono;
color: $amber;
padding: 0;
@include mobile { line-height: 1.4; }
}
h1 { font-size: 2em; font-weight: bold; a { color: inherit; } }
h2 { font-size: 1.5em; }
h3 { font-size: 1.25em; }
h4 { font-size: 1.10em; color: $amber-dim; }
p {
margin: 1em 0;
text-align: justify;
font-family: $helvetica;
color: $body-text;
}
a {
color: $link;
text-decoration: none;
cursor: url("/images/atari-st-mouse-hand.png"), auto;
&:visited { color: $link-visited; }
&:hover, &:active { color: $amber; }
}
ul, ol { margin: 15px 0; padding-left: 30px; }
ul { list-style-type: disc; }
ol { list-style-type: decimal; }
ol ul, ul ol, ul ul, ol ol { margin: 0; }
ul ul, ol ul { list-style-type: circle; }
em, i { font-style: italic; }
strong, b { font-weight: bold; }
img { max-width: 100%; }
::selection { color: $bg-body; background: $amber; }
::-moz-selection { color: $bg-body; background: $amber; }
- Step 3: Start Jekyll server and verify foundation
docker run --rm -p 4000:4000 -v $(pwd):/srv/jekyll \
jekyll/builder:latest jekyll serve --future --livereload
Open http://localhost:4000 — verify:
- Background is near-black
#0A0A0A(no photo) - Body text is
#E0E0E0(light gray) -
Links are cyan
#5BC8FF - Step 4: Commit
git add _sass/_variables.scss _sass/_base-rules.scss
git commit -m "style: rewrite CSS foundation — VT-100 color tokens and base rules"
Task 2: Remove CDN Dependencies
Files:
- Modify:
_layouts/default.html
Context
default.html currently loads: Font Awesome 4.7, Zocial CSS, hover.css, blink.css. These are replaced by Unicode/ASCII equivalents in the new design.
- Step 1: Remove CDN links from
default.html
In _layouts/default.html, replace the <head> section. Find these lines and remove them:
<!-- REMOVE these 3 lines: -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/css-social-buttons/1.3.0/css/zocial.min.css" />
<link rel="stylesheet" type="text/css" href="/blink.css" />
<link rel="stylesheet" type="text/css" href="/hover/hover.css" />
Also update <meta name="theme-color"> from #ffffff to #0A0A0A:
<meta name="theme-color" content="#0A0A0A" />
- Step 2: Verify build has no broken references
docker run -v $(pwd):/srv/jekyll -v $(pwd)/_site:/srv/jekyll/_site \
jekyll/builder:latest /bin/bash -c "chmod 777 /srv/jekyll && jekyll build --future"
Expected: Build succeeds, no errors in output.
- Step 3: Verify no Font Awesome icons broken in rendered HTML
Open http://localhost:4000 — verify no broken fa-* icon squares visible. The svg-icons include uses inline SVG, not FA — should be fine.
- Step 4: Commit
git add _layouts/default.html
git commit -m "style: remove Font Awesome, Zocial, hover.css, blink.css CDN dependencies"
Task 3: Header SCSS + HTML
Files:
- Create:
_sass/_header.scss - Modify:
_layouts/default.html(header section) -
Modify:
style.scss(add import, remove inline.wrapper-masthead/.masthead/.site-*rules) - Step 1: Create
_sass/_header.scss
.wrapper-masthead {
background: $bg-body;
border-bottom: 2px solid $amber;
padding: 0.75rem 0;
width: 100%;
position: relative;
// Scanline overlay
&::after {
content: '';
position: absolute;
inset: 0;
background: repeating-linear-gradient(
0deg,
rgba(0,0,0,0.08),
rgba(0,0,0,0.08) 1px,
transparent 1px,
transparent 2px
);
pointer-events: none;
}
}
.masthead {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 1rem;
font-family: $mono;
@include mobile {
flex-direction: column;
gap: 0.5rem;
}
}
.site-avatar {
width: 40px;
height: 40px;
flex-shrink: 0;
img { width: 100%; height: 100%; object-fit: contain; }
}
.site-name {
font-family: $mono;
font-size: 1.2rem;
color: $amber;
text-shadow: 0 0 8px $amber;
margin: 0;
flex: 1;
padding-left: 1rem;
a { color: $amber; }
}
.site-description {
display: none; // description now in typewriter effect
}
.header-lang {
font-family: $mono;
font-size: 0.85rem;
display: flex;
gap: 0.5rem;
a {
color: $amber-dim;
padding: 0.15rem 0.4rem;
border: 1px solid $amber-dim;
&:visited { color: $amber-dim; }
&:hover { color: $amber; border-color: $amber; text-shadow: 0 0 6px $amber; }
&.active {
color: $amber;
border-color: $amber;
text-shadow: 0 0 6px $amber;
}
}
}
- Step 2: Update header HTML in
_layouts/default.html
Replace the <div class="wrapper-masthead"> block with:
<div class="wrapper-masthead">
<div class="container">
<header class="masthead clearfix">
<a href="/" class="site-avatar">
<img src="/images/new-java-logo.png" alt="FX JavaDevBlog" title="FX JavaDevBlog" />
</a>
<div class="site-info">
<h1 id="site-name" class="site-name"><a href="/">FX JavaDevBlog</a></h1>
</div>
<div class="header-lang">
<a href="/index-fr.html"
class="">FR</a>
<span style="color: #996600; font-family: monospace;">·</span>
<a href="/index-en.html"
class="">EN</a>
</div>
</header>
</div>
</div>
Note: The nav element is removed from the header — navigation moves to sidebar (Task 5).
- Step 3: Add import to
style.scssand remove inline.wrapper-mastheadblock
In style.scss:
- Add
@import "header";after@import "nav"; - Remove (or comment) the existing
.wrapper-masthead,.masthead,.site-avatar,.site-name,.site-descriptionblocks inline instyle.scss
- Step 4: Verify
docker run --rm -p 4000:4000 -v $(pwd):/srv/jekyll \
jekyll/builder:latest jekyll serve --future --livereload
Open http://localhost:4000 — verify:
- Header is
#0A0A0Awith amber bottom border - Site name is amber, glowing slightly
- Language toggle
[FR] · [EN]visible top-right -
Active language is bright amber, inactive is dim
- Step 5: Commit
git add _sass/_header.scss _layouts/default.html style.scss
git commit -m "style: add VT-100 header — amber strip, scanlines, language toggle"
Task 4: Sidebar SCSS + HTML
Files:
- Create:
_sass/_sidebar.scss - Modify:
_layouts/default.html(body structure — add.sidebarwrapper) - Modify:
_includes/full-index-page.html(split-pane layout) -
Modify:
style.scss(add import, rewrite#left/#right,.container) - Step 1: Create
_sass/_sidebar.scss
.site-wrapper {
display: flex;
max-width: 1800px;
margin: 0 auto;
min-height: calc(100vh - 80px);
}
.sidebar {
width: 220px;
min-width: 220px;
flex-shrink: 0;
background: $bg-body;
border-right: 1px solid $border;
padding: 1.5rem 1rem;
font-family: $mono;
position: relative;
// Scanline overlay
&::after {
content: '';
position: absolute;
inset: 0;
background: repeating-linear-gradient(
0deg,
rgba(0,0,0,0.08),
rgba(0,0,0,0.08) 1px,
transparent 1px,
transparent 2px
);
pointer-events: none;
}
.sidebar-prompt {
color: $amber-dim;
font-size: 0.75rem;
margin-bottom: 0.5rem;
}
.sidebar-divider {
border: none;
border-top: 1px solid $border;
margin: 1rem 0;
}
.sidebar-section-title {
color: $amber-dim;
font-size: 0.7rem;
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 0.5rem;
}
.sidebar-tags {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
a {
color: $amber-dim;
font-size: 0.75rem;
font-family: $mono;
&:hover { color: $amber; text-shadow: 0 0 6px $amber; }
&:visited { color: $amber-dim; }
}
}
.sidebar-recent {
list-style: none;
padding: 0;
margin: 0;
li { margin-bottom: 0.4rem; }
a {
color: $amber-dim;
font-size: 0.75rem;
font-family: $mono;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&::before { content: '- '; color: $amber-dim; }
&:hover { color: $amber; }
&:visited { color: $amber-dim; }
}
}
@include mobile {
display: none;
}
}
.main-content {
flex: 1;
min-width: 0;
padding: 1.5rem 2rem;
@include mobile {
padding: 1rem;
}
}
- Step 2: Update
_layouts/default.htmlbody structure
Replace the `<div id=”main” …><article class="post">
Audit du Repository — FX JavaDevBlog
<div class="accroche"></div>
<!-- include language-selector.html -->
Audit du Repository — FX JavaDevBlog
Date : 18 avril 2026
Repository : fxrobin/fxrobin.github.io
Site : https://www.fxjavadevblog.fr
Auditeur : Claude Code
Résumé Exécutif
Blog technique Jekyll bien structuré, focalisé Java/rétro/architecture. Infrastructure solide, automatisation complète. Contenu à 68% vieux de 5+ ans, mais reprise notable en avril 2026.
Bilan santé global :
| Dimension | Note | Commentaire |
|---|---|---|
| Infrastructure | ★★★★★ | CI/CD, Docker, plugins |
| Structure contenu | ★★★★☆ | Conventions cohérentes |
| SEO | ★★★☆☆ | Plugins OK, JSON-LD absent |
| Couverture bilingue | ★★☆☆☆ | 18% EN seulement |
| Fréquence publication | ★★☆☆☆ | Gaps 2 ans répétés |
| Performance frontend | ★★★☆☆ | CDN OK, CSS non-minifié |
1. Contenu
1.1 Volume et distribution
| Catégorie | Total | FR | EN | Récents (≤2 ans) | Moyens (2–5 ans) | Anciens (5+ ans) |
|---|---|---|---|---|---|---|
| Articles | 23 | 17 | 6 | 4 | 4 | 15 |
| Blanka Cave | 10 | 10 | 0 | 0 | 0 | 10 |
| Retro-Prog | 11 | 9 | 2 | 2 | 4 | 5 |
| TOTAL | 44 | 36 | 8 | 6 | 8 | 30 |
Distribution linguistique :
- Français : 36 posts (81%)
- Anglais : 8 posts (18%)
- Paires bilingues (même
ref) : 8
1.2 Timeline de publication
2018 : 21 posts ★★★★★ Lancement / pic d'activité
2019 : 0 posts —————— GAP 1 (2 ans)
2020 : 4 posts ★★
2021 : 8 posts ★★★★
2022 : 3 posts ★
2023 : 2 posts ★
2024 : 2 posts ★ GAP 2 (24 mois)
2025 : 0 posts ——————
2026 : 4 posts ★★ Reprise (avril 2026)
Pics :
- Juillet 2018 : 7 posts (lancement Blanka Cave)
- Mars 2018 : 5 posts
- Avril 2026 : 4 posts (reprise actuelle)
1.3 Thématiques et tags
73 tags uniques. Top 10 :
| Tag | Occurrences |
|---|---|
| Java | 13 |
| Retro / Retro-Prog | 11 |
| Atari | 9 |
| C | 6 |
| Assembleur | 5 |
| Lambda / Functional | 4 |
| JPA / Lombok | 3 |
| Maven / Bean Validation | 2–3 |
Clusters thématiques :
- Rétro computing (Atari ST, Thomson, 68000, 6809) : ~33%
- Java enterprise (CDI, JPA, Quarkus, GraalVM, JAX-RS) : ~27%
- DevOps/Tooling (Maven, Docker, GitHub) : ~14%
- Design patterns & craftsmanship : ~9%
Couverture Java : Java 8, 10, 12, 21 mentionnés dans des posts. Aucun article dédié aux versions Java.
1.4 Qualité des front matter
| Champ | Présence | Statut |
|---|---|---|
| layout, title, lang, category | 44/44 | ✓ 100% |
| logo | 44/44 | ✓ 100% (référencé) |
| subtitle | 34/44 | ✓ 77% |
| ref | 34/44 | ✓ 77% |
| tags | 33/44 | ✓ 75% |
excerpt marker <!--excerpt--> |
33/44 | ✓ 75% |
Les posts Blanka Cave sont intentionnellement minimalistes (pas de tags, pas de ref, sitemap: false).
1.5 Brouillons (_drafts/)
9 fichiers markdown :
| Fichier | Taille | Statut estimé |
|---|---|---|
PLAN.md |
— | Plan éditorial |
a-rediger.md |
— | Placeholder |
questions-poo.md |
13.2 KB | Quasi-publiable |
angular8-javaee.md |
— | Daté (Angular 8) |
choisir-js-angular-react-vue-webcomponents.md |
— | Daté |
cdi-payara-arquillian-deltaspike.md |
— | Abandonné probable |
focus-list.md |
— | Court |
gradle-travis-github.md |
— | Daté |
java-ee-nio.md |
— | Daté |
7 répertoires de drafts en cours :
| Répertoire | Sujet |
|---|---|
blog/ |
Contenu générique |
maven-javadoc-lombok-java-21/ |
Combo Maven + Java 21 |
minikube-helm-quarkus/ |
Kubernetes + Quarkus |
uuid-versions-jmh/ |
UUID v7, benchmarks JMH |
vertx-eventbus-quarkus/ |
Vert.x EventBus |
virtual-threads-loom/ |
Project Loom |
x-mas-architecture/ |
Architecture de Noël |
2. Technologies
2.1 Jekyll
| Paramètre | Valeur |
|---|---|
| Version Jekyll | v1.2.0 |
| Markdown | GFM (GitHub Flavored) |
| Syntax highlighter | Rouge |
| Pagination | 3 posts/page |
| Excerpt separator | <!--excerpt--> |
| Permalink par défaut | /:title/ |
| Style CSS généré | :expanded (non-minifié) |
Plugins activés (3) :
| Plugin | Rôle |
|---|---|
jekyll-sitemap |
Génération sitemap.xml automatique |
jekyll-seo-tag |
Meta tags SEO (OG, Twitter Card) |
jekyll-redirect-from |
Redirections d’URL legacy |
jekyll-feed est commenté dans _config.yml — RSS désactivé intentionnellement.
2.2 CI/CD
GitHub Actions (.github/workflows/jekyll.yml) :
- Déclencheurs : push et PR sur
master - Runner :
ubuntu-latest - Container build :
jekyll/builder:latest - Commande :
jekyll build --future - Pas de Gemfile local, pas de Dockerfile — dépend entièrement du container officiel
2.3 Frontend
Aucun package.json, aucun npm. Tout via CDN :
| Bibliothèque | Version | Source | Usage |
|---|---|---|---|
| TypewriterJS | 1.0.0 | CDNJS | Animation titre header |
| Vue.js | 2.5.16 | CDNJS | Composants réactifs (usage réel ?) |
| Axios | 0.18.0 | CDNJS | Requêtes AJAX |
| Font Awesome | 4.7.0 | CDNJS | Icônes |
| CSS Social Buttons | 1.3.0 | CDNJS | Boutons de partage |
| Mermaid | 10 | JSDelivr | Diagrammes (opt-in) |
| Asciinema | local | /asciinema/ |
Lectures terminales |
JavaScript local (2 fichiers) :
js/main.js(2.8 KB) — Fonctionnalités corejs/cv-scroll-animations.js(4.6 KB) — Animations page CV
2.4 Sass / CSS
26 modules SCSS dans _sass/ :
| Module | Taille | Rôle |
|---|---|---|
_svg-icons.scss |
52.6 KB | SVG inline (icônes sociales) |
_base-rules.scss |
— | Typographie, base |
_post.scss |
— | Styles article |
_variables.scss |
— | Couleurs, polices |
_highlights.scss |
— | Coloration syntaxique |
_table-of-content.scss |
— | TOC |
_nav.scss, _search.scss, _blanka.scss, _retro-list.scss |
— | Composants spécifiques |
effects/ |
— | Animations |
| 16 autres | — | Reset, mixins, layout |
Polices custom (_fonts.scss) : amiga, atari, volter, coders-crux, Monda — identité rétro/hacker forte.
Stylesheets complémentaires : blink.css, hover.css, print.css
2.5 Layouts et Includes
7 layouts :
_layouts/
├── default.html (5.2 KB) ← Base : header, nav, footer, JS
│ ├── post.html (769 B) ← Articles
│ ├── page.html (406 B)
│ ├── page-no-aside.html
│ ├── blog_index.html
│ ├── cv-layout.html
│ └── cv-new-layout.html
25 includes dont :
| Include | Taille | Rôle |
|---|---|---|
toc.html |
3.8 KB | Générateur TOC automatique |
meta.html |
744 B | SEO + Open Graph |
disqus.html |
706 B | Commentaires Disqus |
analytics.html |
376 B | Google Analytics |
search.html |
633 B | Google Custom Search |
post-aside.html |
929 B | Sidebar (TOC + partage) |
language-selector.html |
474 B | Sélecteur FR/EN |
mermaid.html |
128 B | Loader Mermaid |
asciinema.html |
93 B | Player terminal |
svg-icons.html |
2.1 KB | Icônes sociales/footer |
3. Architecture
3.1 Structure répertoires
fxrobin.github.io/
├── _posts/
│ ├── articles/ 23 posts (sous-dossiers par slug)
│ ├── blanka-cave/fr/ 10 posts
│ └── retro-prog/ 11 posts
├── _drafts/ 9 .md + 7 répertoires en cours
├── _layouts/ 7 templates
├── _includes/ 25 composants
├── _sass/ 26 modules SCSS
├── images/ 19 sous-répertoires (logos, flags, par-article)
├── js/ 2 fichiers JS
├── fonts/ 614 KB (polices custom)
├── asciinema/ 621 KB (player + casts)
├── casts/ 54 KB (enregistrements terminal)
├── _config.yml
├── style.scss
├── index.html / index-fr.html / index-en.html
└── .github/workflows/jekyll.yml
3.2 Convention de nommage des posts
_posts/[catégorie]/[slug optionnel]/YYYY-MM-DD-[slug].md
Exemples :
_posts/articles/api-preconditions/2018-06-02-api-preconditions.md_posts/blanka-cave/fr/2018-07-21-Web-Components.md_posts/retro-prog/m68k-cross-compiling/2021-02-05-m68k-cross-compiling-EN.md
3.3 Système multilingue
- Champ
lang: fr|endans le front matter - Champ
refpartagé entre les versions d’un même article language-selector.htmlretrouve la version alternate viaref- Labels UI (menus, textes) définis dans
_config.ymlsoussite.t[lang].* - Blanka Cave : uniquement FR, pas de
ref
3.4 Stratégie permalink
- Par défaut :
/:title/ - Surcharge possible via
permalink:dans le front matter (ex. anglais vs français) - Redirections legacy :
redirect_from:géré parjekyll-redirect-from
4. SEO et Intégrations tierces
4.1 SEO
| Élément | Présence | Statut |
|---|---|---|
| sitemap.xml | ✓ auto via plugin | OK |
| Open Graph (og:title, og:description) | ✓ | OK |
| Twitter Card | ✓ | OK |
| Google Search Console | ✓ (googleb3f4e2521de300ce.html) |
OK |
| Viewport meta | ✓ | OK |
| Canonical URLs | Implicite | OK |
| robots.txt explicite | ✗ | Manquant |
| JSON-LD / Schema.org | ✗ | Absent |
Sitemap dans <head> |
✗ | Non lié |
4.2 Intégrations actives
| Service | Config | Statut |
|---|---|---|
| Disqus | shortname: fxrobin-github-io |
✓ Actif |
| Google Analytics | UA-114271874-1 | ✓ Actif (Universal — obsolète) |
| Google Custom Search | cx=011993730579911903160:17ronej8jdw | ✓ Actif |
| Mermaid.js | opt-in via page.mermaid: true |
✓ Disponible, 0 posts l’utilisent |
| Asciinema | opt-in via include | ✓ Disponible, 0 posts l’utilisent |
5. Qualité et Problèmes Détectés
5.1 Problème critique — Logos manquants
21 fichiers logo référencés dans le front matter mais absents de /images/logos/.
Impact : 48% des posts affichent une image cassée.
Exemples : api-preconditions.png, archiva-rpi.png, code.png (mais code.jpg existe).
Action : Audit exhaustif images/logos/ vs tous les champs logo: des posts.
5.2 Problèmes importants
| Problème | Impact | Recommandation |
|---|---|---|
| Gaps de publication (2 ans) | Audience / SEO | Cadence éditoriale fixe |
| Google Analytics Universal (UA) | Tracking perdu — UA retraité | Migrer vers GA4 |
| Vue.js 2.5.16 inclus sans usage visible | Poids inutile | Vérifier / supprimer |
CSS non-minifié (style: :expanded) |
Performance | Passer à :compressed |
| Couverture EN à 18% | Audience internationale | Traduire 10–15 articles clés |
| Mermaid / Asciinema inutilisés | Fonctionnalités inexploitées | Les utiliser dans les prochains articles |
5.3 Améliorations mineures
| Problème | Recommandation |
|---|---|
| 73 tags sans casse uniforme (“java” vs “Java”) | Guide de style tags |
25% des posts sans <!--excerpt--> |
Ajouter sur les anciens posts clés |
| Dépendances front-end figées sur vieilles versions | Auditer + mettre à jour (FA 4→6, TypewriterJS) |
jekyll-feed commenté (RSS désactivé) |
Considérer activation (audience RSS) |
Pas de robots.txt explicite |
Créer fichier minimal |
| Pas de JSON-LD | Ajouter schema BlogPosting pour rich snippets |
5.4 Drafts — action éditoriale
| Draft | Recommandation |
|---|---|
questions-poo.md (13.2 KB) |
Finaliser et publier |
virtual-threads-loom/ |
Sujet très actuel (Java 21+), prioritaire |
uuid-versions-jmh/ |
JMH = différenciateur technique, prioritaire |
vertx-eventbus-quarkus/ |
Bon sujet Quarkus ecosystem |
angular8-javaee.md |
Abandonner (Angular 8 = daté) |
choisir-js-angular-react-vue-webcomponents.md |
Abandonner ou réécrire 2026 |
cdi-payara-arquillian-deltaspike.md |
Abandonner |
6. Métriques de synthèse
| Métrique | Valeur | Statut |
|---|---|---|
| Posts publiés | 44 | ✓ |
| Posts FR | 36 (81%) | ✓ |
| Posts EN | 8 (18%) | ⚠ Faible |
| Paires bilingues | 8 | ✓ |
| Drafts .md | 9 | ⚠ À trier |
| Répertoires en cours | 7 | ⚠ Prioritiser |
| Front matter complet (requis) | 100% | ✓ |
| Logos référencés vs présents | 52% | ✗ Critique |
| Excerpt marqué | 75% | ✓ |
| Tags uniques | 73 | ✓ |
| Layouts | 7 | ✓ |
| Includes | 25 | ✓ |
| Modules SCSS | 26 | ✓ |
| Plugins Jekyll | 3 | ✓ |
| Intégrations tierces | 5 | ✓ |
7. Recommandations prioritaires
Priorité 1 — Critique
- Réparer les logos manquants (21 fichiers) — impact visuel direct sur 48% des posts
Priorité 2 — Important
- Migrer Google Analytics UA → GA4 — UA est retraité, les données sont perdues
- Établir une cadence de publication — 1 article/mois minimum pour éviter les gaps
- Publier les drafts prioritaires :
virtual-threads-loom,uuid-versions-jmh,questions-poo.md - Supprimer ou mettre à jour Vue.js — v2.5.16 inclus systématiquement, usage non vérifié
Priorité 3 — Amélioration
- Activer la minification CSS :
style: :compresseddans_config.yml - Ajouter
robots.txtexplicite - Ajouter JSON-LD
BlogPostingpour les rich snippets Google - Uniformiser les tags (casse, singulier/pluriel)
- Utiliser Mermaid.js et Asciinema dans les prochains articles techniques
Généré par Claude Code — avril 2026
</article>
</div>` block with:
<div class="site-wrapper">
<aside class="sidebar">
<div class="sidebar-prompt">$ ls /dev/</div>
<nav class="sidebar-nav-list">
</nav>
<hr class="sidebar-divider">
<div class="sidebar-search">
<label class="sidebar-section-title" for="search-input">$ grep -r</label>
<div class="search-prompt">
<span class="search-prefix">"</span>
<input id="search-input"
type="text"
class="search-input"
placeholder=""
autocomplete="off" />
<span class="search-suffix">"</span>
</div>
<div id="search-results" class="search-results"></div>
</div>
<hr class="sidebar-divider">
<div class="sidebar-section-title">#TAGS</div>
<div class="sidebar-tags">
</div>
</aside>
<main class="main-content" id="main" role="main">
<article class="post">
<img src="/images/logos/" class="logo-in-page"/>
<h1>Audit du Repository — FX JavaDevBlog</h1>
<div class="accroche"></div>
<!-- include language-selector.html -->
<div class="post-body">
<div class="entry entry-content">
<h1 id="audit-du-repository--fx-javadevblog">Audit du Repository — FX JavaDevBlog</h1>
<p><strong>Date :</strong> 18 avril 2026<br />
<strong>Repository :</strong> <code class="language-plaintext highlighter-rouge">fxrobin/fxrobin.github.io</code><br />
<strong>Site :</strong> https://www.fxjavadevblog.fr<br />
<strong>Auditeur :</strong> Claude Code</p>
<hr />
<h2 id="résumé-exécutif">Résumé Exécutif</h2>
<p>Blog technique Jekyll bien structuré, focalisé Java/rétro/architecture. Infrastructure solide, automatisation complète. Contenu à 68% vieux de 5+ ans, mais reprise notable en avril 2026.</p>
<p><strong>Bilan santé global :</strong></p>
<table>
<thead>
<tr>
<th>Dimension</th>
<th>Note</th>
<th>Commentaire</th>
</tr>
</thead>
<tbody>
<tr>
<td>Infrastructure</td>
<td>★★★★★</td>
<td>CI/CD, Docker, plugins</td>
</tr>
<tr>
<td>Structure contenu</td>
<td>★★★★☆</td>
<td>Conventions cohérentes</td>
</tr>
<tr>
<td>SEO</td>
<td>★★★☆☆</td>
<td>Plugins OK, JSON-LD absent</td>
</tr>
<tr>
<td>Couverture bilingue</td>
<td>★★☆☆☆</td>
<td>18% EN seulement</td>
</tr>
<tr>
<td>Fréquence publication</td>
<td>★★☆☆☆</td>
<td>Gaps 2 ans répétés</td>
</tr>
<tr>
<td>Performance frontend</td>
<td>★★★☆☆</td>
<td>CDN OK, CSS non-minifié</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="1-contenu">1. Contenu</h2>
<h3 id="11-volume-et-distribution">1.1 Volume et distribution</h3>
<table>
<thead>
<tr>
<th>Catégorie</th>
<th>Total</th>
<th>FR</th>
<th>EN</th>
<th>Récents (≤2 ans)</th>
<th>Moyens (2–5 ans)</th>
<th>Anciens (5+ ans)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Articles</td>
<td>23</td>
<td>17</td>
<td>6</td>
<td>4</td>
<td>4</td>
<td>15</td>
</tr>
<tr>
<td>Blanka Cave</td>
<td>10</td>
<td>10</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>10</td>
</tr>
<tr>
<td>Retro-Prog</td>
<td>11</td>
<td>9</td>
<td>2</td>
<td>2</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td><strong>TOTAL</strong></td>
<td><strong>44</strong></td>
<td><strong>36</strong></td>
<td><strong>8</strong></td>
<td><strong>6</strong></td>
<td><strong>8</strong></td>
<td><strong>30</strong></td>
</tr>
</tbody>
</table>
<p><strong>Distribution linguistique :</strong></p>
<ul>
<li>Français : 36 posts (81%)</li>
<li>Anglais : 8 posts (18%)</li>
<li>Paires bilingues (même <code class="language-plaintext highlighter-rouge">ref</code>) : 8</li>
</ul>
<h3 id="12-timeline-de-publication">1.2 Timeline de publication</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2018 : 21 posts ★★★★★ Lancement / pic d'activité
2019 : 0 posts —————— GAP 1 (2 ans)
2020 : 4 posts ★★
2021 : 8 posts ★★★★
2022 : 3 posts ★
2023 : 2 posts ★
2024 : 2 posts ★ GAP 2 (24 mois)
2025 : 0 posts ——————
2026 : 4 posts ★★ Reprise (avril 2026)
</code></pre></div></div>
<p><strong>Pics :</strong></p>
<ul>
<li>Juillet 2018 : 7 posts (lancement Blanka Cave)</li>
<li>Mars 2018 : 5 posts</li>
<li>Avril 2026 : 4 posts (reprise actuelle)</li>
</ul>
<h3 id="13-thématiques-et-tags">1.3 Thématiques et tags</h3>
<p><strong>73 tags uniques.</strong> Top 10 :</p>
<table>
<thead>
<tr>
<th>Tag</th>
<th>Occurrences</th>
</tr>
</thead>
<tbody>
<tr>
<td>Java</td>
<td>13</td>
</tr>
<tr>
<td>Retro / Retro-Prog</td>
<td>11</td>
</tr>
<tr>
<td>Atari</td>
<td>9</td>
</tr>
<tr>
<td>C</td>
<td>6</td>
</tr>
<tr>
<td>Assembleur</td>
<td>5</td>
</tr>
<tr>
<td>Lambda / Functional</td>
<td>4</td>
</tr>
<tr>
<td>JPA / Lombok</td>
<td>3</td>
</tr>
<tr>
<td>Maven / Bean Validation</td>
<td>2–3</td>
</tr>
</tbody>
</table>
<p><strong>Clusters thématiques :</strong></p>
<ul>
<li>Rétro computing (Atari ST, Thomson, 68000, 6809) : ~33%</li>
<li>Java enterprise (CDI, JPA, Quarkus, GraalVM, JAX-RS) : ~27%</li>
<li>DevOps/Tooling (Maven, Docker, GitHub) : ~14%</li>
<li>Design patterns & craftsmanship : ~9%</li>
</ul>
<p><strong>Couverture Java :</strong> Java 8, 10, 12, 21 mentionnés dans des posts. Aucun article dédié aux versions Java.</p>
<h3 id="14-qualité-des-front-matter">1.4 Qualité des front matter</h3>
<table>
<thead>
<tr>
<th>Champ</th>
<th>Présence</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
<tr>
<td>layout, title, lang, category</td>
<td>44/44</td>
<td>✓ 100%</td>
</tr>
<tr>
<td>logo</td>
<td>44/44</td>
<td>✓ 100% (référencé)</td>
</tr>
<tr>
<td>subtitle</td>
<td>34/44</td>
<td>✓ 77%</td>
</tr>
<tr>
<td>ref</td>
<td>34/44</td>
<td>✓ 77%</td>
</tr>
<tr>
<td>tags</td>
<td>33/44</td>
<td>✓ 75%</td>
</tr>
<tr>
<td>excerpt marker <code class="language-plaintext highlighter-rouge"><!--excerpt--></code></td>
<td>33/44</td>
<td>✓ 75%</td>
</tr>
</tbody>
</table>
<p>Les posts Blanka Cave sont intentionnellement minimalistes (pas de tags, pas de <code class="language-plaintext highlighter-rouge">ref</code>, <code class="language-plaintext highlighter-rouge">sitemap: false</code>).</p>
<h3 id="15-brouillons-_drafts">1.5 Brouillons (_drafts/)</h3>
<p><strong>9 fichiers markdown :</strong></p>
<table>
<thead>
<tr>
<th>Fichier</th>
<th>Taille</th>
<th>Statut estimé</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">PLAN.md</code></td>
<td>—</td>
<td>Plan éditorial</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">a-rediger.md</code></td>
<td>—</td>
<td>Placeholder</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">questions-poo.md</code></td>
<td>13.2 KB</td>
<td>Quasi-publiable</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">angular8-javaee.md</code></td>
<td>—</td>
<td>Daté (Angular 8)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">choisir-js-angular-react-vue-webcomponents.md</code></td>
<td>—</td>
<td>Daté</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">cdi-payara-arquillian-deltaspike.md</code></td>
<td>—</td>
<td>Abandonné probable</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">focus-list.md</code></td>
<td>—</td>
<td>Court</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">gradle-travis-github.md</code></td>
<td>—</td>
<td>Daté</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">java-ee-nio.md</code></td>
<td>—</td>
<td>Daté</td>
</tr>
</tbody>
</table>
<p><strong>7 répertoires de drafts en cours :</strong></p>
<table>
<thead>
<tr>
<th>Répertoire</th>
<th>Sujet</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">blog/</code></td>
<td>Contenu générique</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">maven-javadoc-lombok-java-21/</code></td>
<td>Combo Maven + Java 21</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">minikube-helm-quarkus/</code></td>
<td>Kubernetes + Quarkus</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">uuid-versions-jmh/</code></td>
<td>UUID v7, benchmarks JMH</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">vertx-eventbus-quarkus/</code></td>
<td>Vert.x EventBus</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">virtual-threads-loom/</code></td>
<td>Project Loom</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">x-mas-architecture/</code></td>
<td>Architecture de Noël</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="2-technologies">2. Technologies</h2>
<h3 id="21-jekyll">2.1 Jekyll</h3>
<table>
<thead>
<tr>
<th>Paramètre</th>
<th>Valeur</th>
</tr>
</thead>
<tbody>
<tr>
<td>Version Jekyll</td>
<td>v1.2.0</td>
</tr>
<tr>
<td>Markdown</td>
<td>GFM (GitHub Flavored)</td>
</tr>
<tr>
<td>Syntax highlighter</td>
<td>Rouge</td>
</tr>
<tr>
<td>Pagination</td>
<td>3 posts/page</td>
</tr>
<tr>
<td>Excerpt separator</td>
<td><code class="language-plaintext highlighter-rouge"><!--excerpt--></code></td>
</tr>
<tr>
<td>Permalink par défaut</td>
<td><code class="language-plaintext highlighter-rouge">/:title/</code></td>
</tr>
<tr>
<td>Style CSS généré</td>
<td><code class="language-plaintext highlighter-rouge">:expanded</code> (non-minifié)</td>
</tr>
</tbody>
</table>
<p><strong>Plugins activés (3) :</strong></p>
<table>
<thead>
<tr>
<th>Plugin</th>
<th>Rôle</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">jekyll-sitemap</code></td>
<td>Génération sitemap.xml automatique</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">jekyll-seo-tag</code></td>
<td>Meta tags SEO (OG, Twitter Card)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">jekyll-redirect-from</code></td>
<td>Redirections d’URL legacy</td>
</tr>
</tbody>
</table>
<p><code class="language-plaintext highlighter-rouge">jekyll-feed</code> est commenté dans <code class="language-plaintext highlighter-rouge">_config.yml</code> — RSS désactivé intentionnellement.</p>
<h3 id="22-cicd">2.2 CI/CD</h3>
<p><strong>GitHub Actions</strong> (<code class="language-plaintext highlighter-rouge">.github/workflows/jekyll.yml</code>) :</p>
<ul>
<li>Déclencheurs : push et PR sur <code class="language-plaintext highlighter-rouge">master</code></li>
<li>Runner : <code class="language-plaintext highlighter-rouge">ubuntu-latest</code></li>
<li>Container build : <code class="language-plaintext highlighter-rouge">jekyll/builder:latest</code></li>
<li>Commande : <code class="language-plaintext highlighter-rouge">jekyll build --future</code></li>
<li>Pas de Gemfile local, pas de Dockerfile — dépend entièrement du container officiel</li>
</ul>
<h3 id="23-frontend">2.3 Frontend</h3>
<p><strong>Aucun <code class="language-plaintext highlighter-rouge">package.json</code>, aucun <code class="language-plaintext highlighter-rouge">npm</code>.</strong> Tout via CDN :</p>
<table>
<thead>
<tr>
<th>Bibliothèque</th>
<th>Version</th>
<th>Source</th>
<th>Usage</th>
</tr>
</thead>
<tbody>
<tr>
<td>TypewriterJS</td>
<td>1.0.0</td>
<td>CDNJS</td>
<td>Animation titre header</td>
</tr>
<tr>
<td>Vue.js</td>
<td>2.5.16</td>
<td>CDNJS</td>
<td>Composants réactifs (usage réel ?)</td>
</tr>
<tr>
<td>Axios</td>
<td>0.18.0</td>
<td>CDNJS</td>
<td>Requêtes AJAX</td>
</tr>
<tr>
<td>Font Awesome</td>
<td>4.7.0</td>
<td>CDNJS</td>
<td>Icônes</td>
</tr>
<tr>
<td>CSS Social Buttons</td>
<td>1.3.0</td>
<td>CDNJS</td>
<td>Boutons de partage</td>
</tr>
<tr>
<td>Mermaid</td>
<td>10</td>
<td>JSDelivr</td>
<td>Diagrammes (opt-in)</td>
</tr>
<tr>
<td>Asciinema</td>
<td>local</td>
<td><code class="language-plaintext highlighter-rouge">/asciinema/</code></td>
<td>Lectures terminales</td>
</tr>
</tbody>
</table>
<p><strong>JavaScript local (2 fichiers) :</strong></p>
<ul>
<li><code class="language-plaintext highlighter-rouge">js/main.js</code> (2.8 KB) — Fonctionnalités core</li>
<li><code class="language-plaintext highlighter-rouge">js/cv-scroll-animations.js</code> (4.6 KB) — Animations page CV</li>
</ul>
<h3 id="24-sass--css">2.4 Sass / CSS</h3>
<p><strong>26 modules SCSS dans <code class="language-plaintext highlighter-rouge">_sass/</code> :</strong></p>
<table>
<thead>
<tr>
<th>Module</th>
<th>Taille</th>
<th>Rôle</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">_svg-icons.scss</code></td>
<td><strong>52.6 KB</strong></td>
<td>SVG inline (icônes sociales)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_base-rules.scss</code></td>
<td>—</td>
<td>Typographie, base</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_post.scss</code></td>
<td>—</td>
<td>Styles article</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_variables.scss</code></td>
<td>—</td>
<td>Couleurs, polices</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_highlights.scss</code></td>
<td>—</td>
<td>Coloration syntaxique</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_table-of-content.scss</code></td>
<td>—</td>
<td>TOC</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_nav.scss</code>, <code class="language-plaintext highlighter-rouge">_search.scss</code>, <code class="language-plaintext highlighter-rouge">_blanka.scss</code>, <code class="language-plaintext highlighter-rouge">_retro-list.scss</code></td>
<td>—</td>
<td>Composants spécifiques</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">effects/</code></td>
<td>—</td>
<td>Animations</td>
</tr>
<tr>
<td>16 autres</td>
<td>—</td>
<td>Reset, mixins, layout</td>
</tr>
</tbody>
</table>
<p><strong>Polices custom</strong> (<code class="language-plaintext highlighter-rouge">_fonts.scss</code>) : <code class="language-plaintext highlighter-rouge">amiga</code>, <code class="language-plaintext highlighter-rouge">atari</code>, <code class="language-plaintext highlighter-rouge">volter</code>, <code class="language-plaintext highlighter-rouge">coders-crux</code>, <code class="language-plaintext highlighter-rouge">Monda</code> — identité rétro/hacker forte.</p>
<p><strong>Stylesheets complémentaires :</strong> <code class="language-plaintext highlighter-rouge">blink.css</code>, <code class="language-plaintext highlighter-rouge">hover.css</code>, <code class="language-plaintext highlighter-rouge">print.css</code></p>
<h3 id="25-layouts-et-includes">2.5 Layouts et Includes</h3>
<p><strong>7 layouts :</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>_layouts/
├── default.html (5.2 KB) ← Base : header, nav, footer, JS
│ ├── post.html (769 B) ← Articles
│ ├── page.html (406 B)
│ ├── page-no-aside.html
│ ├── blog_index.html
│ ├── cv-layout.html
│ └── cv-new-layout.html
</code></pre></div></div>
<p><strong>25 includes</strong> dont :</p>
<table>
<thead>
<tr>
<th>Include</th>
<th>Taille</th>
<th>Rôle</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">toc.html</code></td>
<td>3.8 KB</td>
<td>Générateur TOC automatique</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">meta.html</code></td>
<td>744 B</td>
<td>SEO + Open Graph</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">disqus.html</code></td>
<td>706 B</td>
<td>Commentaires Disqus</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">analytics.html</code></td>
<td>376 B</td>
<td>Google Analytics</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">search.html</code></td>
<td>633 B</td>
<td>Google Custom Search</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">post-aside.html</code></td>
<td>929 B</td>
<td>Sidebar (TOC + partage)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">language-selector.html</code></td>
<td>474 B</td>
<td>Sélecteur FR/EN</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">mermaid.html</code></td>
<td>128 B</td>
<td>Loader Mermaid</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">asciinema.html</code></td>
<td>93 B</td>
<td>Player terminal</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">svg-icons.html</code></td>
<td>2.1 KB</td>
<td>Icônes sociales/footer</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="3-architecture">3. Architecture</h2>
<h3 id="31-structure-répertoires">3.1 Structure répertoires</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fxrobin.github.io/
├── _posts/
│ ├── articles/ 23 posts (sous-dossiers par slug)
│ ├── blanka-cave/fr/ 10 posts
│ └── retro-prog/ 11 posts
├── _drafts/ 9 .md + 7 répertoires en cours
├── _layouts/ 7 templates
├── _includes/ 25 composants
├── _sass/ 26 modules SCSS
├── images/ 19 sous-répertoires (logos, flags, par-article)
├── js/ 2 fichiers JS
├── fonts/ 614 KB (polices custom)
├── asciinema/ 621 KB (player + casts)
├── casts/ 54 KB (enregistrements terminal)
├── _config.yml
├── style.scss
├── index.html / index-fr.html / index-en.html
└── .github/workflows/jekyll.yml
</code></pre></div></div>
<h3 id="32-convention-de-nommage-des-posts">3.2 Convention de nommage des posts</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>_posts/[catégorie]/[slug optionnel]/YYYY-MM-DD-[slug].md
</code></pre></div></div>
<p>Exemples :</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">_posts/articles/api-preconditions/2018-06-02-api-preconditions.md</code></li>
<li><code class="language-plaintext highlighter-rouge">_posts/blanka-cave/fr/2018-07-21-Web-Components.md</code></li>
<li><code class="language-plaintext highlighter-rouge">_posts/retro-prog/m68k-cross-compiling/2021-02-05-m68k-cross-compiling-EN.md</code></li>
</ul>
<h3 id="33-système-multilingue">3.3 Système multilingue</h3>
<ul>
<li>Champ <code class="language-plaintext highlighter-rouge">lang: fr|en</code> dans le front matter</li>
<li>Champ <code class="language-plaintext highlighter-rouge">ref</code> partagé entre les versions d’un même article</li>
<li><code class="language-plaintext highlighter-rouge">language-selector.html</code> retrouve la version alternate via <code class="language-plaintext highlighter-rouge">ref</code></li>
<li>Labels UI (menus, textes) définis dans <code class="language-plaintext highlighter-rouge">_config.yml</code> sous <code class="language-plaintext highlighter-rouge">site.t[lang].*</code></li>
<li>Blanka Cave : uniquement FR, pas de <code class="language-plaintext highlighter-rouge">ref</code></li>
</ul>
<h3 id="34-stratégie-permalink">3.4 Stratégie permalink</h3>
<ul>
<li>Par défaut : <code class="language-plaintext highlighter-rouge">/:title/</code></li>
<li>Surcharge possible via <code class="language-plaintext highlighter-rouge">permalink:</code> dans le front matter (ex. anglais vs français)</li>
<li>Redirections legacy : <code class="language-plaintext highlighter-rouge">redirect_from:</code> géré par <code class="language-plaintext highlighter-rouge">jekyll-redirect-from</code></li>
</ul>
<hr />
<h2 id="4-seo-et-intégrations-tierces">4. SEO et Intégrations tierces</h2>
<h3 id="41-seo">4.1 SEO</h3>
<table>
<thead>
<tr>
<th>Élément</th>
<th>Présence</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
<tr>
<td>sitemap.xml</td>
<td>✓ auto via plugin</td>
<td>OK</td>
</tr>
<tr>
<td>Open Graph (og:title, og:description)</td>
<td>✓</td>
<td>OK</td>
</tr>
<tr>
<td>Twitter Card</td>
<td>✓</td>
<td>OK</td>
</tr>
<tr>
<td>Google Search Console</td>
<td>✓ (<code class="language-plaintext highlighter-rouge">googleb3f4e2521de300ce.html</code>)</td>
<td>OK</td>
</tr>
<tr>
<td>Viewport meta</td>
<td>✓</td>
<td>OK</td>
</tr>
<tr>
<td>Canonical URLs</td>
<td>Implicite</td>
<td>OK</td>
</tr>
<tr>
<td>robots.txt explicite</td>
<td>✗</td>
<td>Manquant</td>
</tr>
<tr>
<td>JSON-LD / Schema.org</td>
<td>✗</td>
<td>Absent</td>
</tr>
<tr>
<td>Sitemap dans <code class="language-plaintext highlighter-rouge"><head></code></td>
<td>✗</td>
<td>Non lié</td>
</tr>
</tbody>
</table>
<h3 id="42-intégrations-actives">4.2 Intégrations actives</h3>
<table>
<thead>
<tr>
<th>Service</th>
<th>Config</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
<tr>
<td>Disqus</td>
<td>shortname: <code class="language-plaintext highlighter-rouge">fxrobin-github-io</code></td>
<td>✓ Actif</td>
</tr>
<tr>
<td>Google Analytics</td>
<td>UA-114271874-1</td>
<td>✓ Actif (Universal — obsolète)</td>
</tr>
<tr>
<td>Google Custom Search</td>
<td>cx=011993730579911903160:17ronej8jdw</td>
<td>✓ Actif</td>
</tr>
<tr>
<td>Mermaid.js</td>
<td>opt-in via <code class="language-plaintext highlighter-rouge">page.mermaid: true</code></td>
<td>✓ Disponible, <strong>0 posts l’utilisent</strong></td>
</tr>
<tr>
<td>Asciinema</td>
<td>opt-in via include</td>
<td>✓ Disponible, <strong>0 posts l’utilisent</strong></td>
</tr>
</tbody>
</table>
<hr />
<h2 id="5-qualité-et-problèmes-détectés">5. Qualité et Problèmes Détectés</h2>
<h3 id="51-problème-critique--logos-manquants">5.1 Problème critique — Logos manquants</h3>
<p><strong>21 fichiers logo référencés dans le front matter mais absents de <code class="language-plaintext highlighter-rouge">/images/logos/</code>.</strong></p>
<p>Impact : 48% des posts affichent une image cassée.<br />
Exemples : <code class="language-plaintext highlighter-rouge">api-preconditions.png</code>, <code class="language-plaintext highlighter-rouge">archiva-rpi.png</code>, <code class="language-plaintext highlighter-rouge">code.png</code> (mais <code class="language-plaintext highlighter-rouge">code.jpg</code> existe).</p>
<p><strong>Action : Audit exhaustif <code class="language-plaintext highlighter-rouge">images/logos/</code> vs tous les champs <code class="language-plaintext highlighter-rouge">logo:</code> des posts.</strong></p>
<h3 id="52-problèmes-importants">5.2 Problèmes importants</h3>
<table>
<thead>
<tr>
<th>Problème</th>
<th>Impact</th>
<th>Recommandation</th>
</tr>
</thead>
<tbody>
<tr>
<td>Gaps de publication (2 ans)</td>
<td>Audience / SEO</td>
<td>Cadence éditoriale fixe</td>
</tr>
<tr>
<td>Google Analytics Universal (UA)</td>
<td>Tracking perdu — UA retraité</td>
<td>Migrer vers GA4</td>
</tr>
<tr>
<td>Vue.js 2.5.16 inclus sans usage visible</td>
<td>Poids inutile</td>
<td>Vérifier / supprimer</td>
</tr>
<tr>
<td>CSS non-minifié (<code class="language-plaintext highlighter-rouge">style: :expanded</code>)</td>
<td>Performance</td>
<td>Passer à <code class="language-plaintext highlighter-rouge">:compressed</code></td>
</tr>
<tr>
<td>Couverture EN à 18%</td>
<td>Audience internationale</td>
<td>Traduire 10–15 articles clés</td>
</tr>
<tr>
<td>Mermaid / Asciinema inutilisés</td>
<td>Fonctionnalités inexploitées</td>
<td>Les utiliser dans les prochains articles</td>
</tr>
</tbody>
</table>
<h3 id="53-améliorations-mineures">5.3 Améliorations mineures</h3>
<table>
<thead>
<tr>
<th>Problème</th>
<th>Recommandation</th>
</tr>
</thead>
<tbody>
<tr>
<td>73 tags sans casse uniforme (“java” vs “Java”)</td>
<td>Guide de style tags</td>
</tr>
<tr>
<td>25% des posts sans <code class="language-plaintext highlighter-rouge"><!--excerpt--></code></td>
<td>Ajouter sur les anciens posts clés</td>
</tr>
<tr>
<td>Dépendances front-end figées sur vieilles versions</td>
<td>Auditer + mettre à jour (FA 4→6, TypewriterJS)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">jekyll-feed</code> commenté (RSS désactivé)</td>
<td>Considérer activation (audience RSS)</td>
</tr>
<tr>
<td>Pas de <code class="language-plaintext highlighter-rouge">robots.txt</code> explicite</td>
<td>Créer fichier minimal</td>
</tr>
<tr>
<td>Pas de JSON-LD</td>
<td>Ajouter schema <code class="language-plaintext highlighter-rouge">BlogPosting</code> pour rich snippets</td>
</tr>
</tbody>
</table>
<h3 id="54-drafts--action-éditoriale">5.4 Drafts — action éditoriale</h3>
<table>
<thead>
<tr>
<th>Draft</th>
<th>Recommandation</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">questions-poo.md</code> (13.2 KB)</td>
<td>Finaliser et publier</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">virtual-threads-loom/</code></td>
<td>Sujet très actuel (Java 21+), prioritaire</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">uuid-versions-jmh/</code></td>
<td>JMH = différenciateur technique, prioritaire</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">vertx-eventbus-quarkus/</code></td>
<td>Bon sujet Quarkus ecosystem</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">angular8-javaee.md</code></td>
<td>Abandonner (Angular 8 = daté)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">choisir-js-angular-react-vue-webcomponents.md</code></td>
<td>Abandonner ou réécrire 2026</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">cdi-payara-arquillian-deltaspike.md</code></td>
<td>Abandonner</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="6-métriques-de-synthèse">6. Métriques de synthèse</h2>
<table>
<thead>
<tr>
<th>Métrique</th>
<th>Valeur</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
<tr>
<td>Posts publiés</td>
<td>44</td>
<td>✓</td>
</tr>
<tr>
<td>Posts FR</td>
<td>36 (81%)</td>
<td>✓</td>
</tr>
<tr>
<td>Posts EN</td>
<td>8 (18%)</td>
<td>⚠ Faible</td>
</tr>
<tr>
<td>Paires bilingues</td>
<td>8</td>
<td>✓</td>
</tr>
<tr>
<td>Drafts .md</td>
<td>9</td>
<td>⚠ À trier</td>
</tr>
<tr>
<td>Répertoires en cours</td>
<td>7</td>
<td>⚠ Prioritiser</td>
</tr>
<tr>
<td>Front matter complet (requis)</td>
<td>100%</td>
<td>✓</td>
</tr>
<tr>
<td>Logos référencés vs présents</td>
<td>52%</td>
<td>✗ Critique</td>
</tr>
<tr>
<td>Excerpt marqué</td>
<td>75%</td>
<td>✓</td>
</tr>
<tr>
<td>Tags uniques</td>
<td>73</td>
<td>✓</td>
</tr>
<tr>
<td>Layouts</td>
<td>7</td>
<td>✓</td>
</tr>
<tr>
<td>Includes</td>
<td>25</td>
<td>✓</td>
</tr>
<tr>
<td>Modules SCSS</td>
<td>26</td>
<td>✓</td>
</tr>
<tr>
<td>Plugins Jekyll</td>
<td>3</td>
<td>✓</td>
</tr>
<tr>
<td>Intégrations tierces</td>
<td>5</td>
<td>✓</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="7-recommandations-prioritaires">7. Recommandations prioritaires</h2>
<h3 id="priorité-1--critique">Priorité 1 — Critique</h3>
<ol>
<li><strong>Réparer les logos manquants</strong> (21 fichiers) — impact visuel direct sur 48% des posts</li>
</ol>
<h3 id="priorité-2--important">Priorité 2 — Important</h3>
<ol>
<li><strong>Migrer Google Analytics UA → GA4</strong> — UA est retraité, les données sont perdues</li>
<li><strong>Établir une cadence de publication</strong> — 1 article/mois minimum pour éviter les gaps</li>
<li><strong>Publier les drafts prioritaires</strong> : <code class="language-plaintext highlighter-rouge">virtual-threads-loom</code>, <code class="language-plaintext highlighter-rouge">uuid-versions-jmh</code>, <code class="language-plaintext highlighter-rouge">questions-poo.md</code></li>
<li><strong>Supprimer ou mettre à jour Vue.js</strong> — v2.5.16 inclus systématiquement, usage non vérifié</li>
</ol>
<h3 id="priorité-3--amélioration">Priorité 3 — Amélioration</h3>
<ol>
<li><strong>Activer la minification CSS</strong> : <code class="language-plaintext highlighter-rouge">style: :compressed</code> dans <code class="language-plaintext highlighter-rouge">_config.yml</code></li>
<li><strong>Ajouter <code class="language-plaintext highlighter-rouge">robots.txt</code></strong> explicite</li>
<li><strong>Ajouter JSON-LD</strong> <code class="language-plaintext highlighter-rouge">BlogPosting</code> pour les rich snippets Google</li>
<li><strong>Uniformiser les tags</strong> (casse, singulier/pluriel)</li>
<li><strong>Utiliser Mermaid.js et Asciinema</strong> dans les prochains articles techniques</li>
</ol>
<hr />
<p><em>Généré par Claude Code — avril 2026</em></p>
</div>
<aside class="toc-sidebar">
<div class="sidebar-section-title">CONTENTS</div>
<ul class="toc-list">
<li><a href="#résumé-exécutif">Résumé Exécutif</a></li>
<li><a href="#1-contenu">1. Contenu</a>
<ul>
<li><a href="#11-volume-et-distribution">1.1 Volume et distribution</a></li>
<li><a href="#12-timeline-de-publication">1.2 Timeline de publication</a></li>
<li><a href="#13-thématiques-et-tags">1.3 Thématiques et tags</a></li>
<li><a href="#14-qualité-des-front-matter">1.4 Qualité des front matter</a></li>
<li><a href="#15-brouillons-_drafts">1.5 Brouillons (_drafts/)</a></li>
</ul>
</li>
<li><a href="#2-technologies">2. Technologies</a>
<ul>
<li><a href="#21-jekyll">2.1 Jekyll</a></li>
<li><a href="#22-cicd">2.2 CI/CD</a></li>
<li><a href="#23-frontend">2.3 Frontend</a></li>
<li><a href="#24-sass--css">2.4 Sass / CSS</a></li>
<li><a href="#25-layouts-et-includes">2.5 Layouts et Includes</a></li>
</ul>
</li>
<li><a href="#3-architecture">3. Architecture</a>
<ul>
<li><a href="#31-structure-répertoires">3.1 Structure répertoires</a></li>
<li><a href="#32-convention-de-nommage-des-posts">3.2 Convention de nommage des posts</a></li>
<li><a href="#33-système-multilingue">3.3 Système multilingue</a></li>
<li><a href="#34-stratégie-permalink">3.4 Stratégie permalink</a></li>
</ul>
</li>
<li><a href="#4-seo-et-intégrations-tierces">4. SEO et Intégrations tierces</a>
<ul>
<li><a href="#41-seo">4.1 SEO</a></li>
<li><a href="#42-intégrations-actives">4.2 Intégrations actives</a></li>
</ul>
</li>
<li><a href="#5-qualité-et-problèmes-détectés">5. Qualité et Problèmes Détectés</a>
<ul>
<li><a href="#51-problème-critique--logos-manquants">5.1 Problème critique — Logos manquants</a></li>
<li><a href="#52-problèmes-importants">5.2 Problèmes importants</a></li>
<li><a href="#53-améliorations-mineures">5.3 Améliorations mineures</a></li>
<li><a href="#54-drafts--action-éditoriale">5.4 Drafts — action éditoriale</a></li>
</ul>
</li>
<li><a href="#6-métriques-de-synthèse">6. Métriques de synthèse</a></li>
<li><a href="#7-recommandations-prioritaires">7. Recommandations prioritaires</a>
<ul>
<li><a href="#priorité-1--critique">Priorité 1 — Critique</a></li>
<li><a href="#priorité-2--important">Priorité 2 — Important</a></li>
<li><a href="#priorité-3--amélioration">Priorité 3 — Amélioration</a></li>
</ul>
</li>
</ul>
<hr class="sidebar-divider">
<div class="sidebar-section-title">SHARE</div>
<div class="sidebar-share">
<a href="https://github.com/fxrobin" target="_blank" rel="nofollow">[gh]</a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https://www.fxjavadevblog.fr/analyse-repo/&title=Audit du Repository — FX JavaDevBlog" target="_blank" rel="nofollow">[li]</a>
<a href="https://twitter.com/intent/tweet?text=Audit du Repository — FX JavaDevBlog&url=https://www.fxjavadevblog.fr/analyse-repo/" target="_blank" rel="nofollow">[tw]</a>
</div>
</aside>
</div>
</article>
<div class="disqus">
<h2></h2>
<div class="comments">
<div id="disqus_thread"></div>
<script type="text/javascript">
var disqus_shortname = 'fxrobin-github-io';
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</div>
</main>
</div>
- Step 3: Create
_includes/sidebar-nav.html
<nav class="sidebar-nav-list">
</nav>
- Step 4: Update
style.scss— replace#left/#rightwith new layout vars
In style.scss, replace the existing #left, #right, and .container blocks with:
.container {
margin: 0 auto;
max-width: 1800px;
width: 100%;
}
And remove the #left and #right blocks entirely. Add @import "sidebar"; near the top imports (after @import "header";).
- Step 5: Verify split-pane renders
docker run --rm -p 4000:4000 -v $(pwd):/srv/jekyll \
jekyll/builder:latest jekyll serve --future --livereload
Open http://localhost:4000 — verify:
- Sidebar visible on left, ~220px wide, amber text
- Content area takes remaining width
$ ls /dev/prompt visible in sidebar-
Sidebar has right border in dark gray
- Step 6: Commit
git add _sass/_sidebar.scss _layouts/default.html _includes/sidebar-nav.html style.scss
git commit -m "style: add split-pane sidebar layout — 220px amber chrome left, content right"
Task 5: Navigation + Config Labels
Files:
- Rewrite:
_sass/_nav.scss -
Modify:
_config.yml(nav text labels) - Step 1: Rewrite
_sass/_nav.scss
.sidebar-nav-list {
display: flex;
flex-direction: column;
gap: 0.1rem;
}
.sidebar-nav-item {
font-family: $mono;
font-size: 0.85rem;
color: $amber-dim;
padding: 0.25rem 0.3rem;
display: block;
transition: color 0.15s;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
&::before { content: ' '; }
&:visited { color: $amber-dim; }
&:hover {
color: $amber;
text-shadow: 0 0 6px $amber;
&::before { content: '> '; }
}
&.active {
color: $amber;
text-shadow: 0 0 8px $amber;
&::before { content: '> '; }
&::after {
content: ' █';
animation: blink-cursor 1s step-end infinite;
}
}
}
@keyframes blink-cursor {
50% { opacity: 0; }
}
- Step 2: Update nav labels in
_config.yml
In _config.yml, update the menu: section for both fr: and en::
For fr::
menu:
articles:
url: "/"
text: "/dev/java"
retro-programming:
url: "/retro-programming/"
text: "/dev/retro"
blanka:
url: "/blanka-cave/fr/"
text: "/dev/blanka"
about:
url: "/about/"
text: "/dev/about"
For en::
menu:
articles:
url: "/"
text: "/dev/java"
retro-programming:
url: "/retro-programming/"
text: "/dev/retro"
blanka:
url: "/blanka-cave/en/"
text: "/dev/blanka"
about:
url: "/about/"
text: "/dev/about"
Note: tips (astuces) and links entries removed — content merged/dropped per spec.
- Step 3: Verify nav renders correctly
docker run --rm -p 4000:4000 -v $(pwd):/srv/jekyll \
jekyll/builder:latest jekyll serve --future --livereload
Open http://localhost:4000 — verify:
- Sidebar shows
/dev/java,/dev/retro,/dev/blanka,/dev/about - Active item has
>prefix and blinking█ - Hover shows
>prefix, amber glow -
Inactive items are amber-dim
- Step 4: Commit
git add _sass/_nav.scss _config.yml
git commit -m "style: terminal directory nav — /dev/* labels, active cursor blink"
Task 6: Search Input
Files:
- Modify:
_includes/search.html -
Modify:
_sass/_search.scss - Step 1: Update
_includes/search.html
Replace the entire file content with:
<div class="sidebar-search">
<label class="sidebar-section-title" for="search-input">$ grep -r</label>
<div class="search-prompt">
<span class="search-prefix">"</span>
<input id="search-input"
type="text"
class="search-input"
placeholder=""
autocomplete="off" />
<span class="search-suffix">"</span>
</div>
<div id="search-results" class="search-results"></div>
</div>
- Step 2: Rewrite
_sass/_search.scss
.sidebar-search {
.search-prompt {
display: flex;
align-items: center;
gap: 0.2rem;
font-family: $mono;
color: $amber;
font-size: 0.85rem;
margin-top: 0.4rem;
}
.search-prefix,
.search-suffix {
color: $amber-dim;
user-select: none;
}
.search-input {
background: transparent;
border: none;
border-bottom: 1px solid $amber-dim;
color: $amber;
font-family: $mono;
font-size: 0.85rem;
outline: none;
padding: 0.1rem 0.2rem;
width: 100%;
caret-color: $amber;
&::placeholder { color: $amber-dim; opacity: 0.6; }
&:focus { border-bottom-color: $amber; }
}
.search-results {
margin-top: 0.5rem;
font-family: $mono;
font-size: 0.75rem;
a {
display: block;
color: $amber-dim;
padding: 0.15rem 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&:hover { color: $amber; }
&::before { content: ' ↳ '; }
}
}
}
- Step 3: Verify search renders
Open http://localhost:4000 — sidebar search area shows:
$ grep -rlabel"___________"style input with amber underline only (no box)-
Placeholder in amber-dim
- Step 4: Commit
git add _includes/search.html _sass/_search.scss
git commit -m "style: terminal-style search — grep prompt, amber underline input"
Task 7: Article Cards
Files:
- Create:
_sass/_cards.scss - Modify:
_includes/full-index-page.html -
Modify:
style.scss(add@import "cards", remove@import "front-post") - Step 1: Create
_sass/_cards.scss
.posts-grid {
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.post-card {
border: 1px solid #444444;
background: $bg-card;
font-family: $mono;
transition: border-color 0.1s;
&:hover { border-color: #666666; }
.card-header {
display: flex;
justify-content: space-between;
align-items: baseline;
padding: 0.5rem 0.75rem 0.4rem;
border-bottom: 1px solid #333;
.card-path {
color: $amber;
font-size: 0.85rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.card-date {
color: $amber-dim;
font-size: 0.75rem;
flex-shrink: 0;
margin-left: 1rem;
}
}
.card-body {
padding: 0.6rem 0.75rem;
.card-title {
font-family: $helvetica;
font-size: 1.1rem;
font-weight: 600;
color: $body-text;
margin: 0 0 0.3rem;
a {
color: $body-text;
&:hover { color: $amber; }
&:visited { color: $body-text; }
}
}
.card-excerpt {
font-family: $helvetica;
font-size: 0.88rem;
color: #AAAAAA;
margin: 0;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
}
.card-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.4rem 0.75rem;
border-top: 1px solid #333;
.card-tags {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
.tag {
color: $amber-dim;
font-size: 0.75rem;
&::before { content: '#'; }
&:hover { color: $amber; }
&:visited { color: $amber-dim; }
}
}
.card-read-more {
color: $amber;
font-size: 0.78rem;
border: 1px solid $amber-dim;
padding: 0.15rem 0.5rem;
white-space: nowrap;
transition: background 0.1s, color 0.1s;
&::before { content: '▶ '; }
&:visited { color: $amber; }
&:hover {
background: $amber;
color: $bg-body;
border-color: $amber;
text-shadow: none;
}
}
}
}
.pagination {
display: flex;
align-items: center;
gap: 1rem;
justify-content: center;
margin-top: 2rem;
font-family: $mono;
font-size: 0.85rem;
a, span {
color: $amber-dim;
padding: 0.2rem 0.5rem;
border: 1px solid $border;
}
a {
&:hover { color: $amber; border-color: $amber; }
&:visited { color: $amber-dim; }
}
.page-info { color: $amber-dim; border: none; }
}
- Step 2: Rewrite
_includes/full-index-page.html
<div class="posts-grid">
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/primitive-obsession</span>
<span class="card-date">
2026-04-05
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/primitive-obsession/">L'Obsession des Primitives</a></h2>
<p class="card-excerpt">
// Rien n'empêche d'appeler ça à l'envers. Le compilateur ne dit rien.
public User createUser(String firstName, String lastName, String email, String phone) { /*...*/ }
Voilà le genre de code qu’on écrit depuis des années sans se poser de questions. Et pourtant il y a un bug potentiel dans chaque appel : l’ordre des paramètres. Mais il y a pire : ces quatre String ne représentent pas la même chose. Un prénom, un nom de famille, un email, un numéro de téléphone : ce sont des concepts métier distincts, avec leurs propres règles de validation, leurs propres contraintes. Et vous les représentez tous avec le même type.
C’est le code smell qu’on appelle Primitive Obsession. Et depuis Java 16, on n’a plus d’excuse pour le laisser traîner.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/records/" class="tag">Records</a>
<a href="/tag/craftsmanship/" class="tag">Craftsmanship</a>
<a href="/tag/clean-code/" class="tag">Clean Code</a>
</div>
<a href="/primitive-obsession/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/primitive-obsession-en</span>
<span class="card-date">
2026-04-05
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/primitive-obsession-en/">Primitive Obsession</a></h2>
<p class="card-excerpt">
// Nothing prevents calling this in reverse order. The compiler says nothing.
public User createUser(String firstName, String lastName, String email, String phone) { /*...*/ }
This is the kind of code we’ve been writing for years without questioning it. And yet there’s a potential bug in every single call: the parameter order. But there’s worse: these four String values don’t represent the same thing. A first name, a last name, an email address, a phone number — these are distinct business concepts, each with their own validation rules and constraints. And you’re representing all of them with the same type.
This is the code smell known as Primitive Obsession. And since Java 16, we have no excuse for letting it linger.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/records/" class="tag">Records</a>
<a href="/tag/craftsmanship/" class="tag">Craftsmanship</a>
<a href="/tag/clean-code/" class="tag">Clean Code</a>
</div>
<a href="/primitive-obsession-en/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/eclipse-collections</span>
<span class="card-date">
2026-04-03
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/eclipse-collections/">Eclipse Collections : l'API Collections que vous ne connaissez pas (encore)</a></h2>
<p class="card-excerpt">
Tout le monde connait (ou doit connaitre) les API Collections offertes par le JDK et notamment les interfaces de haut niveau : Collection, Map et très certainement les interfaces spécialisées comme List ou Set.
Bien qu’ayant subi un léger lifting lors du passage à Java 8, notamment grâce à (ou à cause de) la Stream API, cette API historique souffre toujours de divers manques et d’une verbosité parfois pénible.
Il n’est donc pas rare de voir Guava ou Apache Commons Collections ajoutées aux dépendances d’un projet, chacune avec ses inconvénients : Guava embarque tout (y compris ce qu’on ne veut pas), et Apache Commons Collections ne supporte pas les lambdas, ayant été conçue avant Java 8.
Je vais donc vous présenter Eclipse Collections, une API légère, performante et vraiment efficace qui gagne à être connue. Et je vais vous montrer concrètement pourquoi, une fois qu’on y a goûté, on ne revient pas en arrière.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/collections/" class="tag">Collections</a>
<a href="/tag/functional/" class="tag">Functional</a>
<a href="/tag/lambda/" class="tag">Lambda</a>
</div>
<a href="/eclipse-collections/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/eclipse-collections-en</span>
<span class="card-date">
2026-04-03
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/eclipse-collections-en/">Eclipse Collections: the Collections API you don't know (yet)</a></h2>
<p class="card-excerpt">
Everyone knows (or should know) the Collections API provided by the JDK, especially the high-level interfaces: Collection, Map, and certainly the specialized ones like List or Set.
Although it received a slight facelift with Java 8, mostly thanks to (or because of) the Stream API, this historical API still suffers from various gaps and an sometimes painful verbosity.
It is therefore quite common to see Guava or Apache Commons Collections added to a project’s dependencies, each with their own drawbacks: Guava brings everything along (including what you don’t need), and Apache Commons Collections does not support lambdas, having been designed before Java 8.
So I’m going to present Eclipse Collections, a lightweight, performant and really effective API that deserves to be better known. And I’ll show you concretely why, once you get a taste of it, you don’t go back.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/collections/" class="tag">Collections</a>
<a href="/tag/functional/" class="tag">Functional</a>
<a href="/tag/lambda/" class="tag">Lambda</a>
</div>
<a href="/eclipse-collections-en/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/generer-executables-java-avec-maven</span>
<span class="card-date">
2022-12-12
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/generer-executables-java-avec-maven/">Java: Générer des exécutables Windows, Linux et MacOS</a></h2>
<p class="card-excerpt">
Si comme moi tu en as assez de faire des programmes types “ligne de commande” en Java et d’être
obligé de les lancer avec ce genre de choses :
$ java -jar demo-app-v1.0.0-SNAPSHOT.jar arg1 arg2 arg3`
Ce petit article devrait te plaire.
Tu pourras alors faire directement ça :
$ ./demo-app arg1 arg2 arg3
Appétissant !
Dans ce petit tutoriel, je vais donc générer un exécutable :
pour Linux et MacOSX,
pour Windows, un .EXE,
sous forme de Runnable JAR, classique.
Cela nécessite toutefois la présence d’un Runtime JAVA (JRE et/ou JDK) sur la machine qui l’exécutera, bien qu’il existe aussi des solutions pour embarquer un JRE.
Les solutions, que je vais décrire, n’utilisent pas GRAALVM et sa compilation native.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/maven/" class="tag">Maven</a>
<a href="/tag/build/" class="tag">Build</a>
</div>
<a href="/generer-executables-java-avec-maven/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/how-to-generate-java-executables-with-maven</span>
<span class="card-date">
2022-12-12
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/how-to-generate-java-executables-with-maven/">Java: How to generate Windows, Linux and MacOS executables?</a></h2>
<p class="card-excerpt">
If, like me, you are tired of making command line programs in Java and having to run them with this kind of things:
$ java -jar demo-app-v1.0.0-SNAPSHOT.jar arg1 arg2 arg3`
This little article should please you.
You will then be able to do this directly:
$ ./demo-app arg1 arg2 arg3
Appetizing!
In this little tutorial, I will generate an executable file :
for Linux and MacOSX,
for Windows, an .EXE,
as a classic Runnable JAR.
However, this requires the presence of a JAVA Runtime (JRE and/or JDK) on the machine that will run it, although there are also solutions to embed a JRE.
The solutions I will describe do not use GRAALVM and its native compilation.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/maven/" class="tag">Maven</a>
<a href="/tag/build/" class="tag">Build</a>
</div>
<a href="/how-to-generate-java-executables-with-maven/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/quarkus-jpa-graalvm</span>
<span class="card-date">
2020-04-16
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/quarkus-jpa-graalvm/">REST API avec Quarkus, JPA, PostGreSQL et GraalVM</a></h2>
<p class="card-excerpt">
Ce tutoriel Quarkus-JPA-PostgreSQL met en oeuvre :
une API Rest partielle (GET) avec JAX-RS et Quarkus sur une source de données JPA
des tests unitaires
des tests d’intégration au niveau API (http) avec un PostGreSQL lancé par un plugin maven Docker
une distribution native, compilée avec GraalVM et une image docker de l’application compilée
Réalisé sous Linux Mint 19 mais devrait convenir à de nombreuses distributions, voire à Windows.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/quarkus/" class="tag">Quarkus</a>
<a href="/tag/jax-rs/" class="tag">JAX-RS</a>
<a href="/tag/rest/" class="tag">REST</a>
</div>
<a href="/quarkus-jpa-graalvm/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/functional-switch</span>
<span class="card-date">
2020-02-26
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/functional-switch">Functional Switch/Case en Java 8 et +</a></h2>
<p class="card-excerpt">
Java 12 est sorti le 20/03/19, apportant une nouvelle façon d’écrire des structures de contrôle switch/case.
Cela m’a donné une idée, certes un peu étrange, de revoir le traditionnel switch/case d’un point de vue
programmation fonctionnelle en s’appuyant sur des lambdas et une petite classe Switch, le tout en JAVA 8 !
Attention toutefois, il est certain que cette approche est beaucoup moins performante qu’un switch/case classique,
mais je ne renonce pas à la beauté du geste.
Versions de cet article :
04/10/2019 : première publication.
26/02/2020 : suite à idée judicieuse postée sur les forums “developpez.com”, voir la partie “Let’s go further …”
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/lambda/" class="tag">Lambda</a>
<a href="/tag/functional/" class="tag">Functional</a>
<a href="/tag/patterns/" class="tag">Patterns</a>
</div>
<a href="/functional-switch" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/functional-switch-en</span>
<span class="card-date">
2020-02-26
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/functional-switch-en/">Functional Switch/Case with Java 8+</a></h2>
<p class="card-excerpt">
Java 12 was released on 20/03/19, bringing a new way to write switch/case control structures.
This gave me an idea, admittedly a bit strange, to revisit the traditional switch/case from a
functional programming point of view by using lambdas and a small Switch class, all in JAVA 8!
Be careful though, it is certain that this approach is much less efficient than a classic switch/case,
but I don’t give up the beauty of the gesture.
Versions of this article:
04/10/2019: first publication.
26/02/2020 : following a judicious idea posted on “developpez.com” forums, see the “Let’s go further …” part.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/lambda/" class="tag">Lambda</a>
<a href="/tag/functional/" class="tag">Functional</a>
<a href="/tag/patterns/" class="tag">Patterns</a>
</div>
<a href="/functional-switch-en/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/Singleton-Est-Mort-Vive-Singleton</span>
<span class="card-date">
2018-08-06
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/Singleton-Est-Mort-Vive-Singleton/">Le singleton est mort, vive le singleton !</a></h2>
<p class="card-excerpt">
Version 1 parue le 16/12/2017
Version 2 parue le 06/08/2018 : accès concurrents, PermGen / Meta spaces, Holder interne
L’objectif de ce billet est de présenter une implémentation simple en Java du pattern Singleton.
Je ne traiterai donc pas de l’utilité ni des recommandations d’usage liées à celui-ci mais bien de mise en oeuvre (codage pour les intimes) en Java Standard Edition (JSE).
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/patterns/" class="tag">Patterns</a>
<a href="/tag/jvm/" class="tag">JVM</a>
<a href="/tag/craftsmanship/" class="tag">Craftsmanship</a>
</div>
<a href="/Singleton-Est-Mort-Vive-Singleton/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/cdi-deltaspike-junit5</span>
<span class="card-date">
2018-06-21
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/cdi-deltaspike-junit5/">Découverte de Deltaspike Data Module</a></h2>
<p class="card-excerpt">
Cet article va vous permettre de découvrir Deltaspike Data Module, une alternative à Spring Data dans le monde CDI et dans notre cas en CDI 2.0.
Cette accroche est parlante pour ceux qui connaissent Spring Data mais peut-être pas pour les autres : Deltaspike Data va permettre d’avoir très simplement une fonctionnalité de CRUD (Create, Read, Update, Delete) sur des entités JPA et bien plus encore en vous faisant économiser énormément de temps de développement et de bugs potentiels !
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/cdi/" class="tag">CDI</a>
<a href="/tag/junit/" class="tag">JUnit</a>
<a href="/tag/jpa/" class="tag">JPA</a>
</div>
<a href="/cdi-deltaspike-junit5/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/api-preconditions</span>
<span class="card-date">
2018-06-02
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/api-preconditions/">Préconditions des méthodes d'une API</a></h2>
<p class="card-excerpt">
Comme tout système s’appuyant sur des inputs, il est très important de contrôler les arguments des méthodes quand on élabore une API, qu’elle soit locale sous forme de JAR ou distante via un service REST, afin de non seulement la rendre plus robuste et stable mais aussi de se prémunir de certaines attaques.
Cependant, en Java de base, c’est particulièrement laborieux, rébarbatif et cela engendre une fainéantise exacerbée. Conséquences directes et désastreuses : baisse de la qualité, de la robustesse du code et créations potentielles de failles de sécurité.
Cet article tente de faire le tour de la question, sans prétention, en ratissant assez large. C’est à dire en
allant de Java classique jusqu’à Bean Validation et JAX-RS, en passant par une implémentation spécifique “Faite Maison”.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/clean-code/" class="tag">Clean Code</a>
<a href="/tag/jax-rs/" class="tag">JAX-RS</a>
<a href="/tag/rest/" class="tag">REST</a>
</div>
<a href="/api-preconditions/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/jshell-http-server</span>
<span class="card-date">
2018-04-23
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/jshell-http-server/">Serveur minimal HTTP avec JShell en Java_10</a></h2>
<p class="card-excerpt">
NodeJS se targue de pouvoir monter en quelques lignes
de code un simple serveur HTTP. Effectivement, créer ce genre de serveur est vraiment simple et particulièrement
utile pour du déploiement dans le Cloud.
Et Java dans tout ça ? A la traîne ? Has-Been ?
“Si à 50 ans t’as pas de Rolex et/ou si tu sais pas faire de TypeScript, t’as raté ta vie !”
Fort heureusement, je vais vous montrer qu’avec JShell, apparu avec Java 9, en 10 lignes de code environ,
vous obtiendrez un serveur HTTP Asynchrone, performant, en ayant à portée de main tout ce que vous offre Java 10,
ses modules, ainsi qu’historiquement, toutes les bibliothèques JAR de son écosystème !
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/jshell/" class="tag">JShell</a>
</div>
<a href="/jshell-http-server/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/Archiva-Raspberry</span>
<span class="card-date">
2018-04-14
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/Archiva-Raspberry/">Apache Archiva sur Raspberry PI</a></h2>
<p class="card-excerpt">
“Il me faut un repo Maven dédié !”. Voilà ce qui m’est venu en tête quand j’ai dû changer
de machine récemment alors que tous les artefacts maven que je produisais étaient capitalisés dans le .m2/repository de mon home. Autant dire “Pas capitalisés”.
Bien sûr, j’utilise un repo Nexus au boulot mais je change d’activité et je vais devenir plus mobile, il me faut donc une solution.
J’aurais pu prendre une image Docker et la déployer sur AWS ou équivalent : la solution de facilité qui demande toutefois un peu de “ressource” financière.
Et je le vois, là, rose, toutes diodes allumées, connecté à ma box, servant de proxy Squid de temps en temps.
Mon Raspberry PI 1, je l’entends encore me dire “Moi je peux, moi je peux, moi je peux !” en trépignant dans son joli boitier.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/open-source/" class="tag">Open Source</a>
<a href="/tag/maven/" class="tag">Maven</a>
<a href="/tag/raspberry/" class="tag">Raspberry</a>
</div>
<a href="/Archiva-Raspberry/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/Contribuer-Eclipse-Foundation-Done</span>
<span class="card-date">
2018-04-02
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/Contribuer-Eclipse-Foundation-Done/">Contribuer à l'Eclipse Foundation : DONE</a></h2>
<p class="card-excerpt">
Comme tout bon développeur Java, je suis un gros consommateur des solutions fournies par l’Eclipse Foundation.
Je ne vais en citer que quelques-unes : Eclipse IDE, EclipseLink, Eclipse GlassFish, Jetty, Eclipse EGit, Eclipse Maven Integration, etc.
Il était donc temps, au lieu d’attendre en ronchonnant qu’un patch ne soit développé, de contribuer en fournissant un correctif à un projet.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/open-source/" class="tag">Open Source</a>
<a href="/tag/eclipse/" class="tag">Eclipse</a>
<a href="/tag/glassfish/" class="tag">GlassFish</a>
</div>
<a href="/Contribuer-Eclipse-Foundation-Done/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/construction-instance-java</span>
<span class="card-date">
2018-03-16
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/construction-instance-java/">Connaissez-vous bien l'instanciation ?</a></h2>
<p class="card-excerpt">
Ce court billet va vous présenter quelles instructions sont exécutées dans vos
classes Java, lorsque que vous en réclamez une instance.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
</div>
<a href="/construction-instance-java/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/Xenon-Reborn</span>
<span class="card-date">
2018-03-14
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/Xenon-Reborn/">Xenon Reborn, développer en s'amusant et réciproquement</a></h2>
<p class="card-excerpt">
Dans mon parcours professionnel, j’ai été formateur de jeunes développeurs pendant sept années.
Ces derniers venaient d’horizons différents, parfois sans aucune compétence en terme de programmation.
Afin de rendre ludique l’apprentissage des fondamentaux de l’algorithmique et de Java, je les ai fait participer à la création d’un jeu video : Xenon Reborn, inspiré du célèbre jeu Xenon des Bitmap Brothers.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/libgdx/" class="tag">LibGDX</a>
</div>
<a href="/Xenon-Reborn/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/Enum-JPA-Named-Query</span>
<span class="card-date">
2018-03-12
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/Enum-JPA-Named-Query/">Où définir au mieux une NamedQuery JPA ?</a></h2>
<p class="card-excerpt">
Je vais vous présenter succinctement les deux façons
natives en JPA pour déclarer des NamedQuery.
On verra alors que ces deux solutions ont des défauts et je vous proposerai alors une 3ème qui me paraît plus satisfaisante, fondée sur une “enum”.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/jpa/" class="tag">JPA</a>
</div>
<a href="/Enum-JPA-Named-Query/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/Lombok-Yes-But</span>
<span class="card-date">
2018-03-05
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/Lombok-Yes-But/">Lombok, YES! But ...</a></h2>
<p class="card-excerpt">
I will present in this post the Lombok library which I’m currently using for quite every development in Java. After 4 years dealing with it, I wish I could share some experience and give some advice.
As an excerpt, here is my best : don’t use @Data but you’ll need to be patient and to read the conclusion to know why.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/lombok/" class="tag">Lombok</a>
<a href="/tag/patterns/" class="tag">Patterns</a>
</div>
<a href="/Lombok-Yes-But/" class="card-read-more">
</a>
</div>
</article>
<article class="post-card">
<div class="card-header">
<span class="card-path">/dev/java/Lombok-Oui-Mais</span>
<span class="card-date">
2018-03-05
</span>
</div>
<div class="card-body">
<h2 class="card-title"><a href="/Lombok-Oui-Mais/">Lombok, Oui ! Mais...</a></h2>
<p class="card-excerpt">
Dans ce billet, je vais présenter la bibliothèque Lombok dont je ne peux plus me passer pour mes développements Java. Cela fait maintenant plus de 4 ans que je l’utilise et tout n’est pas rose. Ce sera donc l’occasion de partager aussi certaines recommandations.
J’en donne une : n’utilisez pas @Data et je vais vous expliquer pourquoi. Un peu de patience.
</p>
</div>
<div class="card-footer">
<div class="card-tags">
<a href="/tag/java/" class="tag">Java</a>
<a href="/tag/lombok/" class="tag">Lombok</a>
<a href="/tag/patterns/" class="tag">Patterns</a>
</div>
<a href="/Lombok-Oui-Mais/" class="card-read-more">
</a>
</div>
</article>
</div>
- Step 3: Update
style.scssimports
In style.scss:
- Add
@import "cards"; -
Remove
@import "front-post";(or leave_front-post.scssempty — it will be cleaned in Task 11) - Step 4: Verify cards render
Open http://localhost:4000 — verify:
- Each post is inside a dark box with thin border
- Top row shows amber path (
/dev/java/...) and amber-dim date - Title is readable white/gray Monda font
- Bottom row has
#tagtokens left,[▶ READ_MORE]right -
Hover on READ_MORE → amber background, black text
- Step 5: Commit
git add _sass/_cards.scss _includes/full-index-page.html style.scss
git commit -m "style: Unicode box article cards — path/date header, Monda title, tag footer"
Task 8: Article Page
Files:
- Create:
_sass/_article.scss - Rewrite:
_sass/_post.scss - Modify:
_layouts/post.html - Modify:
_includes/post-aside.html -
Modify:
style.scss(add@import "article") - Step 1: Create
_sass/_article.scss
.post-breadcrumb {
font-family: $mono;
font-size: 0.82rem;
color: $amber-dim;
margin-bottom: 1rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid $border;
&::after { content: ' $'; color: $amber; }
}
.post-header {
display: flex;
align-items: flex-start;
gap: 0.75rem;
margin-bottom: 1.5rem;
.post-logo {
width: 36px;
height: 36px;
object-fit: contain;
flex-shrink: 0;
}
.post-title-group {
flex: 1;
h1 {
font-family: $helvetica;
font-size: 1.8rem;
font-weight: 700;
color: $body-text;
margin: 0 0 0.25rem;
text-shadow: none;
}
.post-subtitle {
font-family: $mono;
font-size: 0.9rem;
color: $amber-dim;
font-style: italic;
margin: 0;
}
}
}
.post-meta {
font-family: $mono;
font-size: 0.8rem;
color: $amber-dim;
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1.5rem;
padding-bottom: 1rem;
border-bottom: 1px solid $border;
}
// Article body — switches to Monda for readability
.entry {
font-family: $helvetica;
color: $body-text;
line-height: 1.7;
p {
font-family: $helvetica;
color: $body-text;
margin: 1em 0;
padding-left: 0;
}
h2 {
font-family: $mono;
color: $amber;
font-size: 1.3rem;
margin-top: 1.8rem;
margin-bottom: 0.5rem;
border-bottom: 1px solid $border;
padding-bottom: 0.3rem;
text-shadow: 0 0 6px rgba($amber, 0.4);
&::before { content: '## '; color: $amber-dim; }
@include mobile { &::before { content: ''; } }
}
h3 {
font-family: $mono;
color: $body-text;
font-size: 1.1rem;
margin-top: 1.4rem;
&::before { content: '### '; color: $amber-dim; font-size: 0.9em; }
@include mobile { &::before { content: ''; } }
}
h4 {
font-family: $mono;
color: $amber-dim;
font-size: 1rem;
margin-top: 1.2rem;
}
blockquote {
border-left: 3px solid $amber;
margin: 1.5rem 0;
padding: 0.5rem 1rem;
color: #AAAAAA;
font-style: italic;
background: rgba($amber, 0.03);
}
strong, b {
color: $body-text;
border-bottom: 1px solid rgba($amber, 0.4);
}
a {
color: $link;
&:visited { color: $link-visited; }
&:hover { color: $amber; }
}
ul, ol {
font-family: $helvetica;
color: $body-text;
li { margin-bottom: 0.3rem; }
}
table {
width: 100%;
border-collapse: collapse;
margin: 1.5rem 0;
font-family: $mono;
font-size: 0.85rem;
th {
background: #1a1a1a;
color: $amber;
border: 1px solid $border;
padding: 0.5rem 0.75rem;
text-align: left;
}
td {
border: 1px solid $border;
padding: 0.4rem 0.75rem;
color: $body-text;
}
tr:nth-child(even) td { background: #0d0d0d; }
}
img { margin: 1rem auto; display: block; }
}
// TOC sidebar (article pages)
.toc-sidebar {
.sidebar-section-title {
margin-bottom: 0.5rem;
}
.toc-list {
list-style: none;
padding: 0;
margin: 0;
li { margin-bottom: 0.3rem; }
a {
font-family: $mono;
font-size: 0.78rem;
color: $amber-dim;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&::before { content: '§ '; }
&:hover { color: $amber; }
&:visited { color: $amber-dim; }
}
}
}
// Comments toggle
.comments-toggle {
font-family: $mono;
font-size: 0.85rem;
color: $amber;
background: transparent;
border: 1px solid $amber-dim;
padding: 0.3rem 0.75rem;
cursor: pointer;
margin-top: 2rem;
display: block;
width: 100%;
text-align: left;
transition: border-color 0.15s, color 0.15s;
&:hover { border-color: $amber; }
}
.comments-section { display: none; &.open { display: block; } }
- Step 2: Rewrite
_sass/_post.scss
.post {
margin-top: 1rem;
ul, ol { margin-left: 1em; }
.logo-in-page { display: none; } // replaced by .post-header .post-logo
.accroche { display: none; } // replaced by .post-subtitle in new header
.date { display: none; } // replaced by .post-meta
.metadata { display: none; } // replaced by .post-meta
}
- Step 3: Update
_layouts/post.html
Replace the entire file with:
---
layout: default
---
<article class="post">
<div class="post-breadcrumb">~/dev/java/2026-04-18-vt100-redesign</div>
<div class="post-header">
<div class="post-title-group">
<h1>VT-100 Hybrid Redesign Implementation Plan</h1>
</div>
</div>
<div class="post-meta">
<span class="date">
</span>
<span class="language-selector">
<span style="vertical-align: middle;"><a href="/primitive-obsession-en/"><img src="/images/flags/en.png" /></a></span>
<span style="vertical-align: middle;"><a href="/eclipse-collections-en/"><img src="/images/flags/en.png" /></a></span>
<span style="vertical-align: middle;"><a href="/c-programming-for-atari-st-with-docker/"><img src="/images/flags/en.png" /></a></span>
<span style="vertical-align: middle;"><a href="/my-jekyll-tips-with-github-pages/"><img src="/images/flags/en.png" /></a></span>
<span style="vertical-align: middle;"><a href="/how-to-generate-java-executables-with-maven/"><img src="/images/flags/en.png" /></a></span>
<span style="vertical-align: middle;"><a href="/c-programming-for-atari-st-with-linux/"><img src="/images/flags/en.png" /></a></span>
<span style="vertical-align: middle;"><a href="/functional-switch-en/"><img src="/images/flags/en.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Lombok-Yes-But/"><img src="/images/flags/en.png" /></a></span>
<span style="vertical-align: middle;"><a href="/primitive-obsession/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/eclipse-collections/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/atari-st-c-compiler-avec-docker/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/my-jekyll-tips-with-github-pages-fr/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/generer-executables-java-avec-maven/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/6809-thomson-to8-bootsector/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/m68k-atari-st-ym-player/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/m68k-atari-st-assembly-and-c/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/atari-st-4-bitplanes-simulator/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/atari-st-4-bitplanes/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/6809-thomson-mo5-assembly-linux/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/m68k-atari-st-assembly-linux/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/programmation-c-pour-atari-st-sous-linux/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Worst-Collection-Api-Of-The-World/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/quarkus-jpa-graalvm/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/functional-switch"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Dockerfile-perime/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/coding-style/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Mot-De-Passe-En-Clair/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Singleton-Est-Mort-Vive-Singleton/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Float-BigDecimal-Montant/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Reactive-Programming/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/GWT-AngularJS-GoogleMaps-Kotlin/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Web-Components/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Angular2-AngularJS/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/XML-JSON/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/EJB-versus-light/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/cdi-deltaspike-junit5/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/api-preconditions/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/jshell-http-server/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Archiva-Raspberry/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Contribuer-Eclipse-Foundation-Done/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/construction-instance-java/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Xenon-Reborn/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Enum-JPA-Named-Query/"><img src="/images/flags/fr.png" /></a></span>
<span style="vertical-align: middle;"><a href="/Lombok-Oui-Mais/"><img src="/images/flags/fr.png" /></a></span>
</span>
</div>
<aside class="toc-sidebar">
<div class="sidebar-section-title">CONTENTS</div>
<ul class="toc-list">
<li><a href="#résumé-exécutif">Résumé Exécutif</a></li>
<li><a href="#1-contenu">1. Contenu</a>
<ul>
<li><a href="#11-volume-et-distribution">1.1 Volume et distribution</a></li>
<li><a href="#12-timeline-de-publication">1.2 Timeline de publication</a></li>
<li><a href="#13-thématiques-et-tags">1.3 Thématiques et tags</a></li>
<li><a href="#14-qualité-des-front-matter">1.4 Qualité des front matter</a></li>
<li><a href="#15-brouillons-_drafts">1.5 Brouillons (_drafts/)</a></li>
</ul>
</li>
<li><a href="#2-technologies">2. Technologies</a>
<ul>
<li><a href="#21-jekyll">2.1 Jekyll</a></li>
<li><a href="#22-cicd">2.2 CI/CD</a></li>
<li><a href="#23-frontend">2.3 Frontend</a></li>
<li><a href="#24-sass--css">2.4 Sass / CSS</a></li>
<li><a href="#25-layouts-et-includes">2.5 Layouts et Includes</a></li>
</ul>
</li>
<li><a href="#3-architecture">3. Architecture</a>
<ul>
<li><a href="#31-structure-répertoires">3.1 Structure répertoires</a></li>
<li><a href="#32-convention-de-nommage-des-posts">3.2 Convention de nommage des posts</a></li>
<li><a href="#33-système-multilingue">3.3 Système multilingue</a></li>
<li><a href="#34-stratégie-permalink">3.4 Stratégie permalink</a></li>
</ul>
</li>
<li><a href="#4-seo-et-intégrations-tierces">4. SEO et Intégrations tierces</a>
<ul>
<li><a href="#41-seo">4.1 SEO</a></li>
<li><a href="#42-intégrations-actives">4.2 Intégrations actives</a></li>
</ul>
</li>
<li><a href="#5-qualité-et-problèmes-détectés">5. Qualité et Problèmes Détectés</a>
<ul>
<li><a href="#51-problème-critique--logos-manquants">5.1 Problème critique — Logos manquants</a></li>
<li><a href="#52-problèmes-importants">5.2 Problèmes importants</a></li>
<li><a href="#53-améliorations-mineures">5.3 Améliorations mineures</a></li>
<li><a href="#54-drafts--action-éditoriale">5.4 Drafts — action éditoriale</a></li>
</ul>
</li>
<li><a href="#6-métriques-de-synthèse">6. Métriques de synthèse</a></li>
<li><a href="#7-recommandations-prioritaires">7. Recommandations prioritaires</a>
<ul>
<li><a href="#priorité-1--critique">Priorité 1 — Critique</a></li>
<li><a href="#priorité-2--important">Priorité 2 — Important</a></li>
<li><a href="#priorité-3--amélioration">Priorité 3 — Amélioration</a></li>
</ul>
</li>
<li><a href="#"></a></li>
</ul>
<hr class="sidebar-divider">
<div class="sidebar-section-title">SHARE</div>
<div class="sidebar-share">
<a href="https://github.com/fxrobin" target="_blank" rel="nofollow">[gh]</a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https://www.fxjavadevblog.fr/docs/superpowers/plans/2026-04-18-vt100-redesign/&title=VT-100 Hybrid Redesign Implementation Plan" target="_blank" rel="nofollow">[li]</a>
<a href="https://twitter.com/intent/tweet?text=VT-100 Hybrid Redesign Implementation Plan&url=https://www.fxjavadevblog.fr/docs/superpowers/plans/2026-04-18-vt100-redesign/" target="_blank" rel="nofollow">[tw]</a>
</div>
</aside>
<div class="entry">
<article class="post">
<img src="/images/logos/" class="logo-in-page"/>
<h1>Audit du Repository — FX JavaDevBlog</h1>
<div class="accroche"></div>
<!-- include language-selector.html -->
<div class="post-body">
<div class="entry entry-content">
<h1 id="audit-du-repository--fx-javadevblog">Audit du Repository — FX JavaDevBlog</h1>
<p><strong>Date :</strong> 18 avril 2026<br />
<strong>Repository :</strong> <code class="language-plaintext highlighter-rouge">fxrobin/fxrobin.github.io</code><br />
<strong>Site :</strong> https://www.fxjavadevblog.fr<br />
<strong>Auditeur :</strong> Claude Code</p>
<hr />
<h2 id="résumé-exécutif">Résumé Exécutif</h2>
<p>Blog technique Jekyll bien structuré, focalisé Java/rétro/architecture. Infrastructure solide, automatisation complète. Contenu à 68% vieux de 5+ ans, mais reprise notable en avril 2026.</p>
<p><strong>Bilan santé global :</strong></p>
<table>
<thead>
<tr>
<th>Dimension</th>
<th>Note</th>
<th>Commentaire</th>
</tr>
</thead>
<tbody>
<tr>
<td>Infrastructure</td>
<td>★★★★★</td>
<td>CI/CD, Docker, plugins</td>
</tr>
<tr>
<td>Structure contenu</td>
<td>★★★★☆</td>
<td>Conventions cohérentes</td>
</tr>
<tr>
<td>SEO</td>
<td>★★★☆☆</td>
<td>Plugins OK, JSON-LD absent</td>
</tr>
<tr>
<td>Couverture bilingue</td>
<td>★★☆☆☆</td>
<td>18% EN seulement</td>
</tr>
<tr>
<td>Fréquence publication</td>
<td>★★☆☆☆</td>
<td>Gaps 2 ans répétés</td>
</tr>
<tr>
<td>Performance frontend</td>
<td>★★★☆☆</td>
<td>CDN OK, CSS non-minifié</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="1-contenu">1. Contenu</h2>
<h3 id="11-volume-et-distribution">1.1 Volume et distribution</h3>
<table>
<thead>
<tr>
<th>Catégorie</th>
<th>Total</th>
<th>FR</th>
<th>EN</th>
<th>Récents (≤2 ans)</th>
<th>Moyens (2–5 ans)</th>
<th>Anciens (5+ ans)</th>
</tr>
</thead>
<tbody>
<tr>
<td>Articles</td>
<td>23</td>
<td>17</td>
<td>6</td>
<td>4</td>
<td>4</td>
<td>15</td>
</tr>
<tr>
<td>Blanka Cave</td>
<td>10</td>
<td>10</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>10</td>
</tr>
<tr>
<td>Retro-Prog</td>
<td>11</td>
<td>9</td>
<td>2</td>
<td>2</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td><strong>TOTAL</strong></td>
<td><strong>44</strong></td>
<td><strong>36</strong></td>
<td><strong>8</strong></td>
<td><strong>6</strong></td>
<td><strong>8</strong></td>
<td><strong>30</strong></td>
</tr>
</tbody>
</table>
<p><strong>Distribution linguistique :</strong></p>
<ul>
<li>Français : 36 posts (81%)</li>
<li>Anglais : 8 posts (18%)</li>
<li>Paires bilingues (même <code class="language-plaintext highlighter-rouge">ref</code>) : 8</li>
</ul>
<h3 id="12-timeline-de-publication">1.2 Timeline de publication</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>2018 : 21 posts ★★★★★ Lancement / pic d'activité
2019 : 0 posts —————— GAP 1 (2 ans)
2020 : 4 posts ★★
2021 : 8 posts ★★★★
2022 : 3 posts ★
2023 : 2 posts ★
2024 : 2 posts ★ GAP 2 (24 mois)
2025 : 0 posts ——————
2026 : 4 posts ★★ Reprise (avril 2026)
</code></pre></div></div>
<p><strong>Pics :</strong></p>
<ul>
<li>Juillet 2018 : 7 posts (lancement Blanka Cave)</li>
<li>Mars 2018 : 5 posts</li>
<li>Avril 2026 : 4 posts (reprise actuelle)</li>
</ul>
<h3 id="13-thématiques-et-tags">1.3 Thématiques et tags</h3>
<p><strong>73 tags uniques.</strong> Top 10 :</p>
<table>
<thead>
<tr>
<th>Tag</th>
<th>Occurrences</th>
</tr>
</thead>
<tbody>
<tr>
<td>Java</td>
<td>13</td>
</tr>
<tr>
<td>Retro / Retro-Prog</td>
<td>11</td>
</tr>
<tr>
<td>Atari</td>
<td>9</td>
</tr>
<tr>
<td>C</td>
<td>6</td>
</tr>
<tr>
<td>Assembleur</td>
<td>5</td>
</tr>
<tr>
<td>Lambda / Functional</td>
<td>4</td>
</tr>
<tr>
<td>JPA / Lombok</td>
<td>3</td>
</tr>
<tr>
<td>Maven / Bean Validation</td>
<td>2–3</td>
</tr>
</tbody>
</table>
<p><strong>Clusters thématiques :</strong></p>
<ul>
<li>Rétro computing (Atari ST, Thomson, 68000, 6809) : ~33%</li>
<li>Java enterprise (CDI, JPA, Quarkus, GraalVM, JAX-RS) : ~27%</li>
<li>DevOps/Tooling (Maven, Docker, GitHub) : ~14%</li>
<li>Design patterns & craftsmanship : ~9%</li>
</ul>
<p><strong>Couverture Java :</strong> Java 8, 10, 12, 21 mentionnés dans des posts. Aucun article dédié aux versions Java.</p>
<h3 id="14-qualité-des-front-matter">1.4 Qualité des front matter</h3>
<table>
<thead>
<tr>
<th>Champ</th>
<th>Présence</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
<tr>
<td>layout, title, lang, category</td>
<td>44/44</td>
<td>✓ 100%</td>
</tr>
<tr>
<td>logo</td>
<td>44/44</td>
<td>✓ 100% (référencé)</td>
</tr>
<tr>
<td>subtitle</td>
<td>34/44</td>
<td>✓ 77%</td>
</tr>
<tr>
<td>ref</td>
<td>34/44</td>
<td>✓ 77%</td>
</tr>
<tr>
<td>tags</td>
<td>33/44</td>
<td>✓ 75%</td>
</tr>
<tr>
<td>excerpt marker <code class="language-plaintext highlighter-rouge"><!--excerpt--></code></td>
<td>33/44</td>
<td>✓ 75%</td>
</tr>
</tbody>
</table>
<p>Les posts Blanka Cave sont intentionnellement minimalistes (pas de tags, pas de <code class="language-plaintext highlighter-rouge">ref</code>, <code class="language-plaintext highlighter-rouge">sitemap: false</code>).</p>
<h3 id="15-brouillons-_drafts">1.5 Brouillons (_drafts/)</h3>
<p><strong>9 fichiers markdown :</strong></p>
<table>
<thead>
<tr>
<th>Fichier</th>
<th>Taille</th>
<th>Statut estimé</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">PLAN.md</code></td>
<td>—</td>
<td>Plan éditorial</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">a-rediger.md</code></td>
<td>—</td>
<td>Placeholder</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">questions-poo.md</code></td>
<td>13.2 KB</td>
<td>Quasi-publiable</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">angular8-javaee.md</code></td>
<td>—</td>
<td>Daté (Angular 8)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">choisir-js-angular-react-vue-webcomponents.md</code></td>
<td>—</td>
<td>Daté</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">cdi-payara-arquillian-deltaspike.md</code></td>
<td>—</td>
<td>Abandonné probable</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">focus-list.md</code></td>
<td>—</td>
<td>Court</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">gradle-travis-github.md</code></td>
<td>—</td>
<td>Daté</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">java-ee-nio.md</code></td>
<td>—</td>
<td>Daté</td>
</tr>
</tbody>
</table>
<p><strong>7 répertoires de drafts en cours :</strong></p>
<table>
<thead>
<tr>
<th>Répertoire</th>
<th>Sujet</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">blog/</code></td>
<td>Contenu générique</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">maven-javadoc-lombok-java-21/</code></td>
<td>Combo Maven + Java 21</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">minikube-helm-quarkus/</code></td>
<td>Kubernetes + Quarkus</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">uuid-versions-jmh/</code></td>
<td>UUID v7, benchmarks JMH</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">vertx-eventbus-quarkus/</code></td>
<td>Vert.x EventBus</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">virtual-threads-loom/</code></td>
<td>Project Loom</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">x-mas-architecture/</code></td>
<td>Architecture de Noël</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="2-technologies">2. Technologies</h2>
<h3 id="21-jekyll">2.1 Jekyll</h3>
<table>
<thead>
<tr>
<th>Paramètre</th>
<th>Valeur</th>
</tr>
</thead>
<tbody>
<tr>
<td>Version Jekyll</td>
<td>v1.2.0</td>
</tr>
<tr>
<td>Markdown</td>
<td>GFM (GitHub Flavored)</td>
</tr>
<tr>
<td>Syntax highlighter</td>
<td>Rouge</td>
</tr>
<tr>
<td>Pagination</td>
<td>3 posts/page</td>
</tr>
<tr>
<td>Excerpt separator</td>
<td><code class="language-plaintext highlighter-rouge"><!--excerpt--></code></td>
</tr>
<tr>
<td>Permalink par défaut</td>
<td><code class="language-plaintext highlighter-rouge">/:title/</code></td>
</tr>
<tr>
<td>Style CSS généré</td>
<td><code class="language-plaintext highlighter-rouge">:expanded</code> (non-minifié)</td>
</tr>
</tbody>
</table>
<p><strong>Plugins activés (3) :</strong></p>
<table>
<thead>
<tr>
<th>Plugin</th>
<th>Rôle</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">jekyll-sitemap</code></td>
<td>Génération sitemap.xml automatique</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">jekyll-seo-tag</code></td>
<td>Meta tags SEO (OG, Twitter Card)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">jekyll-redirect-from</code></td>
<td>Redirections d’URL legacy</td>
</tr>
</tbody>
</table>
<p><code class="language-plaintext highlighter-rouge">jekyll-feed</code> est commenté dans <code class="language-plaintext highlighter-rouge">_config.yml</code> — RSS désactivé intentionnellement.</p>
<h3 id="22-cicd">2.2 CI/CD</h3>
<p><strong>GitHub Actions</strong> (<code class="language-plaintext highlighter-rouge">.github/workflows/jekyll.yml</code>) :</p>
<ul>
<li>Déclencheurs : push et PR sur <code class="language-plaintext highlighter-rouge">master</code></li>
<li>Runner : <code class="language-plaintext highlighter-rouge">ubuntu-latest</code></li>
<li>Container build : <code class="language-plaintext highlighter-rouge">jekyll/builder:latest</code></li>
<li>Commande : <code class="language-plaintext highlighter-rouge">jekyll build --future</code></li>
<li>Pas de Gemfile local, pas de Dockerfile — dépend entièrement du container officiel</li>
</ul>
<h3 id="23-frontend">2.3 Frontend</h3>
<p><strong>Aucun <code class="language-plaintext highlighter-rouge">package.json</code>, aucun <code class="language-plaintext highlighter-rouge">npm</code>.</strong> Tout via CDN :</p>
<table>
<thead>
<tr>
<th>Bibliothèque</th>
<th>Version</th>
<th>Source</th>
<th>Usage</th>
</tr>
</thead>
<tbody>
<tr>
<td>TypewriterJS</td>
<td>1.0.0</td>
<td>CDNJS</td>
<td>Animation titre header</td>
</tr>
<tr>
<td>Vue.js</td>
<td>2.5.16</td>
<td>CDNJS</td>
<td>Composants réactifs (usage réel ?)</td>
</tr>
<tr>
<td>Axios</td>
<td>0.18.0</td>
<td>CDNJS</td>
<td>Requêtes AJAX</td>
</tr>
<tr>
<td>Font Awesome</td>
<td>4.7.0</td>
<td>CDNJS</td>
<td>Icônes</td>
</tr>
<tr>
<td>CSS Social Buttons</td>
<td>1.3.0</td>
<td>CDNJS</td>
<td>Boutons de partage</td>
</tr>
<tr>
<td>Mermaid</td>
<td>10</td>
<td>JSDelivr</td>
<td>Diagrammes (opt-in)</td>
</tr>
<tr>
<td>Asciinema</td>
<td>local</td>
<td><code class="language-plaintext highlighter-rouge">/asciinema/</code></td>
<td>Lectures terminales</td>
</tr>
</tbody>
</table>
<p><strong>JavaScript local (2 fichiers) :</strong></p>
<ul>
<li><code class="language-plaintext highlighter-rouge">js/main.js</code> (2.8 KB) — Fonctionnalités core</li>
<li><code class="language-plaintext highlighter-rouge">js/cv-scroll-animations.js</code> (4.6 KB) — Animations page CV</li>
</ul>
<h3 id="24-sass--css">2.4 Sass / CSS</h3>
<p><strong>26 modules SCSS dans <code class="language-plaintext highlighter-rouge">_sass/</code> :</strong></p>
<table>
<thead>
<tr>
<th>Module</th>
<th>Taille</th>
<th>Rôle</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">_svg-icons.scss</code></td>
<td><strong>52.6 KB</strong></td>
<td>SVG inline (icônes sociales)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_base-rules.scss</code></td>
<td>—</td>
<td>Typographie, base</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_post.scss</code></td>
<td>—</td>
<td>Styles article</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_variables.scss</code></td>
<td>—</td>
<td>Couleurs, polices</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_highlights.scss</code></td>
<td>—</td>
<td>Coloration syntaxique</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_table-of-content.scss</code></td>
<td>—</td>
<td>TOC</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">_nav.scss</code>, <code class="language-plaintext highlighter-rouge">_search.scss</code>, <code class="language-plaintext highlighter-rouge">_blanka.scss</code>, <code class="language-plaintext highlighter-rouge">_retro-list.scss</code></td>
<td>—</td>
<td>Composants spécifiques</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">effects/</code></td>
<td>—</td>
<td>Animations</td>
</tr>
<tr>
<td>16 autres</td>
<td>—</td>
<td>Reset, mixins, layout</td>
</tr>
</tbody>
</table>
<p><strong>Polices custom</strong> (<code class="language-plaintext highlighter-rouge">_fonts.scss</code>) : <code class="language-plaintext highlighter-rouge">amiga</code>, <code class="language-plaintext highlighter-rouge">atari</code>, <code class="language-plaintext highlighter-rouge">volter</code>, <code class="language-plaintext highlighter-rouge">coders-crux</code>, <code class="language-plaintext highlighter-rouge">Monda</code> — identité rétro/hacker forte.</p>
<p><strong>Stylesheets complémentaires :</strong> <code class="language-plaintext highlighter-rouge">blink.css</code>, <code class="language-plaintext highlighter-rouge">hover.css</code>, <code class="language-plaintext highlighter-rouge">print.css</code></p>
<h3 id="25-layouts-et-includes">2.5 Layouts et Includes</h3>
<p><strong>7 layouts :</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>_layouts/
├── default.html (5.2 KB) ← Base : header, nav, footer, JS
│ ├── post.html (769 B) ← Articles
│ ├── page.html (406 B)
│ ├── page-no-aside.html
│ ├── blog_index.html
│ ├── cv-layout.html
│ └── cv-new-layout.html
</code></pre></div></div>
<p><strong>25 includes</strong> dont :</p>
<table>
<thead>
<tr>
<th>Include</th>
<th>Taille</th>
<th>Rôle</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">toc.html</code></td>
<td>3.8 KB</td>
<td>Générateur TOC automatique</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">meta.html</code></td>
<td>744 B</td>
<td>SEO + Open Graph</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">disqus.html</code></td>
<td>706 B</td>
<td>Commentaires Disqus</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">analytics.html</code></td>
<td>376 B</td>
<td>Google Analytics</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">search.html</code></td>
<td>633 B</td>
<td>Google Custom Search</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">post-aside.html</code></td>
<td>929 B</td>
<td>Sidebar (TOC + partage)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">language-selector.html</code></td>
<td>474 B</td>
<td>Sélecteur FR/EN</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">mermaid.html</code></td>
<td>128 B</td>
<td>Loader Mermaid</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">asciinema.html</code></td>
<td>93 B</td>
<td>Player terminal</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">svg-icons.html</code></td>
<td>2.1 KB</td>
<td>Icônes sociales/footer</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="3-architecture">3. Architecture</h2>
<h3 id="31-structure-répertoires">3.1 Structure répertoires</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fxrobin.github.io/
├── _posts/
│ ├── articles/ 23 posts (sous-dossiers par slug)
│ ├── blanka-cave/fr/ 10 posts
│ └── retro-prog/ 11 posts
├── _drafts/ 9 .md + 7 répertoires en cours
├── _layouts/ 7 templates
├── _includes/ 25 composants
├── _sass/ 26 modules SCSS
├── images/ 19 sous-répertoires (logos, flags, par-article)
├── js/ 2 fichiers JS
├── fonts/ 614 KB (polices custom)
├── asciinema/ 621 KB (player + casts)
├── casts/ 54 KB (enregistrements terminal)
├── _config.yml
├── style.scss
├── index.html / index-fr.html / index-en.html
└── .github/workflows/jekyll.yml
</code></pre></div></div>
<h3 id="32-convention-de-nommage-des-posts">3.2 Convention de nommage des posts</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>_posts/[catégorie]/[slug optionnel]/YYYY-MM-DD-[slug].md
</code></pre></div></div>
<p>Exemples :</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">_posts/articles/api-preconditions/2018-06-02-api-preconditions.md</code></li>
<li><code class="language-plaintext highlighter-rouge">_posts/blanka-cave/fr/2018-07-21-Web-Components.md</code></li>
<li><code class="language-plaintext highlighter-rouge">_posts/retro-prog/m68k-cross-compiling/2021-02-05-m68k-cross-compiling-EN.md</code></li>
</ul>
<h3 id="33-système-multilingue">3.3 Système multilingue</h3>
<ul>
<li>Champ <code class="language-plaintext highlighter-rouge">lang: fr|en</code> dans le front matter</li>
<li>Champ <code class="language-plaintext highlighter-rouge">ref</code> partagé entre les versions d’un même article</li>
<li><code class="language-plaintext highlighter-rouge">language-selector.html</code> retrouve la version alternate via <code class="language-plaintext highlighter-rouge">ref</code></li>
<li>Labels UI (menus, textes) définis dans <code class="language-plaintext highlighter-rouge">_config.yml</code> sous <code class="language-plaintext highlighter-rouge">site.t[lang].*</code></li>
<li>Blanka Cave : uniquement FR, pas de <code class="language-plaintext highlighter-rouge">ref</code></li>
</ul>
<h3 id="34-stratégie-permalink">3.4 Stratégie permalink</h3>
<ul>
<li>Par défaut : <code class="language-plaintext highlighter-rouge">/:title/</code></li>
<li>Surcharge possible via <code class="language-plaintext highlighter-rouge">permalink:</code> dans le front matter (ex. anglais vs français)</li>
<li>Redirections legacy : <code class="language-plaintext highlighter-rouge">redirect_from:</code> géré par <code class="language-plaintext highlighter-rouge">jekyll-redirect-from</code></li>
</ul>
<hr />
<h2 id="4-seo-et-intégrations-tierces">4. SEO et Intégrations tierces</h2>
<h3 id="41-seo">4.1 SEO</h3>
<table>
<thead>
<tr>
<th>Élément</th>
<th>Présence</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
<tr>
<td>sitemap.xml</td>
<td>✓ auto via plugin</td>
<td>OK</td>
</tr>
<tr>
<td>Open Graph (og:title, og:description)</td>
<td>✓</td>
<td>OK</td>
</tr>
<tr>
<td>Twitter Card</td>
<td>✓</td>
<td>OK</td>
</tr>
<tr>
<td>Google Search Console</td>
<td>✓ (<code class="language-plaintext highlighter-rouge">googleb3f4e2521de300ce.html</code>)</td>
<td>OK</td>
</tr>
<tr>
<td>Viewport meta</td>
<td>✓</td>
<td>OK</td>
</tr>
<tr>
<td>Canonical URLs</td>
<td>Implicite</td>
<td>OK</td>
</tr>
<tr>
<td>robots.txt explicite</td>
<td>✗</td>
<td>Manquant</td>
</tr>
<tr>
<td>JSON-LD / Schema.org</td>
<td>✗</td>
<td>Absent</td>
</tr>
<tr>
<td>Sitemap dans <code class="language-plaintext highlighter-rouge"><head></code></td>
<td>✗</td>
<td>Non lié</td>
</tr>
</tbody>
</table>
<h3 id="42-intégrations-actives">4.2 Intégrations actives</h3>
<table>
<thead>
<tr>
<th>Service</th>
<th>Config</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
<tr>
<td>Disqus</td>
<td>shortname: <code class="language-plaintext highlighter-rouge">fxrobin-github-io</code></td>
<td>✓ Actif</td>
</tr>
<tr>
<td>Google Analytics</td>
<td>UA-114271874-1</td>
<td>✓ Actif (Universal — obsolète)</td>
</tr>
<tr>
<td>Google Custom Search</td>
<td>cx=011993730579911903160:17ronej8jdw</td>
<td>✓ Actif</td>
</tr>
<tr>
<td>Mermaid.js</td>
<td>opt-in via <code class="language-plaintext highlighter-rouge">page.mermaid: true</code></td>
<td>✓ Disponible, <strong>0 posts l’utilisent</strong></td>
</tr>
<tr>
<td>Asciinema</td>
<td>opt-in via include</td>
<td>✓ Disponible, <strong>0 posts l’utilisent</strong></td>
</tr>
</tbody>
</table>
<hr />
<h2 id="5-qualité-et-problèmes-détectés">5. Qualité et Problèmes Détectés</h2>
<h3 id="51-problème-critique--logos-manquants">5.1 Problème critique — Logos manquants</h3>
<p><strong>21 fichiers logo référencés dans le front matter mais absents de <code class="language-plaintext highlighter-rouge">/images/logos/</code>.</strong></p>
<p>Impact : 48% des posts affichent une image cassée.<br />
Exemples : <code class="language-plaintext highlighter-rouge">api-preconditions.png</code>, <code class="language-plaintext highlighter-rouge">archiva-rpi.png</code>, <code class="language-plaintext highlighter-rouge">code.png</code> (mais <code class="language-plaintext highlighter-rouge">code.jpg</code> existe).</p>
<p><strong>Action : Audit exhaustif <code class="language-plaintext highlighter-rouge">images/logos/</code> vs tous les champs <code class="language-plaintext highlighter-rouge">logo:</code> des posts.</strong></p>
<h3 id="52-problèmes-importants">5.2 Problèmes importants</h3>
<table>
<thead>
<tr>
<th>Problème</th>
<th>Impact</th>
<th>Recommandation</th>
</tr>
</thead>
<tbody>
<tr>
<td>Gaps de publication (2 ans)</td>
<td>Audience / SEO</td>
<td>Cadence éditoriale fixe</td>
</tr>
<tr>
<td>Google Analytics Universal (UA)</td>
<td>Tracking perdu — UA retraité</td>
<td>Migrer vers GA4</td>
</tr>
<tr>
<td>Vue.js 2.5.16 inclus sans usage visible</td>
<td>Poids inutile</td>
<td>Vérifier / supprimer</td>
</tr>
<tr>
<td>CSS non-minifié (<code class="language-plaintext highlighter-rouge">style: :expanded</code>)</td>
<td>Performance</td>
<td>Passer à <code class="language-plaintext highlighter-rouge">:compressed</code></td>
</tr>
<tr>
<td>Couverture EN à 18%</td>
<td>Audience internationale</td>
<td>Traduire 10–15 articles clés</td>
</tr>
<tr>
<td>Mermaid / Asciinema inutilisés</td>
<td>Fonctionnalités inexploitées</td>
<td>Les utiliser dans les prochains articles</td>
</tr>
</tbody>
</table>
<h3 id="53-améliorations-mineures">5.3 Améliorations mineures</h3>
<table>
<thead>
<tr>
<th>Problème</th>
<th>Recommandation</th>
</tr>
</thead>
<tbody>
<tr>
<td>73 tags sans casse uniforme (“java” vs “Java”)</td>
<td>Guide de style tags</td>
</tr>
<tr>
<td>25% des posts sans <code class="language-plaintext highlighter-rouge"><!--excerpt--></code></td>
<td>Ajouter sur les anciens posts clés</td>
</tr>
<tr>
<td>Dépendances front-end figées sur vieilles versions</td>
<td>Auditer + mettre à jour (FA 4→6, TypewriterJS)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">jekyll-feed</code> commenté (RSS désactivé)</td>
<td>Considérer activation (audience RSS)</td>
</tr>
<tr>
<td>Pas de <code class="language-plaintext highlighter-rouge">robots.txt</code> explicite</td>
<td>Créer fichier minimal</td>
</tr>
<tr>
<td>Pas de JSON-LD</td>
<td>Ajouter schema <code class="language-plaintext highlighter-rouge">BlogPosting</code> pour rich snippets</td>
</tr>
</tbody>
</table>
<h3 id="54-drafts--action-éditoriale">5.4 Drafts — action éditoriale</h3>
<table>
<thead>
<tr>
<th>Draft</th>
<th>Recommandation</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="language-plaintext highlighter-rouge">questions-poo.md</code> (13.2 KB)</td>
<td>Finaliser et publier</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">virtual-threads-loom/</code></td>
<td>Sujet très actuel (Java 21+), prioritaire</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">uuid-versions-jmh/</code></td>
<td>JMH = différenciateur technique, prioritaire</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">vertx-eventbus-quarkus/</code></td>
<td>Bon sujet Quarkus ecosystem</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">angular8-javaee.md</code></td>
<td>Abandonner (Angular 8 = daté)</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">choisir-js-angular-react-vue-webcomponents.md</code></td>
<td>Abandonner ou réécrire 2026</td>
</tr>
<tr>
<td><code class="language-plaintext highlighter-rouge">cdi-payara-arquillian-deltaspike.md</code></td>
<td>Abandonner</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="6-métriques-de-synthèse">6. Métriques de synthèse</h2>
<table>
<thead>
<tr>
<th>Métrique</th>
<th>Valeur</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
<tr>
<td>Posts publiés</td>
<td>44</td>
<td>✓</td>
</tr>
<tr>
<td>Posts FR</td>
<td>36 (81%)</td>
<td>✓</td>
</tr>
<tr>
<td>Posts EN</td>
<td>8 (18%)</td>
<td>⚠ Faible</td>
</tr>
<tr>
<td>Paires bilingues</td>
<td>8</td>
<td>✓</td>
</tr>
<tr>
<td>Drafts .md</td>
<td>9</td>
<td>⚠ À trier</td>
</tr>
<tr>
<td>Répertoires en cours</td>
<td>7</td>
<td>⚠ Prioritiser</td>
</tr>
<tr>
<td>Front matter complet (requis)</td>
<td>100%</td>
<td>✓</td>
</tr>
<tr>
<td>Logos référencés vs présents</td>
<td>52%</td>
<td>✗ Critique</td>
</tr>
<tr>
<td>Excerpt marqué</td>
<td>75%</td>
<td>✓</td>
</tr>
<tr>
<td>Tags uniques</td>
<td>73</td>
<td>✓</td>
</tr>
<tr>
<td>Layouts</td>
<td>7</td>
<td>✓</td>
</tr>
<tr>
<td>Includes</td>
<td>25</td>
<td>✓</td>
</tr>
<tr>
<td>Modules SCSS</td>
<td>26</td>
<td>✓</td>
</tr>
<tr>
<td>Plugins Jekyll</td>
<td>3</td>
<td>✓</td>
</tr>
<tr>
<td>Intégrations tierces</td>
<td>5</td>
<td>✓</td>
</tr>
</tbody>
</table>
<hr />
<h2 id="7-recommandations-prioritaires">7. Recommandations prioritaires</h2>
<h3 id="priorité-1--critique">Priorité 1 — Critique</h3>
<ol>
<li><strong>Réparer les logos manquants</strong> (21 fichiers) — impact visuel direct sur 48% des posts</li>
</ol>
<h3 id="priorité-2--important">Priorité 2 — Important</h3>
<ol>
<li><strong>Migrer Google Analytics UA → GA4</strong> — UA est retraité, les données sont perdues</li>
<li><strong>Établir une cadence de publication</strong> — 1 article/mois minimum pour éviter les gaps</li>
<li><strong>Publier les drafts prioritaires</strong> : <code class="language-plaintext highlighter-rouge">virtual-threads-loom</code>, <code class="language-plaintext highlighter-rouge">uuid-versions-jmh</code>, <code class="language-plaintext highlighter-rouge">questions-poo.md</code></li>
<li><strong>Supprimer ou mettre à jour Vue.js</strong> — v2.5.16 inclus systématiquement, usage non vérifié</li>
</ol>
<h3 id="priorité-3--amélioration">Priorité 3 — Amélioration</h3>
<ol>
<li><strong>Activer la minification CSS</strong> : <code class="language-plaintext highlighter-rouge">style: :compressed</code> dans <code class="language-plaintext highlighter-rouge">_config.yml</code></li>
<li><strong>Ajouter <code class="language-plaintext highlighter-rouge">robots.txt</code></strong> explicite</li>
<li><strong>Ajouter JSON-LD</strong> <code class="language-plaintext highlighter-rouge">BlogPosting</code> pour les rich snippets Google</li>
<li><strong>Uniformiser les tags</strong> (casse, singulier/pluriel)</li>
<li><strong>Utiliser Mermaid.js et Asciinema</strong> dans les prochains articles techniques</li>
</ol>
<hr />
<p><em>Généré par Claude Code — avril 2026</em></p>
</div>
<aside class="toc-sidebar">
<div class="sidebar-section-title">CONTENTS</div>
<ul class="toc-list">
<li><a href="#résumé-exécutif">Résumé Exécutif</a></li>
<li><a href="#1-contenu">1. Contenu</a>
<ul>
<li><a href="#11-volume-et-distribution">1.1 Volume et distribution</a></li>
<li><a href="#12-timeline-de-publication">1.2 Timeline de publication</a></li>
<li><a href="#13-thématiques-et-tags">1.3 Thématiques et tags</a></li>
<li><a href="#14-qualité-des-front-matter">1.4 Qualité des front matter</a></li>
<li><a href="#15-brouillons-_drafts">1.5 Brouillons (_drafts/)</a></li>
</ul>
</li>
<li><a href="#2-technologies">2. Technologies</a>
<ul>
<li><a href="#21-jekyll">2.1 Jekyll</a></li>
<li><a href="#22-cicd">2.2 CI/CD</a></li>
<li><a href="#23-frontend">2.3 Frontend</a></li>
<li><a href="#24-sass--css">2.4 Sass / CSS</a></li>
<li><a href="#25-layouts-et-includes">2.5 Layouts et Includes</a></li>
</ul>
</li>
<li><a href="#3-architecture">3. Architecture</a>
<ul>
<li><a href="#31-structure-répertoires">3.1 Structure répertoires</a></li>
<li><a href="#32-convention-de-nommage-des-posts">3.2 Convention de nommage des posts</a></li>
<li><a href="#33-système-multilingue">3.3 Système multilingue</a></li>
<li><a href="#34-stratégie-permalink">3.4 Stratégie permalink</a></li>
</ul>
</li>
<li><a href="#4-seo-et-intégrations-tierces">4. SEO et Intégrations tierces</a>
<ul>
<li><a href="#41-seo">4.1 SEO</a></li>
<li><a href="#42-intégrations-actives">4.2 Intégrations actives</a></li>
</ul>
</li>
<li><a href="#5-qualité-et-problèmes-détectés">5. Qualité et Problèmes Détectés</a>
<ul>
<li><a href="#51-problème-critique--logos-manquants">5.1 Problème critique — Logos manquants</a></li>
<li><a href="#52-problèmes-importants">5.2 Problèmes importants</a></li>
<li><a href="#53-améliorations-mineures">5.3 Améliorations mineures</a></li>
<li><a href="#54-drafts--action-éditoriale">5.4 Drafts — action éditoriale</a></li>
</ul>
</li>
<li><a href="#6-métriques-de-synthèse">6. Métriques de synthèse</a></li>
<li><a href="#7-recommandations-prioritaires">7. Recommandations prioritaires</a>
<ul>
<li><a href="#priorité-1--critique">Priorité 1 — Critique</a></li>
<li><a href="#priorité-2--important">Priorité 2 — Important</a></li>
<li><a href="#priorité-3--amélioration">Priorité 3 — Amélioration</a></li>
</ul>
</li>
</ul>
<hr class="sidebar-divider">
<div class="sidebar-section-title">SHARE</div>
<div class="sidebar-share">
<a href="https://github.com/fxrobin" target="_blank" rel="nofollow">[gh]</a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https://www.fxjavadevblog.fr/analyse-repo/&title=Audit du Repository — FX JavaDevBlog" target="_blank" rel="nofollow">[li]</a>
<a href="https://twitter.com/intent/tweet?text=Audit du Repository — FX JavaDevBlog&url=https://www.fxjavadevblog.fr/analyse-repo/" target="_blank" rel="nofollow">[tw]</a>
</div>
</aside>
</div>
</article>
<div class="disqus">
<h2></h2>
<div class="comments">
<div id="disqus_thread"></div>
<script type="text/javascript">
var disqus_shortname = 'fxrobin-github-io';
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</div>
</div>
</article>
<button class="comments-toggle" onclick="this.textContent=this.textContent.includes('▼')?'[COMMENTS ▲]':'[COMMENTS ▼]';document.getElementById('comments-section').classList.toggle('open')">[COMMENTS ▼]</button>
<div id="comments-section" class="comments-section">
<div class="disqus">
<h2></h2>
<div class="comments">
<div id="disqus_thread"></div>
<script type="text/javascript">
var disqus_shortname = 'fxrobin-github-io';
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</div>
</div>
<div class="article-list-footer">
<div class="article-list-header"><i class="fa fa-newspaper-o"></i> </div>
</div>
- Step 4: Update
_includes/post-aside.html
Replace the entire file:
<aside class="toc-sidebar">
<div class="sidebar-section-title">CONTENTS</div>
<ul>
<li><a href="#">Audit du Repository — FX JavaDevBlog</a></li>
<li><a href="#audit-du-repository--fx-javadevblog">Audit du Repository — FX JavaDevBlog</a>
<ul>
<li><a href="#résumé-exécutif">Résumé Exécutif</a></li>
<li><a href="#1-contenu">1. Contenu</a>
<ul>
<li><a href="#11-volume-et-distribution">1.1 Volume et distribution</a></li>
<li><a href="#12-timeline-de-publication">1.2 Timeline de publication</a></li>
<li><a href="#13-thématiques-et-tags">1.3 Thématiques et tags</a></li>
<li><a href="#14-qualité-des-front-matter">1.4 Qualité des front matter</a></li>
<li><a href="#15-brouillons-_drafts">1.5 Brouillons (_drafts/)</a></li>
</ul>
</li>
<li><a href="#2-technologies">2. Technologies</a>
<ul>
<li><a href="#21-jekyll">2.1 Jekyll</a></li>
<li><a href="#22-cicd">2.2 CI/CD</a></li>
<li><a href="#23-frontend">2.3 Frontend</a></li>
<li><a href="#24-sass--css">2.4 Sass / CSS</a></li>
<li><a href="#25-layouts-et-includes">2.5 Layouts et Includes</a></li>
</ul>
</li>
<li><a href="#3-architecture">3. Architecture</a>
<ul>
<li><a href="#31-structure-répertoires">3.1 Structure répertoires</a></li>
<li><a href="#32-convention-de-nommage-des-posts">3.2 Convention de nommage des posts</a></li>
<li><a href="#33-système-multilingue">3.3 Système multilingue</a></li>
<li><a href="#34-stratégie-permalink">3.4 Stratégie permalink</a></li>
</ul>
</li>
<li><a href="#4-seo-et-intégrations-tierces">4. SEO et Intégrations tierces</a>
<ul>
<li><a href="#41-seo">4.1 SEO</a></li>
<li><a href="#42-intégrations-actives">4.2 Intégrations actives</a></li>
</ul>
</li>
<li><a href="#5-qualité-et-problèmes-détectés">5. Qualité et Problèmes Détectés</a>
<ul>
<li><a href="#51-problème-critique--logos-manquants">5.1 Problème critique — Logos manquants</a></li>
<li><a href="#52-problèmes-importants">5.2 Problèmes importants</a></li>
<li><a href="#53-améliorations-mineures">5.3 Améliorations mineures</a></li>
<li><a href="#54-drafts--action-éditoriale">5.4 Drafts — action éditoriale</a></li>
</ul>
</li>
<li><a href="#6-métriques-de-synthèse">6. Métriques de synthèse</a></li>
<li><a href="#7-recommandations-prioritaires">7. Recommandations prioritaires</a>
<ul>
<li><a href="#priorité-1--critique">Priorité 1 — Critique</a></li>
<li><a href="#priorité-2--important">Priorité 2 — Important</a></li>
<li><a href="#priorité-3--amélioration">Priorité 3 — Amélioration</a></li>
</ul>
</li>
<li><a href="#"></a></li>
</ul>
</li>
</ul>
<hr class="sidebar-divider">
<div class="sidebar-section-title">SHARE</div>
<div class="sidebar-share">
<a href="https://github.com/fxrobin" target="_blank" rel="nofollow">[gh]</a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url=https://www.fxjavadevblog.fr/docs/superpowers/plans/2026-04-18-vt100-redesign/&title=VT-100 Hybrid Redesign Implementation Plan" target="_blank" rel="nofollow">[li]</a>
<a href="https://twitter.com/intent/tweet?text=VT-100 Hybrid Redesign Implementation Plan&url=https://www.fxjavadevblog.fr/docs/superpowers/plans/2026-04-18-vt100-redesign/" target="_blank" rel="nofollow">[tw]</a>
</div>
</aside>
Add to _sass/_article.scss (append):
.sidebar-share {
display: flex;
gap: 0.5rem;
font-family: $mono;
font-size: 0.8rem;
margin-top: 0.4rem;
a {
color: $amber-dim;
border: 1px solid $border;
padding: 0.15rem 0.4rem;
&:hover { color: $amber; border-color: $amber; }
&:visited { color: $amber-dim; }
}
}
- Step 5: Add import to
style.scss
Add @import "article"; after @import "post";.
- Step 6: Verify article page
Navigate to any article (e.g., http://localhost:4000/eclipse-collections/) — verify:
- Breadcrumb
~/dev/java/slug $in amber monospace above title - Logo is small (36px) left of title
- Title is large Monda, white
- Body text is Monda,
#E0E0E0 h2headings show##prefix in amberh3headings show###prefix-
[COMMENTS ▼]button at bottom, clicks to expand Disqus - Step 7: Commit
git add _sass/_article.scss _sass/_post.scss _layouts/post.html _includes/post-aside.html style.scss
git commit -m "style: article page — breadcrumb, Monda body, ## heading prefix, collapsible comments"
Task 9: Effects Cleanup
Files:
-
Rewrite:
_sass/_fx.scss(keep.preformatted, remove glitch/chrome/street/flickering) -
Step 1: Rewrite
_sass/_fx.scss
// CRT terminal code block — keep as-is (core retro feature)
.preformatted {
font-family: "Share Tech Mono", monospace;
color: #00ff00;
background-color: black;
background-image:
repeating-linear-gradient(0deg,rgba(0,0,0,0.95),rgba(0,0,0,0.15) 1px, transparent 1px, transparent 2px),
radial-gradient(rgba(0, 150, 0, 0.75), black 120%);
padding: 7px 7px 7px 10px;
border: 1px solid $amber;
border-radius: 0;
box-shadow: none;
margin: 1em 0;
white-space: pre;
overflow: auto;
tab-size: 4;
-moz-tab-size: 4;
text-shadow: 0 0 5px #C8C8C8;
}
.nowrap { white-space: nowrap; }
.fakescreen {
margin-left: 2em;
border: solid $border 2px;
border-radius: 0;
}
- Step 2: Remove
hover.cssclass references in templates
Search for hvr- class usage still in templates:
grep -r "hvr-" _layouts/ _includes/ --include="*.html"
Remove any remaining hvr-* class attributes found (they reference the now-removed hover.css).
- Step 3: Verify code blocks
Open any article with code — verify:
- Code blocks are green-on-black with CRT scanline effect
- Border is 1px amber (not the old
#339933green border) -
No
box-shadowlift - Step 4: Commit
git add _sass/_fx.scss
git commit -m "style: fx cleanup — keep CRT code block, remove glitch/chrome/street effects"
Task 10: Footer
Files:
- Create:
_sass/_footer.scss - Modify:
_layouts/default.html(footer HTML) -
Modify:
style.scss(add import, remove inline.wrapper-footer) - Step 1: Create
_sass/_footer.scss
.wrapper-footer {
border-top: 1px solid $border;
background: $bg-body;
margin-top: 2rem;
}
footer {
font-family: $mono;
font-size: 0.75rem;
padding: 1rem;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 0.5rem;
color: $amber-dim;
@include mobile {
flex-direction: column;
text-align: center;
}
a {
color: $amber-dim;
border: 1px solid $border;
padding: 0.1rem 0.35rem;
font-family: $mono;
transition: color 0.15s, border-color 0.15s;
&:hover { color: $amber; border-color: $amber; }
&:visited { color: $amber-dim; }
}
.footer-links {
display: flex;
gap: 0.4rem;
flex-wrap: wrap;
align-items: center;
}
.footer-legal {
color: $amber-dim;
opacity: 0.6;
}
}
- Step 2: Update footer HTML in
_layouts/default.html
Replace the <div class="wrapper-footer"> block with:
<div class="wrapper-footer">
<div class="container">
<footer>
<div class="footer-links">
<a href="https://github.com/fxrobin/" target="_blank" rel="nofollow">[gh]</a>
<a href="https://www.linkedin.com/in/fxrobin/" target="_blank" rel="nofollow">[li]</a>
<a href="https://stackoverflow.com/users/3017541/fxrobin" target="_blank" rel="nofollow">[so]</a>
<a href="/feed.xml">[rss]</a>
<img src="/images/creative-commons/by-sa.svg" alt="CC:BY-SA" style="height:14px; opacity:0.5;" />
</div>
<div class="footer-legal">
FX Robin · CC BY-SA · ref:[]
</div>
</footer>
</div>
</div>
- Step 3: Update
style.scss
Add @import "footer"; and remove the inline .wrapper-footer block from style.scss.
- Step 4: Verify footer
Open http://localhost:4000 — footer shows:
- Single line, near-black background, amber-dim text
[gh] [li] [so] [rss]links with box borders-
CC-BY-SA icon + legal text right side
- Step 5: Commit
git add _sass/_footer.scss _layouts/default.html style.scss
git commit -m "style: minimal VT-100 footer — text link social buttons, amber monospace"
Task 11: Final Cleanup
Files:
- Delete:
_sass/_article-list-post-footer.scss - Modify:
style.scss(remove dead imports, final import order) -
Modify:
_sass/_front-post.scss(empty/stub — kept for safety, all rules replaced by_cards.scss) - Step 1: Empty
_sass/_front-post.scss
Replace file contents with a single comment:
// Replaced by _cards.scss in VT-100 redesign
- Step 2: Update
style.scssfinal import order
Replace the style.scss content after .clearfix with a clean, ordered import list:
// Layout
@import "header";
@import "sidebar";
@import "footer";
@import "nav";
// Content
@import "cards";
@import "article";
@import "post";
@import "front-post";
@import "table-of-content";
// Components
@import "search";
@import "share";
@import "languages";
@import "disqus";
@import "video";
@import "article-list";
@import "retro-list";
@import "blanka";
@import "stackoverflow";
@import "back-to-top";
@import "gurumeditation";
// Utilities
@import "highlights";
@import "svg-icons";
@import "fx";
Remove: @import "article-list-post-footer";
- Step 3: Delete deprecated file
rm _sass/_article-list-post-footer.scss
Also update style.scss to remove that import if still present.
- Step 4: Full build verify
docker run -v $(pwd):/srv/jekyll -v $(pwd)/_site:/srv/jekyll/_site \
jekyll/builder:latest /bin/bash -c "chmod 777 /srv/jekyll && jekyll build --future"
Expected: Build succeeds, zero SCSS errors.
- Step 5: Cross-page visual check
Open each page and verify:
- http://localhost:4000 — index: cards render, sidebar visible, nav active item blinking
- http://localhost:4000/retro-programming/ —
/dev/retrocards - http://localhost:4000/blanka-cave/fr/ —
/dev/blankacards - Any article — breadcrumb, Monda body,
##headings, collapsible comments -
Mobile (resize to 400px) — sidebar hidden, content full width, header stacks
- Step 6: Final commit
git add -A
git commit -m "style: VT-100 hybrid redesign complete — cleanup, final import order"
Self-Review
Spec coverage check
| Spec section | Task |
|---|---|
| Color tokens | Task 1 |
| Typography | Task 1 |
| Cursor | Task 1 (retained in base-rules) |
| Layout: split-pane | Task 4 |
| Header: typewriter, scanlines, lang toggle | Task 3 |
| Sidebar: nav, search, tags | Tasks 4, 5, 6 |
Nav /dev/* labels |
Task 5 |
| Active nav blink cursor | Task 5 |
| Phosphor glow on hover | Task 3, 5 |
| Article cards: Unicode box | Task 7 |
| Cards: path/date/title/excerpt/tags/CTA | Task 7 |
| Pagination | Task 7 |
| Article page: breadcrumb | Task 8 |
| Article page: Monda body | Task 8 |
h2 ## prefix / h3 ### prefix |
Task 8 |
| Blockquote: amber left border | Task 8 |
TOC: § prefix |
Task 8 |
| Comments: collapsible | Task 8 |
Share: [gh][li][tw] |
Task 8 |
| CRT code block retained | Task 9 |
| Footer: text links | Task 10 |
| Remove: FA, Zocial, hover.css, blink.css | Task 2 |
| Remove: glitch/chrome/street/bg-image | Tasks 1, 9 |
| Mobile responsive | Tasks 3, 4 |