Présentation
Le projet zt propose un système de templating HTML pour le langage Zig. Les templates sont analysés et transpilés en code Zig lors de l’étape zig build, ce qui permet d’importer les fichiers de template comme n’importe quel module Zig. Cette approche garantit que chaque paramètre du template possède un type connu à la compilation.
Architecture et fonctionnement
Le processus se compose de trois étapes : lecture du fichier .zt, génération d’un fichier .zig contenant une fonction render, puis compilation du code généré. La fonction render écrit directement sur un std.Io.Writer, éliminant ainsi toute allocation intermédiaire. Le modèle d’allocation repose sur les arena allocators de Zig, ce qui évite la gestion manuelle de la mémoire pour les chaînes de caractères.
pub templ Layout(title: []const u8) {
{title}
@children
}
Le code ci‑dessus montre la syntaxe d’un template : les balises HTML sont écrites littéralement, les expressions Zig sont encadrées par { }, et le mot‑clé @children insère le contenu d’un sous‑template. Le rendu s’effectue via la fonction générée :
const std = @import("std");
const pages = @import("templates/pages.zig");
pub fn main(init: std.process.Init) !void {
var buf: [4096]u8 = undefined;
var stdout = std.Io.File.stdout().writer(init.io, &buf);
const w = &stdout.interface;
const user = .{ .id = 1, .name = "Lukas" };
try pages.HomePage.render(.{user}, w);
try w.flush();
}
Analyse de performances et de sécurité
Parce que le rendu se résume à une suite d’appels writer.writeAll, le coût d’exécution est comparable à du code C manuel. Aucun tampon temporaire n’est créé, ce qui réduit la pression sur le ramasse‑miettes et améliore la latence dans les serveurs à haut débit. En matière de sécurité, chaque valeur dynamique est automatiquement échappée en HTML, y compris dans les attributs. Les URL sont analysées pour détecter les schémas dangereux, et l’injection de HTML brut n’est possible qu’en utilisant la syntaxe explicite {!value}. Ainsi, la plupart des vecteurs XSS classiques sont neutralisés avant même que le code ne s’exécute.
Limitations et perspectives
Le parseur impose que toutes les balises soient correctement fermées, ce qui empêche la génération accidentelle de markup invalide mais rend impossible l’utilisation de texte brut contenant des mots réservés comme if ou for en début de ligne. Cette contrainte nécessite d’entourer le texte dans une balise ou de le convertir en expression chaîne. De plus, le système ne supporte pas encore les blocs de contrôle écrits avec un préfixe @, ce qui pourrait simplifier la différenciation entre code Zig et texte. Enfin, le modèle actuel ne propose pas de mécanisme de hot‑reload ; toute modification du template requiert une recompilation complète du projet.