ENbext.dev
DocumentationInclusions côté serveur

Traduction automatique depuis l’anglais. Consulter l’original.

Sur cette page

Partiels basés sur des fichiers

Le cas d'utilisation le plus simple : "J'ai un fichier footer.html et je le veux sur chaque page." Pas de point de terminaison, pas de framework, pas d'étape de construction : juste un fichier sur le disque, résolu côté serveur.

html
<!-- bext-native -->
<bext-include src="/_partials/footer.html"></bext-include>

<!-- SSI-compatible -->
<!--#include virtual="/_partials/footer.html" -->

<!-- ESI -->
<esi:include src="/_partials/footer.html" />

Tous les trois lisent à partir du répertoire _partials/ du site, mettent en cache le contenu en mémoire et invalident automatiquement le cache lorsque le fichier change sur le disque.

Le répertoire _partials/#

Par convention, les fragments HTML résident dans {site_root}/_partials/. Ce répertoire est découvert automatiquement au démarrage du serveur.

code
site/
├── _partials/
│   ├── footer.html
│   ├── header.html
│   ├── social-links.html
│   └── legal/
│       ├── privacy.html
│       └── terms.html
├── pages/
│   └── index.html
└── bext.config.toml

Référencez-les avec des chemins absolus :

html
<bext-include src="/_partials/footer.html"></bext-include>
<bext-include src="/_partials/legal/privacy.html"></bext-include>

Règles de résolution#

src Résolu à
/_partials/X {site_root}/_partials/X
SSI file="X" {document_root}/X (par rapport au fichier en cours de diffusion)
SSI virtual="/X" {site_root}/X (relatif au serveur)
/arbitrary/path.html {site_root}/arbitrary/path.html

Le préfixe _partials/ est une convention et non une exigence : tout fichier .html (ou autre extension autorisée) sous la racine du site peut être inclus.

Conseil

L'ajout d'un attribut ttl à un fichier ignore partiellement l'appel stat() — bext sert à partir du cache pour la durée de vie complète sans vérifier l'heure de modification du fichier. Utilisez-le pour les chemins ultra-chauds, mais n'oubliez pas que les modifications de fichiers ne se propageront pas tant que la durée de vie n'aura pas expiré ou que vous n'aurez pas purgé la balise de cache.

Cache basé sur le temps#

Les fichiers sont mis en cache par chemin + mtime :

code
First request to /_partials/footer.html
  → stat file → mtime = 1712000000
  → read file → "<p>...</p>"
  → cache entry: (path, content, mtime)
  → return content

Second request
  → cache has this path
  → stat file → mtime = 1712000000 (unchanged)
  → cache hit → return cached content (no file read)

You edit footer.html
  → file's mtime changes to 1712001234

Third request
  → cache has this path
  → stat file → mtime = 1712001234 (changed!)
  → re-read file
  → update cache with new content and mtime
  → return fresh content

L'appel système stat() dure environ 1 µs sous Linux (atteint principalement le cache d'inodes du noyau). La diffusion partielle d'un fichier mis en cache est dominée par ce coût, et non par le fichier lu.

Mode développement : observateur de fichiers#

En développement ( bext dev ), l'observateur de fichiers surveille le répertoire du site. Les modifications apportées aux fichiers _partials/ déclenchent une invalidation immédiate du cache : vous n'avez même pas besoin de la vérification des statistiques ; l'observateur pousse les invalidations vers le résolveur.

bash
$ bext dev
[bext] watching site/
[bext] change: _partials/footer.html — invalidating include cache

La prochaine demande pour cette partie relit le fichier sans aucune surcharge statistique.

Attention

Seuls les fichiers avec les extensions allowed_extensions (par défaut : html, htm, svg, txt ) sont servis. La tentative d'inclusion d'un fichier .env, .toml ou .json est rejetée avec un avertissement et n'est pas servie en silence.

Sécurité du chemin#

Les fichiers partiels appliquent une désinfection stricte des chemins :

  • Octets nuls dans le chemin : rejetés.
  • Composants .. : rejetés (empêche /_partials/../../etc/passwd ).
  • Liens symboliques en dehors de la racine du site : rejetés (prison de liens symboliques appliquée via canonicalize() ).
  • Barre oblique de début : traité comme relatif au serveur (racine du site).
html
<!-- All rejected -->
<bext-include src="/_partials/../../etc/passwd"></bext-include>
<bext-include src="/../../etc/passwd"></bext-include>
<bext-include src="/_partials/\0hidden"></bext-include>

Limites de taille et d’extension#

toml
[include.files]
enabled = true
max_size = "1MB"
allowed_extensions = ["html", "htm", "svg", "txt"]
  • max_size : les fichiers plus volumineux sont rejetés avec un avertissement. Les inclusions concernent des fragments et non des pages complètes.
  • allowed_extensions : seuls les fichiers avec ces extensions sont résolus. Empêche l'insertion accidentelle de fichiers de configuration, de secrets, etc.

Extensions par défaut : html, htm, svg, txt. Ajoutez md si vous souhaitez que Markdown soit inclus, mais bext ne transformera pas le contenu – vous verrez Markdown brut dans le HTML.

Fichiers non UTF-8#

Les fichiers partiels sont traités comme du HTML UTF-8. Les fichiers qui ne sont pas UTF-8 valides (fichiers binaires, encodages non UTF) sont rejetés :

code
WARN file partial not UTF-8: /_partials/logo.png — skipping

Pour les logos SVG, le fichier est un valide UTF-8 (texte XML), il fonctionne donc bien comme fichier partiel. Pour les fichiers binaires réels, utilisez <img>, non inclus.

Combinaison avec TTL#

Les fichiers partiels utilisent mtime pour la fraîcheur par défaut – aucun TTL n'est nécessaire. Mais vous pouvez en ajouter un pour ignorer complètement la vérification des statistiques :

html
<bext-include src="/_partials/footer.html"
  ttl="1h"
></bext-include>

Avec ttl="1h", bext ne déclare même pas le fichier - il est quand même utilisé à partir du cache pendant une heure. Compromis : les modifications de fichiers prennent jusqu'à une heure pour se propager (sauf si elles sont explicitement purgées via l'API de purge du cache).

Ceci est principalement utile pour les chemins très chauds où même la statistique de 1 µs vaut la peine d'être ignorée.

Combinaison avec d'autres attributs#

Les fichiers partiels fonctionnent avec toutes les autres fonctionnalités d'inclusion :

html
<bext-include src="/_partials/user-profile.html"
  auth="required"
  vary="role"
  ttl="5m"
></bext-include>

Le contenu du fichier est mis en cache par rôle. Les utilisateurs anonymes voient la solution de repli. Chaque rôle authentifié obtient sa propre copie mise en cache.

Inclut imbriqué#

Un fichier partiel peut contenir d'autres inclusions :

html
<!-- _partials/footer.html -->
<footer>
  <p>&copy; 2026 Example</p>
  <bext-include src="/_partials/social-links.html"></bext-include>
</footer>

Lorsque footer.html est résolu, bext continue de rechercher les inclusions imbriquées. La configuration de sécurité limite la profondeur d'imbrication (par défaut : 3) pour éviter la récursion :

toml
[include.security]
max_depth = 3

Un fichier qui s'inclut lui-même (directement ou de manière transitive) est délimité en toute sécurité.

Migration SSI#

Si vous migrez depuis nginx avec SSI, vos balises <!--#include --> existantes fonctionnent inchangées :

html
<!-- works exactly as it did under nginx -->
<body>
  <!--#include virtual="/includes/header.html" -->
  <main>...</main>
  <!--#include virtual="/includes/footer.html" -->
</body>

bext résout les deux balises du système de fichiers. L'invalidation du cache et de mtime est automatique.

Vous bénéficiez également de toutes les autres fonctionnalités incluses de bext : ajoutez ttl via les règles de configuration, utilisez SSI avec <bext-include>, l'authentification de couche ou les expériences via la configuration.

Voir aussi#

Modifier cette page ↗Besoin d’aide ? ↗
Rechercher dans la documentation

Saisissez un sujet, une commande ou une question.