{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Cecil - Documentation",
  "home_page_url": "https://cecil-945.pages.dev/fr/documentation/",
  "feed_url": "https://cecil-945.pages.dev/fr/documentation/feed.json",
  "description": "Documentation du générateur de site statique Cecil.",
  "icon": "https://cecil-945.pages.dev/favicon.7ff4b89eec6dad139a7d2d6561543285.png",
  "favicon": "https://cecil-945.pages.dev/thumbnails/64x/favicon.7ff4b89eec6dad139a7d2d6561543285.png",
  "language": "fr",
  "items": [
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/bien-demarrer/installation/",
      "url": "https://cecil-945.pages.dev/fr/documentation/bien-demarrer/installation/",
      "title": "Installation",
      "summary": "Prérequis, méthodes d’installation (PHAR, binaire autonome, gestionnaires de paquets, Composer), mise à jour et dépannage.",
      "date_published": "2026-10-05T00:00:00+00:00",
      "date_modified": "2026-10-13T00:00:00+00:00","content_text": "Installation\nCecil est distribué sous la forme d’un unique fichier exécutable, cecil.phar, qui fonctionne partout où PHP est installé, ainsi que sous forme de binaires autonomes qui ne nécessitent pas PHP.\nPrérequis\n\nPHP 8.3+\nExtensions PHP : fileinfo, gd et mbstring\n\nVérifiez votre version de PHP et les extensions chargées :\nphp -v\nphp -m\nExtensions optionnelles\n\n\n\nExtension\nUsage\n\n\n\n\nintl\nLocalisation des dates avec d’autres locales que en (améliore les performances sinon).\n\n\nimagick\nTraitement des images, préféré à GD si disponible.\n\n\nffi\nTraitement des images avec libvips (nécessite une installation via Composer).\n\n\n\nTélécharger le PHAR\nTéléchargez cecil.phar depuis votre terminal :\ncurl -LO https:\/\/cecil.app\/cecil.phar\nPuis exécutez-le avec PHP :\nphp cecil.phar --version\nVous pouvez également télécharger une version spécifique ou la version d’aperçu.\nBinaire autonome\nSi PHP n’est pas installé, téléchargez le binaire autonome correspondant à votre plateforme depuis la dernière version GitHub. Il embarque PHP et les extensions requises.\n\n\n\nPlateforme\nFichier\n\n\n\n\nLinux x64\ncecil-linux-x64\n\n\nLinux ARM64\ncecil-linux-arm64\n\n\nmacOS Intel\ncecil-macos-x64\n\n\nmacOS Apple Silicon\ncecil-macos-arm64\n\n\nWindows x64\ncecil-windows-x64.exe\n\n\n\nPar exemple, sous Linux x64 :\ncurl -Lo cecil https:\/\/github.com\/Cecilapp\/Cecil\/releases\/latest\/download\/cecil-linux-x64\nchmod +x cecil\n.\/cecil --version\nSous macOS, les binaires ne sont pas signés : supprimez l’attribut de quarantaine avant la première exécution avec xattr -d com.apple.quarantine cecil.\nLes sommes de contrôle SHA-256 sont disponibles dans le fichier cecil-binaries.sha256 de chaque version, et la provenance du build peut être vérifiée avec gh attestation verify cecil --repo Cecilapp\/Cecil.\nLe binaire utilise GD pour le traitement des images : Imagick et libvips ne sont pas disponibles. La commande self-update n’est pas disponible non plus : téléchargez à nouveau le binaire pour le mettre à jour.\nLa commande serve repose sur le serveur web intégré de PHP, que le binaire n’embarque pas : elle nécessite un exécutable PHP local. Sans PHP, exécutez la commande build et servez le dossier de sortie avec un autre serveur web.\nInstallation globale\nInstaller Cecil globalement permet d’exécuter la commande cecil depuis n’importe quel dossier, au lieu de php cecil.phar.\nmacOS et Linux\nAvec Homebrew :\nbrew install cecilapp\/tap\/cecil\nOu manuellement, en déplaçant le PHAR dans un dossier de votre PATH :\nmv cecil.phar \/usr\/local\/bin\/cecil\nchmod +x \/usr\/local\/bin\/cecil\nWindows\nAvec Scoop :\nscoop install https:\/\/cecil.app\/scoop\/cecil.json\nOu manuellement :\n\nDéplacez cecil.phar dans un dossier dédié tel que C:\\bin\nRenommez cecil.phar en cecil\nAjoutez ;C:\\bin à votre variable d’environnement PATH\nCréez un « wrapping batch script » à côté\n\nPHIVE\nAvec PHIVE (The PHAR Installation and Verification Environment) :\nphive install cecil\nComposer\nAvec Composer :\ncomposer global require cecil\/cecil\nAssurez-vous que le dossier des binaires globaux de Composer est dans votre PATH. Exécutez composer global config bin-dir --absolute pour l’obtenir.\nPour utiliser Cecil comme dépendance d’un projet PHP, voir Bibliothèque.\nVérifier l’installation\ncecil --version\nExécutez cecil list pour afficher les commandes disponibles.\nMise à jour\nMettez à jour Cecil vers la dernière version selon votre méthode d’installation :\n# PHAR\nphp cecil.phar self-update\n# Homebrew\nbrew upgrade cecilapp\/tap\/cecil\n# Scoop\nscoop update cecil\n# PHIVE\nphive update cecil\n# Composer\ncomposer global update cecil\/cecil\nLe binaire autonome se met à jour en le téléchargeant à nouveau.\nLa commande self-update (PHAR uniquement) accepte également les options suivantes :\n\n--rollback : revient à la version précédemment installée\n--stable : force la mise à jour vers la dernière version stable\n--preview : force la mise à jour vers la dernière version instable\n\nLe journal des modifications de chaque version est disponible sur GitHub.\nDépannage\ncommand not found: cecil\nLe dossier d’installation n’est pas dans votre PATH : ajoutez-le, ou exécutez Cecil avec php cecil.phar depuis le dossier contenant le PHAR.\nErreur de version ou d’extension PHP\nLe PHP utilisé en ligne de commande peut différer de celui attendu (plusieurs versions installées) : vérifiez-le avec php -v et php --ini, puis activez les extensions manquantes dans le fichier php.ini chargé.\nDiagnostiquer un site\nUne fois un site créé, exécutez la commande doctor pour diagnostiquer sa configuration.",
      "content_html": "<h1>Installation</h1>\n<p>Cecil est distribué sous la forme d’un unique fichier exécutable, <code translate=\"no\">cecil.phar</code>, qui fonctionne partout où PHP est installé, ainsi que sous forme de <a href=\"#standalone-binary\">binaires autonomes</a> qui ne nécessitent pas PHP.</p>\n<h2 id=\"prerequis\">Prérequis</h2>\n<ul>\n<li><a href=\"https://www.php.net/manual/fr/install.php\" target=\"_blank\" rel=\"noopener noreferrer\">PHP</a> 8.3+</li>\n<li>Extensions PHP : <code translate=\"no\">fileinfo</code>, <code translate=\"no\">gd</code> et <code translate=\"no\">mbstring</code></li>\n</ul>\n<p>Vérifiez votre version de PHP et les extensions chargées :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php -v\nphp -m</code></pre>\n<h3 id=\"extensions-optionnelles\">Extensions optionnelles</h3>\n<table>\n<thead>\n<tr>\n<th>Extension</th>\n<th>Usage</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><a href=\"https://www.php.net/manual/fr/book.intl.php\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">intl</code></a></td>\n<td><a href=\"../templates/5-localization.fr.md\">Localisation</a> des dates avec d’autres locales que <code translate=\"no\">en</code> (améliore les performances sinon).</td>\n</tr>\n<tr>\n<td><a href=\"https://www.php.net/manual/fr/book.imagick.php\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">imagick</code></a></td>\n<td>Traitement des images, préféré à GD si disponible.</td>\n</tr>\n<tr>\n<td><a href=\"https://www.php.net/manual/fr/book.ffi.php\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">ffi</code></a></td>\n<td>Traitement des images avec <a href=\"https://www.libvips.org/\" target=\"_blank\" rel=\"noopener noreferrer\">libvips</a> (nécessite une <a href=\"#composer\">installation via Composer</a>).</td>\n</tr>\n</tbody>\n</table>\n<h2 id=\"telecharger-le-phar\">Télécharger le PHAR</h2>\n<p>Téléchargez <code translate=\"no\">cecil.phar</code> depuis votre terminal :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">curl -LO https://cecil.app/cecil.phar</code></pre>\n<p>Puis exécutez-le avec PHP :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar --version</code></pre>\n<aside class=\"note note-info\"><p>Vous pouvez également télécharger une <a href=\"/fr/telecharger/\">version spécifique ou la version d’aperçu</a>.</p></aside>\n<h2 id=\"standalone-binary\">Binaire autonome</h2>\n<p>Si PHP n’est pas installé, téléchargez le binaire autonome correspondant à votre plateforme depuis la <a href=\"https://github.com/Cecilapp/Cecil/releases/latest\" target=\"_blank\" rel=\"noopener noreferrer\">dernière version GitHub</a>. Il embarque PHP et les extensions requises.</p>\n<table>\n<thead>\n<tr>\n<th>Plateforme</th>\n<th>Fichier</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Linux x64</td>\n<td><code translate=\"no\">cecil-linux-x64</code></td>\n</tr>\n<tr>\n<td>Linux ARM64</td>\n<td><code translate=\"no\">cecil-linux-arm64</code></td>\n</tr>\n<tr>\n<td>macOS Intel</td>\n<td><code translate=\"no\">cecil-macos-x64</code></td>\n</tr>\n<tr>\n<td>macOS Apple Silicon</td>\n<td><code translate=\"no\">cecil-macos-arm64</code></td>\n</tr>\n<tr>\n<td>Windows x64</td>\n<td><code translate=\"no\">cecil-windows-x64.exe</code></td>\n</tr>\n</tbody>\n</table>\n<p>Par exemple, sous Linux x64 :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">curl -Lo cecil https://github.com/Cecilapp/Cecil/releases/latest/download/cecil-linux-x64\nchmod +x cecil\n./cecil --version</code></pre>\n<p>Sous macOS, les binaires ne sont pas signés : supprimez l’attribut de quarantaine avant la première exécution avec <code translate=\"no\">xattr -d com.apple.quarantine cecil</code>.</p>\n<aside class=\"note note-info\"><p>Les sommes de contrôle SHA-256 sont disponibles dans le fichier <code translate=\"no\">cecil-binaries.sha256</code> de chaque version, et la provenance du build peut être vérifiée avec <code translate=\"no\">gh attestation verify cecil --repo Cecilapp/Cecil</code>.</p></aside>\n<aside class=\"note note-important\"><p>Le binaire utilise GD pour le traitement des images : Imagick et libvips ne sont pas disponibles. La commande <code translate=\"no\">self-update</code> n’est pas disponible non plus : téléchargez à nouveau le binaire pour le mettre à jour.</p>\n<p>La commande <code translate=\"no\">serve</code> repose sur le serveur web intégré de PHP, que le binaire n’embarque pas : elle nécessite un exécutable PHP local. Sans PHP, exécutez la commande <code translate=\"no\">build</code> et servez le dossier de sortie avec un autre serveur web.</p></aside>\n<h2 id=\"installation-globale\">Installation globale</h2>\n<p>Installer Cecil globalement permet d’exécuter la commande <code translate=\"no\">cecil</code> depuis n’importe quel dossier, au lieu de <code translate=\"no\">php cecil.phar</code>.</p>\n<h3 id=\"macos-et-linux\">macOS et Linux</h3>\n<p>Avec <a href=\"https://brew.sh\" target=\"_blank\" rel=\"noopener noreferrer\">Homebrew</a> :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">brew install cecilapp/tap/cecil</code></pre>\n<p>Ou manuellement, en déplaçant le PHAR dans un dossier de votre <code translate=\"no\">PATH</code> :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">mv cecil.phar /usr/<span class=\"hljs-built_in\">local</span>/bin/cecil\nchmod +x /usr/<span class=\"hljs-built_in\">local</span>/bin/cecil</code></pre>\n<h3 id=\"windows\">Windows</h3>\n<p>Avec <a href=\"https://scoop.sh\" target=\"_blank\" rel=\"noopener noreferrer\">Scoop</a> :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">scoop install https://cecil.app/scoop/cecil.json</code></pre>\n<p>Ou manuellement :</p>\n<ol>\n<li>Déplacez <code translate=\"no\">cecil.phar</code> dans un dossier dédié tel que <code translate=\"no\">C:\\bin</code></li>\n<li>Renommez <code translate=\"no\">cecil.phar</code> en <code translate=\"no\">cecil</code></li>\n<li>Ajoutez <code translate=\"no\">;C:\\bin</code> à votre variable d’environnement <code translate=\"no\">PATH</code></li>\n<li>Créez un <a href=\"https://raw.githubusercontent.com/Cecilapp/Cecil/main/bin/cecil.bat\" target=\"_blank\" rel=\"noopener noreferrer\">« wrapping batch script »</a> à côté</li>\n</ol>\n<h3 id=\"phive\">PHIVE</h3>\n<p>Avec <a href=\"https://phar.io\" target=\"_blank\" rel=\"noopener noreferrer\">PHIVE</a> (The PHAR Installation and Verification Environment) :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">phive install cecil</code></pre>\n<h3 id=\"composer\">Composer</h3>\n<p>Avec <a href=\"https://getcomposer.org\" target=\"_blank\" rel=\"noopener noreferrer\">Composer</a> :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">composer global require cecil/cecil</code></pre>\n<aside class=\"note note-important\"><p>Assurez-vous que le dossier des binaires globaux de Composer est dans votre <code translate=\"no\">PATH</code>. Exécutez <code translate=\"no\">composer global config bin-dir --absolute</code> pour l’obtenir.</p></aside>\n<aside class=\"note note-tip\"><p>Pour utiliser Cecil comme dépendance d’un projet PHP, voir <a href=\"../developers/2-library.fr.md\">Bibliothèque</a>.</p></aside>\n<h2 id=\"verifier-l-installation\">Vérifier l’installation</h2>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">cecil --version</code></pre>\n<aside class=\"note note-info\"><p>Exécutez <code translate=\"no\">cecil list</code> pour afficher les <a href=\"../commands/index.fr.md\">commandes disponibles</a>.</p></aside>\n<h2 id=\"mise-a-jour\">Mise à jour</h2>\n<p>Mettez à jour Cecil vers la dernière version selon votre méthode d’installation :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\"><span class=\"hljs-comment\"># PHAR</span>\nphp cecil.phar self-update\n<span class=\"hljs-comment\"># Homebrew</span>\nbrew upgrade cecilapp/tap/cecil\n<span class=\"hljs-comment\"># Scoop</span>\nscoop update cecil\n<span class=\"hljs-comment\"># PHIVE</span>\nphive update cecil\n<span class=\"hljs-comment\"># Composer</span>\ncomposer global update cecil/cecil</code></pre>\n<p>Le <a href=\"#standalone-binary\">binaire autonome</a> se met à jour en le téléchargeant à nouveau.</p>\n<p>La commande <code translate=\"no\">self-update</code> (PHAR uniquement) accepte également les options suivantes :</p>\n<ul>\n<li><code translate=\"no\">--rollback</code> : revient à la version précédemment installée</li>\n<li><code translate=\"no\">--stable</code> : force la mise à jour vers la dernière version stable</li>\n<li><code translate=\"no\">--preview</code> : force la mise à jour vers la dernière version instable</li>\n</ul>\n<aside class=\"note note-info\"><p>Le journal des modifications de chaque version est disponible sur <a href=\"https://github.com/Cecilapp/Cecil/releases\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub</a>.</p></aside>\n<h2 id=\"depannage\">Dépannage</h2>\n<h3 id=\"command-not-found-cecil\"><code translate=\"no\">command not found: cecil</code></h3>\n<p>Le dossier d’installation n’est pas dans votre <code translate=\"no\">PATH</code> : ajoutez-le, ou exécutez Cecil avec <code translate=\"no\">php cecil.phar</code> depuis le dossier contenant le PHAR.</p>\n<h3 id=\"erreur-de-version-ou-d-extension-php\">Erreur de version ou d’extension PHP</h3>\n<p>Le PHP utilisé en ligne de commande peut différer de celui attendu (plusieurs versions installées) : vérifiez-le avec <code translate=\"no\">php -v</code> et <code translate=\"no\">php --ini</code>, puis activez les extensions manquantes dans le fichier <code translate=\"no\">php.ini</code> chargé.</p>\n<h3 id=\"diagnostiquer-un-site\">Diagnostiquer un site</h3>\n<p>Une fois un site créé, exécutez la commande <a href=\"../commands/5-doctor.fr.md\"><code translate=\"no\">doctor</code></a> pour diagnostiquer sa configuration.</p>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/developpeurs/architecture/",
      "url": "https://cecil-945.pages.dev/fr/documentation/developpeurs/architecture/",
      "title": "Architecture",
      "summary": "Diagramme du processus de génération et composants clés.",
      "date_published": "2026-05-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Architecture\nCette page présente une vue d’ensemble du pipeline de construction de Cecil et de ses composants clés.\nDiagramme\ngraph TD\n    %% Entrée\n    CLI[\"bin\/cecil\\n(Point d'entrée CLI)\"]\n    APP[\"Application\\n(Symfony Console)\"]\n    CMD[\"Commandes\\nbuild \/ serve \/ new:site\\nnew:page \/ clear \/ show:content\"]\n\n    CLI --&gt; APP --&gt; CMD\n\n    %% Orchestrateur\n    BUILDER[\"Builder\\n(Orchestrateur)\"]\n    CONFIG[\"Configuration\\n(config.yml + default.php\\n+ thèmes)\"]\n    CMD --&gt; BUILDER\n    CONFIG --&gt; BUILDER\n\n    %% Pipeline\n    subgraph PIPELINE[\"Pipeline de génération (étapes)\"]\n        S1[\"1. Pages\/Load\\n(Finder → fichiers Markdown)\"]\n        S2[\"2. Data\/Load\\n(fichiers YAML)\"]\n        S3[\"3. StaticFiles\/Load\\n(chargement des fichiers statiques)\"]\n        S4[\"4. Pages\/Create\\n(création des objets Page)\"]\n        S5[\"5. Pages\/Convert\\n(Markdown → HTML\\nfront matter)\"]\n        S6[\"6. Taxonomies\/Create\\n(création des taxonomies)\"]\n        S7[\"7. Pages\/Generate\\n(générateurs)\"]\n        S8[\"8. Menus\/Create\\n(création des menus)\"]\n        S9[\"9. StaticFiles\/Copy\\n(copie des fichiers statiques)\"]\n        S10[\"10. Pages\/Render\\n(rendu Twig)\"]\n        S11[\"11. Pages\/Save\\n(sauvegarde des pages)\"]\n        S12[\"12. Assets\/Save\\n(sauvegarde des assets)\"]\n        S13[\"13. Optimize\/*\\n(optimisation HTML\/CSS\/JS\/Images)\"]\n\n        S1 --&gt; S2 --&gt; S3 --&gt; S4 --&gt; S5 --&gt; S6 --&gt; S7 --&gt; S8 --&gt; S9 --&gt; S10 --&gt; S11 --&gt; S12 --&gt; S13\n    end\n\n    BUILDER --&gt; PIPELINE\n\n    %% Sous-systèmes\n    subgraph COLLECTIONS[\"Collections\"]\n        PC[\"PagesCollection\\n(objets Page)\"]\n        TC[\"TaxonomiesCollection\\n(vocabulaires\/termes)\"]\n        MC[\"MenusCollection\"]\n    end\n\n    subgraph GENERATORS[\"Générateurs (virtuels)\"]\n        GP[\"Pagination\"]\n        GT[\"Taxonomie\"]\n        GS[\"Section\"]\n        GR[\"Redirection\"]\n        GD[\"DefaultPages (accueil, 404)\"]\n    end\n\n    subgraph RENDERER[\"Rendu Twig\"]\n        TW[\"Moteur Twig\"]\n        EXT[\"Extensions\\n(Core, Content, Collection)\"]\n        PP[\"PostProcessors\\n(métadonnées, extraits, liens)\"]\n        TH[\"Thèmes \/ Layouts\"]\n        TW --&gt; EXT\n        TW --&gt; PP\n        TH --&gt; TW\n    end\n\n    subgraph ASSETS[\"Assets\"]\n        AL[\"Localisateur d'assets\"]\n        AC[\"Compilateur\\n(SCSS → CSS)\"]\n        AI[\"Processeur d'images\\n(responsive, WebP, AVIF)\"]\n        AO[\"Optimiseur\\n(minification CSS\/JS)\"]\n    end\n\n    subgraph OUTPUT[\"Sortie (_site\/)\"]\n        HTML[\"pages .html\"]\n        CSS2[\"assets CSS\/JS\"]\n        IMG[\"images\"]\n        SF[\"fichiers statiques\"]\n    end\n\n    S4 --&gt; PC\n    S6 --&gt; TC\n    S8 --&gt; MC\n    S7 --&gt; GENERATORS\n    GENERATORS --&gt; PC\n    S10 --&gt; RENDERER\n    S12 --&gt; ASSETS\n\n    PC --&gt; RENDERER\n    TC --&gt; RENDERER\n    MC --&gt; RENDERER\n\n    RENDERER --&gt; S11\n    S11 --&gt; HTML\n    S12 --&gt; CSS2\n    S12 --&gt; IMG\n    S9 --&gt; SF\n\n    %% Entrées\n    subgraph INPUT[\"Sources\"]\n        MD[\"content\/\\n(Markdown + front matter)\"]\n        DATA[\"data\/\\n(YAML)\"]\n        STATIC[\"static\/\"]\n        LAYOUTS[\"layouts\/\\n(modèles Twig)\"]\n    end\n\n    MD --&gt; S1\n    DATA --&gt; S2\n    STATIC --&gt; S3\n    LAYOUTS --&gt; TH\nLégende des composants clés\n\n\n\nComposant\nRôle\n\n\n\n\nBuilder\nOrchestrateur central, exécute les étapes en séquence\n\n\nConfig\nFusion de la configuration par défaut + thème + projet + CLI\n\n\nSteps\nPipeline modulaire (13 étapes), chacune avec init() \/ canProcess() \/ process()\n\n\nCollections\nPages, Taxonomies, Menus — structures de données centrales\n\n\nGenerators\nCréent des pages virtuelles (pagination, tags, redirections…)\n\n\nRenderer (Twig)\nApplique les modèles + extensions + post-traitements\n\n\nAssets\nCompile SCSS, optimise images, fingerprinte les fichiers\n\n\n",
      "content_html": "<h1>Architecture</h1>\n<p>Cette page présente une vue d’ensemble du pipeline de construction de Cecil et de ses composants clés.</p>\n<h2 id=\"diagramme\">Diagramme</h2>\n<pre><code class=\"language-mermaid\" translate=\"no\">graph TD\n    %% Entrée\n    CLI[\"bin/cecil\\n(Point d'entrée CLI)\"]\n    APP[\"Application\\n(Symfony Console)\"]\n    CMD[\"Commandes\\nbuild / serve / new:site\\nnew:page / clear / show:content\"]\n\n    CLI --&gt; APP --&gt; CMD\n\n    %% Orchestrateur\n    BUILDER[\"Builder\\n(Orchestrateur)\"]\n    CONFIG[\"Configuration\\n(config.yml + default.php\\n+ thèmes)\"]\n    CMD --&gt; BUILDER\n    CONFIG --&gt; BUILDER\n\n    %% Pipeline\n    subgraph PIPELINE[\"Pipeline de génération (étapes)\"]\n        S1[\"1. Pages/Load\\n(Finder → fichiers Markdown)\"]\n        S2[\"2. Data/Load\\n(fichiers YAML)\"]\n        S3[\"3. StaticFiles/Load\\n(chargement des fichiers statiques)\"]\n        S4[\"4. Pages/Create\\n(création des objets Page)\"]\n        S5[\"5. Pages/Convert\\n(Markdown → HTML\\nfront matter)\"]\n        S6[\"6. Taxonomies/Create\\n(création des taxonomies)\"]\n        S7[\"7. Pages/Generate\\n(générateurs)\"]\n        S8[\"8. Menus/Create\\n(création des menus)\"]\n        S9[\"9. StaticFiles/Copy\\n(copie des fichiers statiques)\"]\n        S10[\"10. Pages/Render\\n(rendu Twig)\"]\n        S11[\"11. Pages/Save\\n(sauvegarde des pages)\"]\n        S12[\"12. Assets/Save\\n(sauvegarde des assets)\"]\n        S13[\"13. Optimize/*\\n(optimisation HTML/CSS/JS/Images)\"]\n\n        S1 --&gt; S2 --&gt; S3 --&gt; S4 --&gt; S5 --&gt; S6 --&gt; S7 --&gt; S8 --&gt; S9 --&gt; S10 --&gt; S11 --&gt; S12 --&gt; S13\n    end\n\n    BUILDER --&gt; PIPELINE\n\n    %% Sous-systèmes\n    subgraph COLLECTIONS[\"Collections\"]\n        PC[\"PagesCollection\\n(objets Page)\"]\n        TC[\"TaxonomiesCollection\\n(vocabulaires/termes)\"]\n        MC[\"MenusCollection\"]\n    end\n\n    subgraph GENERATORS[\"Générateurs (virtuels)\"]\n        GP[\"Pagination\"]\n        GT[\"Taxonomie\"]\n        GS[\"Section\"]\n        GR[\"Redirection\"]\n        GD[\"DefaultPages (accueil, 404)\"]\n    end\n\n    subgraph RENDERER[\"Rendu Twig\"]\n        TW[\"Moteur Twig\"]\n        EXT[\"Extensions\\n(Core, Content, Collection)\"]\n        PP[\"PostProcessors\\n(métadonnées, extraits, liens)\"]\n        TH[\"Thèmes / Layouts\"]\n        TW --&gt; EXT\n        TW --&gt; PP\n        TH --&gt; TW\n    end\n\n    subgraph ASSETS[\"Assets\"]\n        AL[\"Localisateur d'assets\"]\n        AC[\"Compilateur\\n(SCSS → CSS)\"]\n        AI[\"Processeur d'images\\n(responsive, WebP, AVIF)\"]\n        AO[\"Optimiseur\\n(minification CSS/JS)\"]\n    end\n\n    subgraph OUTPUT[\"Sortie (_site/)\"]\n        HTML[\"pages .html\"]\n        CSS2[\"assets CSS/JS\"]\n        IMG[\"images\"]\n        SF[\"fichiers statiques\"]\n    end\n\n    S4 --&gt; PC\n    S6 --&gt; TC\n    S8 --&gt; MC\n    S7 --&gt; GENERATORS\n    GENERATORS --&gt; PC\n    S10 --&gt; RENDERER\n    S12 --&gt; ASSETS\n\n    PC --&gt; RENDERER\n    TC --&gt; RENDERER\n    MC --&gt; RENDERER\n\n    RENDERER --&gt; S11\n    S11 --&gt; HTML\n    S12 --&gt; CSS2\n    S12 --&gt; IMG\n    S9 --&gt; SF\n\n    %% Entrées\n    subgraph INPUT[\"Sources\"]\n        MD[\"content/\\n(Markdown + front matter)\"]\n        DATA[\"data/\\n(YAML)\"]\n        STATIC[\"static/\"]\n        LAYOUTS[\"layouts/\\n(modèles Twig)\"]\n    end\n\n    MD --&gt; S1\n    DATA --&gt; S2\n    STATIC --&gt; S3\n    LAYOUTS --&gt; TH</code></pre>\n<h2 id=\"legende-des-composants-cles\">Légende des composants clés</h2>\n<table>\n<thead>\n<tr>\n<th>Composant</th>\n<th>Rôle</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Builder</strong></td>\n<td>Orchestrateur central, exécute les étapes en séquence</td>\n</tr>\n<tr>\n<td><strong>Config</strong></td>\n<td>Fusion de la configuration par défaut + thème + projet + CLI</td>\n</tr>\n<tr>\n<td><strong>Steps</strong></td>\n<td>Pipeline modulaire (13 étapes), chacune avec <code translate=\"no\">init()</code> / <code translate=\"no\">canProcess()</code> / <code translate=\"no\">process()</code></td>\n</tr>\n<tr>\n<td><strong>Collections</strong></td>\n<td>Pages, Taxonomies, Menus — structures de données centrales</td>\n</tr>\n<tr>\n<td><strong>Generators</strong></td>\n<td>Créent des pages virtuelles (pagination, tags, redirections…)</td>\n</tr>\n<tr>\n<td><strong>Renderer (Twig)</strong></td>\n<td>Applique les modèles + extensions + post-traitements</td>\n</tr>\n<tr>\n<td><strong>Assets</strong></td>\n<td>Compile SCSS, optimise images, fingerprinte les fichiers</td>\n</tr>\n</tbody>\n</table>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/assets/images/",
      "url": "https://cecil-945.pages.dev/fr/documentation/assets/images/",
      "title": "Images",
      "summary": "Redimensionnez, recadrez et convertissez les images, générez des images responsives et des placeholders.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Images\nCecil fournit des fonctions et filtres Twig pour redimensionner, recadrer et convertir des images, et pour générer des images responsives et des images de substitution.\nimage_srcset\nConstruit l'attribut HTML img srcset (responsive) d'un élément d'image.\n{{ image_srcset(asset) }}\nExemples :\n{% set asset = asset(image_path) %}\n&lt;img src=\"{{ url(asset) }}\" width=\"{{ asset.width }}\" height=\"{{ asset.height }}\" alt=\"\" class=\"asset\" srcset=\"{{ image_srcset(asset) }}\" sizes=\"{{ image_sizes('asset') }}\"&gt;\nimage_sizes\nRenvoie l'attribut HTML img sizes basé sur un nom de classe CSS.\nIl doit être utilisé conjointement avec la fonction image_srcset.\n{{ image_sizes('class') }}\nExemples :\n{% set asset = asset(image_path) %}\n&lt;img src=\"{{ url(asset) }}\" width=\"{{ asset.width }}\" height=\"{{ asset.height }}\" alt=\"\" class=\"asset\" srcset=\"{{ image_srcset(asset) }}\" sizes=\"{{ image_sizes('asset') }}\"&gt;\nimage_from_website\nConstruit l'élément HTML img à partir d'une URL de site Web en extrayant son image d'illustration.\nRetourne null si aucune image n'est trouvée.\n{{ image_from_website('url', {attributs}, {options}) }}\nL'image est recherchée dans le HTML de la page avec les fallbacks suivants, le premier candidat pouvant être téléchargé en tant qu'image est utilisé :\n\nOpen Graph : og:image:secure_url, og:image, og:image:url\nTwitter : twitter:image, twitter:image:src\n&lt;link rel=\"image_src\"&gt;\nMicrodata : itemprop=\"image\"\nJSON-LD : propriété image\nPremière &lt;img&gt; de &lt;article&gt;, &lt;main&gt; ou &lt;body&gt;\n&lt;link rel=\"apple-touch-icon\"&gt;\n&lt;link rel=\"icon\"&gt;\n\nLes URL relatives sont résolues par rapport à &lt;base href&gt; ou à l'URL de la page.\nL'URL de l'image trouvée et l'image téléchargée sont mises en cache (voir cache.assets.remote.ttl).\nOptions :\n\nfallback : chemin (ou URL) de l'image utilisée si aucune image n'est trouvée\nautres options de image (ex. : responsive, formats)\n\nExemples :\n{{ image_from_website('https:\/\/example.com\/page-with-image.html') }}\n\n{# avec une image de fallback #}\n{{ image_from_website('https:\/\/example.com\/', {alt: 'Illustration'}, {fallback: 'images\/default.png'}) }}\nresize\nRedimensionne une image à une largeur (en pixels) ou\/et une hauteur (en pixels) spécifiée.\n\nSi seule la largeur est spécifiée, la hauteur est calculée pour conserver le rapport hauteur\/largeur\nSi seule la hauteur est spécifiée, la largeur est calculée pour conserver le rapport hauteur\/largeur\nSi la largeur et la hauteur sont spécifiées, l'image est redimensionnée pour s'adapter aux dimensions données, l'image est recadrée et centrée si nécessaire\nSi Remove_animation est vrai, toute animation dans l'image (par exemple, GIF) sera supprimée\n\n{{ asset(image_path)|resize(width: width, height: height, remove_animation: bool) }}\nLe fichier original n'est pas modifié et la version redimensionnée est enregistrée sous \/thumbnails\/&lt;width&gt;x&lt;height&gt;\/image.jpg.\nLes fichiers ICO sont supportés : la plus grande icône est redimensionnée et enregistrée dans un fichier ICO à icône unique (compressée en PNG). Les icônes stockées en BMP avec une profondeur de couleur autre que 24 ou 32 bits nécessitent l'extension PHP Imagick : à défaut, le fichier ICO original est conservé et un avertissement est journalisé.\nExemples :\n{{ asset(page.image)|resize(300) }}\n{# equivalent to: #}\n{{ asset(page.image)|resize(width: 300) }}\n{# resizes to 300px width, height auto-calculated to preserve aspect ratio #}\n{{ asset(page.image)|resize(height: 200) }}\n{# resizes to 300px width and 200px height, and crops if necessary #}\n{{ asset(page.image)|resize(300, 200) }}\n{# removes any animation from the image #}\n{{ asset(page.image)|resize(width: 1200, height: 630, remove_animation: true) }}\ncover\nRedimensionne une image à une largeur et une hauteur spécifiées, en la recadrant si nécessaire.\nLe filtre cover est obsolète depuis la version 8.77 et sera supprimé dans les versions futures. Utilisez plutôt le filtre resize, avec les paramètres de largeur et de hauteur.\n{{ asset(image_path)|cover(width, height) }}\nExemple:\n{{ asset(page.image)|cover(1200, 630) }}\nmaskable\nAjoute un remplissage, en pourcentages, à une image pour la rendre masquable.\n{{ asset(image_path)|maskable(padding) }}\nExemple:\n{{ asset('icon.png')|maskable }}\nwebp\nConvertit une image au format WebP.\nExemple:\n&lt;picture&gt;\n    &lt;source type=\"image\/webp\" srcset=\"{{ asset(image_path)|webp }}\"&gt;\n    &lt;img src=\"{{ url(asset(image_path)) }}\" width=\"{{ asset(image_path).width }}\" height=\"{{ asset(image_path).height }}\" alt=\"\"&gt;\n&lt;\/picture&gt;\navif\nConvertit une image au format AVIF.\nExemple:\n&lt;picture&gt;\n    &lt;source type=\"image\/avif\" srcset=\"{{ asset(image_path)|avif }}\"&gt;\n    &lt;img src=\"{{ url(asset(image_path)) }}\" width=\"{{ asset(image_path).width }}\" height=\"{{ asset(image_path).height }}\" alt=\"\"&gt;\n&lt;\/picture&gt;\nlqip\nRenvoie un espace réservé pour une image de faible qualité (100 x 100 px, flou à 50 %) comme URL de données.\n{{ asset(image_path)|lqip }}\ndominant_color\nRenvoie la couleur hexadécimale dominante d'une image.\n{{ asset(image_path)|dominant_color }}",
      "content_html": "<h1>Images</h1>\n<p>Cecil fournit des fonctions et filtres Twig pour redimensionner, recadrer et convertir des images, et pour générer des images responsives et des images de substitution.</p>\n<h2 id=\"image-srcset\">image_srcset</h2>\n<p>Construit l'attribut HTML img <code translate=\"no\">srcset</code> (responsive) d'un élément d'image.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ image_srcset(asset) }}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> asset = asset(image_path) %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(asset) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">width</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset.width }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">height</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset.height }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">alt</span>=<span class=\"hljs-string\">\"\"</span> <span class=\"hljs-attr\">class</span>=<span class=\"hljs-string\">\"asset\"</span> <span class=\"hljs-attr\">srcset</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ image_srcset(asset) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">sizes</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ image_sizes('asset') }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span></code></pre>\n<h2 id=\"image-sizes\">image_sizes</h2>\n<p>Renvoie l'attribut HTML img <code translate=\"no\">sizes</code> basé sur un nom de classe CSS.\nIl doit être utilisé conjointement avec la fonction <a href=\"1-images.fr.md#image-srcset\"><code translate=\"no\">image_srcset</code></a>.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ image_sizes('class') }}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> asset = asset(image_path) %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(asset) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">width</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset.width }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">height</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset.height }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">alt</span>=<span class=\"hljs-string\">\"\"</span> <span class=\"hljs-attr\">class</span>=<span class=\"hljs-string\">\"asset\"</span> <span class=\"hljs-attr\">srcset</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ image_srcset(asset) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">sizes</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ image_sizes('asset') }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span></code></pre>\n<h2 id=\"image-from-website\">image_from_website</h2>\n<p>Construit l'élément HTML img à partir d'une URL de site Web en extrayant son image d'illustration.\nRetourne <code translate=\"no\">null</code> si aucune image n'est trouvée.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ image_from_website('url', {attributs}, {options}) }}</span></code></pre>\n<p>L'image est recherchée dans le HTML de la page avec les fallbacks suivants, le premier candidat pouvant être téléchargé en tant qu'image est utilisé :</p>\n<ol>\n<li>Open Graph : <code translate=\"no\">og:image:secure_url</code>, <code translate=\"no\">og:image</code>, <code translate=\"no\">og:image:url</code></li>\n<li>Twitter : <code translate=\"no\">twitter:image</code>, <code translate=\"no\">twitter:image:src</code></li>\n<li><code translate=\"no\">&lt;link rel=\"image_src\"&gt;</code></li>\n<li>Microdata : <code translate=\"no\">itemprop=\"image\"</code></li>\n<li>JSON-LD : propriété <code translate=\"no\">image</code></li>\n<li>Première <code translate=\"no\">&lt;img&gt;</code> de <code translate=\"no\">&lt;article&gt;</code>, <code translate=\"no\">&lt;main&gt;</code> ou <code translate=\"no\">&lt;body&gt;</code></li>\n<li><code translate=\"no\">&lt;link rel=\"apple-touch-icon\"&gt;</code></li>\n<li><code translate=\"no\">&lt;link rel=\"icon\"&gt;</code></li>\n</ol>\n<p>Les URL relatives sont résolues par rapport à <code translate=\"no\">&lt;base href&gt;</code> ou à l'URL de la page.</p>\n<p>L'URL de l'image trouvée et l'image téléchargée sont mises en cache (voir <a href=\"../configuration/9-cache.fr.md\"><code translate=\"no\">cache.assets.remote.ttl</code></a>).</p>\n<p>Options :</p>\n<ul>\n<li><code translate=\"no\">fallback</code> : chemin (ou URL) de l'image utilisée si aucune image n'est trouvée</li>\n<li>autres options de <a href=\"../templates/reference/1-functions.fr.md#html\"><code translate=\"no\">image</code></a> (ex. : <code translate=\"no\">responsive</code>, <code translate=\"no\">formats</code>)</li>\n</ul>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ image_from_website('https://example.com/page-with-image.html') }}</span><span class=\"xml\">\n\n</span><span class=\"hljs-comment\">{# avec une image de fallback #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ image_from_website('https://example.com/', {alt: 'Illustration'}, {fallback: 'images/default.png'}) }}</span></code></pre>\n<h2 id=\"resize\">resize</h2>\n<p>Redimensionne une image à une largeur (en pixels) ou/et une hauteur (en pixels) spécifiée.</p>\n<ul>\n<li>Si seule la largeur est spécifiée, la hauteur est calculée pour conserver le rapport hauteur/largeur</li>\n<li>Si seule la hauteur est spécifiée, la largeur est calculée pour conserver le rapport hauteur/largeur</li>\n<li>Si la largeur et la hauteur sont spécifiées, l'image est redimensionnée pour s'adapter aux dimensions données, l'image est recadrée et centrée si nécessaire</li>\n<li>Si Remove_animation est vrai, toute animation dans l'image (par exemple, GIF) sera supprimée</li>\n</ul>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(image_path)|resize(width: width, height: height, remove_animation: bool) }}</span></code></pre>\n<aside class=\"note note-info\"><p>Le fichier original n'est pas modifié et la version redimensionnée est enregistrée sous <code translate=\"no\">/thumbnails/&lt;width&gt;x&lt;height&gt;/image.jpg</code>.</p></aside>\n<aside class=\"note note-tip\"><p>Les fichiers ICO sont supportés : la plus grande icône est redimensionnée et enregistrée dans un fichier ICO à icône unique (compressée en PNG). Les icônes stockées en BMP avec une profondeur de couleur autre que 24 ou 32 bits nécessitent l'extension PHP <a href=\"https://www.php.net/manual/fr/book.imagick.php\" target=\"_blank\" rel=\"noopener noreferrer\">Imagick</a> : à défaut, le fichier ICO original est conservé et un avertissement est journalisé.</p></aside>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(page.image)|resize(300) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# equivalent to: #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ asset(page.image)|resize(width: 300) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# resizes to 300px width, height auto-calculated to preserve aspect ratio #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ asset(page.image)|resize(height: 200) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# resizes to 300px width and 200px height, and crops if necessary #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ asset(page.image)|resize(300, 200) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# removes any animation from the image #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ asset(page.image)|resize(width: 1200, height: 630, remove_animation: true) }}</span></code></pre>\n<h2 id=\"cover\">cover</h2>\n<p>Redimensionne une image à une largeur et une hauteur spécifiées, en la recadrant si nécessaire.</p>\n<aside class=\"note note-warning\"><p>Le filtre <code translate=\"no\">cover</code> est obsolète depuis la version <ins>8.77</ins> et sera supprimé dans les versions futures. Utilisez plutôt le filtre <a href=\"#resize\"><code translate=\"no\">resize</code></a>, avec les paramètres de largeur et de hauteur.</p></aside>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(image_path)|cover(width, height) }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(page.image)|cover(1200, 630) }}</span></code></pre>\n<h2 id=\"maskable\">maskable</h2>\n<p>Ajoute un remplissage, en pourcentages, à une image pour la rendre masquable.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(image_path)|maskable(padding) }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset('icon.png')|maskable }}</span></code></pre>\n<h2 id=\"webp\">webp</h2>\n<p>Convertit une image au format <a href=\"https://developers.google.com/speed/webp\" target=\"_blank\" rel=\"noopener noreferrer\">WebP</a>.</p>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">picture</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">source</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"image/webp\"</span> <span class=\"hljs-attr\">srcset</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset(image_path)|webp }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(asset(image_path)) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">width</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset(image_path).width }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">height</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset(image_path).height }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">alt</span>=<span class=\"hljs-string\">\"\"</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">picture</span>&gt;</span></span></code></pre>\n<h2 id=\"avif\">avif</h2>\n<p>Convertit une image au format <a href=\"https://github.com/AOMediaCodec/libavif\" target=\"_blank\" rel=\"noopener noreferrer\">AVIF</a>.</p>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">picture</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">source</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"image/avif\"</span> <span class=\"hljs-attr\">srcset</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset(image_path)|avif }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(asset(image_path)) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">width</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset(image_path).width }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">height</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ asset(image_path).height }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">alt</span>=<span class=\"hljs-string\">\"\"</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">picture</span>&gt;</span></span></code></pre>\n<h2 id=\"lqip\">lqip</h2>\n<p>Renvoie un <a href=\"https://www.guypo.com/introducing-lqip-low-quality-image-placeholders\" target=\"_blank\" rel=\"noopener noreferrer\">espace réservé pour une image de faible qualité</a> (100 x 100 px, flou à 50 %) comme URL de données.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(image_path)|lqip }}</span></code></pre>\n<h2 id=\"dominant-color\">dominant_color</h2>\n<p>Renvoie la <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color\" target=\"_blank\" rel=\"noopener noreferrer\">couleur hexadécimale</a> dominante d'une image.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(image_path)|dominant_color }}</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/templates/regles-de-recherche/",
      "url": "https://cecil-945.pages.dev/fr/documentation/templates/regles-de-recherche/",
      "title": "Organisation et règles de recherche",
      "summary": "Types de templates, convention de nommage, templates intégrés et choix du template d’une page.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Organisation et règles de recherche\nCecil génère les pages à l’aide de templates Twig : cette page explique comment les templates sont organisés et comment le bon template est choisi pour chaque page.\nOrganisation des fichiers\nTypes de templates\nIl existe trois types de templates, layouts, components et autres templates : layouts sont utilisés pour afficher les pages, et chacun d'eux peut inclure des templates et components.\nConvention de nommage\nLes fichiers templates sont stockés dans le répertoire layouts\/ et doivent être nommés selon la convention suivante :\nlayouts\/(&lt;section&gt;\/)&lt;type&gt;|&lt;layout&gt;.&lt;format&gt;(.&lt;language&gt;).twig\n\n&lt;section&gt; (facultatif)\nLa section de la page (ex. : blog).\n&lt;type&gt;\nLe type de page : home (ou index) pour homepage, list pour list, page pour page, etc. (Voir Règles de recherche pour plus de détails).\n&lt;layout&gt; (facultatif)\nLe nom de la layout personnalisée défini dans le front-matter de la page (par exemple : layout: my-layout).\n&lt;format&gt;\nLe format de sortie de la page rendue (par exemple : html, rss, json, xml, etc.).\n&lt;language&gt; (facultatif)\nLa langue de la page (ex. : fr).\n\nExemples :\nlayouts\/home.html.twig       # `type` est \"homepage\"\nlayouts\/page.html.twig       # `type` est \"page\"\nlayouts\/page.html.fr.twig    # `type` est \"page\" et `language` est \"fr\"\nlayouts\/my-layout.html.twig  # `layout` est \"my-layout\"\nlayouts\/blog\/list.html.twig  # `section` est \"blog\"\nlayouts\/blog\/list.rss.twig   # `section` est \"blog\" et `format` est \"rss\"\n&lt;mon-site&gt;\n├─ ...\n├─ layouts\n|  ├─ index.html.twig      # Utilisé par le type \"homepage\"\n|  ├─ list.html.twig       # Utilisé par les types \"homepage\" et \"section\"\n|  ├─ list.rss.twig        # Utilisé par les types \"homepage\" et \"section\", pour le format de sortie RSS\n|  ├─ page.html.twig       # Utilisé par le type \"page\"\n|  ├─ taxonomy\n|  |  ├─ tags.html.twig    # Utilisé par le type \"vocabulary\" de `tags` (liste des termes)\n|  |  └─ tag.html.twig     # Utilisé par le type \"term\" de `tags` (liste des pages)\n|  ├─ my-layout.html.twig  # Utilisé par les pages avec `layout: my-layout` dans le front-matter\n|  ├─ ...\n|  └─ partials\n|     ├─ footer.html.twig  # Template inclus\n|     └─ ...\n└─ themes                  # Layouts et templates des thèmes\n   └─ ...\nTemplates intégrés\nCecil est livré avec un ensemble de templates intégrés.\nSi vous avez besoin de modifier des templates intégrés, vous pouvez facilement les extraire via la commande suivante : ils seront copiés dans le répertoire layouts de votre site.\nphp cecil.phar util:templates:extract\nRègles de recherche\nDans la plupart des cas vous n'avez pas besoin de préciser la layout : Cecil sélectionne la layout la plus appropriée, en fonction du type de la page.\nPar exemple, la sortie HTML de home page (index.md) sera rendue :\n\navec my-layout.html.twig si la variable layout est définie sur \"my-layout\" (dans le préambule)\nsinon, avec index.html.twig si le fichier existe\nsinon, avec home.html.twig si le fichier existe\nsinon, avec list.html.twig si le fichier existe\n\nToutes les règles sont détaillées ci-dessous, pour chaque type de page, par ordre de priorité.\nType homepage\n\n&lt;layout&gt;.&lt;format&gt;.twig\nindex.&lt;format&gt;.twig\nhome.&lt;format&gt;.twig\nlist.&lt;format&gt;.twig\n_default\/&lt;layout&gt;.&lt;format&gt;.twig\n_default\/index.&lt;format&gt;.twig\n_default\/home.&lt;format&gt;.twig\n_default\/list.&lt;format&gt;.twig\n_default\/page.&lt;format&gt;.twig\n\nType page\n\n&lt;section&gt;\/&lt;layout&gt;.&lt;format&gt;.twig\n&lt;layout&gt;.&lt;format&gt;.twig\n&lt;section&gt;\/page.&lt;format&gt;.twig\n_default\/&lt;layout&gt;.&lt;format&gt;.twig\npage.&lt;format&gt;.twig\n_default\/page.&lt;format&gt;.twig\n\nType section\n\n&lt;layout&gt;.&lt;format&gt;.twig\n&lt;section&gt;\/index.&lt;format&gt;.twig\n&lt;section&gt;\/list.&lt;format&gt;.twig\nsection\/&lt;section&gt;.&lt;format&gt;.twig\n&lt;parent&gt;\/index.&lt;format&gt;.twig, &lt;parent&gt;\/list.&lt;format&gt;.twig et section\/&lt;parent&gt;.&lt;format&gt;.twig, pour chaque section parente d’une sous-section (la plus proche en premier)\n_default\/section.&lt;format&gt;.twig\nlist.&lt;format&gt;.twig\n_default\/list.&lt;format&gt;.twig\n\nLa &lt;section&gt; d’une sous-section est son chemin complet (ex. : blog\/2024), et une sous-section se replie sur les templates de ses sections parentes : si blog\/2024\/list.html.twig n’existe pas, la sous-section blog\/2024 est rendue avec blog\/list.html.twig.\nType vocabulary\n\ntaxonomy\/&lt;plural&gt;.&lt;format&gt;.twig\nvocabulary.&lt;format&gt;.twig\n_default\/vocabulary.&lt;format&gt;.twig\n\nType term\n\ntaxonomy\/&lt;plural&gt;\/&lt;term&gt;.&lt;format&gt;.twig\ntaxonomy\/&lt;singular&gt;.&lt;format&gt;.twig\nterm.&lt;format&gt;.twig\n_default\/term.&lt;format&gt;.twig\n_default\/list.&lt;format&gt;.twig\n\nLe template du vocabulaire est nommé d’après le pluriel (ex. : taxonomy\/categories.html.twig pour \/categories\/), tandis que le template d’un terme est nommé d’après le singulier (ex. : taxonomy\/category.html.twig pour \/categories\/data-sovereignty\/).\n&lt;term&gt; est le nom du terme « slugifié » : un template dédié au terme « Data Sovereignty » du vocabulaire categories est taxonomy\/categories\/data-sovereignty.html.twig.\nLa plupart de ces layouts sont disponibles par défaut, voir templates intégrés.",
      "content_html": "<h1>Organisation et règles de recherche</h1>\n<p>Cecil génère les pages à l’aide de templates Twig : cette page explique comment les templates sont organisés et comment le bon template est choisi pour chaque page.</p>\n<h2 id=\"organisation-des-fichiers\">Organisation des fichiers</h2>\n<h3 id=\"types-de-templates\">Types de templates</h3>\n<p>Il existe trois types de templates, <strong><em>layouts</em></strong>, <strong><em>components</em></strong> et <strong><em>autres templates</em></strong> : <em>layouts</em> sont utilisés pour afficher les <a href=\"../content/1-pages.fr.md\">pages</a>, et chacun d'eux peut <a href=\"https://twig.symfony.com/doc/templates.html#including-other-templates\" target=\"_blank\" rel=\"noopener noreferrer\">inclure des templates</a> et <a href=\"4-components.fr.md\">components</a>.</p>\n<h3 id=\"convention-de-nommage\">Convention de nommage</h3>\n<p>Les fichiers templates sont stockés dans le répertoire <code translate=\"no\">layouts/</code> et doivent être nommés selon la convention suivante :</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">layouts/(&lt;section&gt;/)&lt;type&gt;|&lt;layout&gt;.&lt;format&gt;(.&lt;language&gt;).twig</code></pre>\n<dl>\n<dt><code translate=\"no\">&lt;section&gt;</code> (<em>facultatif</em>)</dt>\n<dd>La section de la page (ex. : <code translate=\"no\">blog</code>).</dd>\n<dt><code translate=\"no\">&lt;type&gt;</code></dt>\n<dd>Le type de page : <code translate=\"no\">home</code> (ou <code translate=\"no\">index</code>) pour <em>homepage</em>, <code translate=\"no\">list</code> pour <em>list</em>, <code translate=\"no\">page</code> pour <em>page</em>, etc. (Voir <a href=\"#regles-de-recherche\"><em>Règles de recherche</em></a> pour plus de détails).</dd>\n<dt><code translate=\"no\">&lt;layout&gt;</code> (<em>facultatif</em>)</dt>\n<dd>Le nom de la layout personnalisée défini dans le <a href=\"../content/1-pages.fr.md#front-matter\">front-matter</a> de la page (par exemple : <code translate=\"no\">layout: my-layout</code>).</dd>\n<dt><code translate=\"no\">&lt;format&gt;</code></dt>\n<dd>Le <a href=\"../configuration/8-output.fr.md#output-formats\">format de sortie</a> de la page rendue (par exemple : <code translate=\"no\">html</code>, <code translate=\"no\">rss</code>, <code translate=\"no\">json</code>, <code translate=\"no\">xml</code>, etc.).</dd>\n<dt><code translate=\"no\">&lt;language&gt;</code> (<em>facultatif</em>)</dt>\n<dd>La langue de la page (ex. : <code translate=\"no\">fr</code>).</dd>\n</dl>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">layouts/home.html.twig       # `type` est \"homepage\"\nlayouts/page.html.twig       # `type` est \"page\"\nlayouts/page.html.fr.twig    # `type` est \"page\" et `language` est \"fr\"\nlayouts/my-layout.html.twig  # `layout` est \"my-layout\"\nlayouts/blog/list.html.twig  # `section` est \"blog\"\nlayouts/blog/list.rss.twig   # `section` est \"blog\" et `format` est \"rss\"</code></pre>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">&lt;mon-site&gt;\n├─ ...\n├─ layouts\n|  ├─ index.html.twig      # Utilisé par le type \"homepage\"\n|  ├─ list.html.twig       # Utilisé par les types \"homepage\" et \"section\"\n|  ├─ list.rss.twig        # Utilisé par les types \"homepage\" et \"section\", pour le format de sortie RSS\n|  ├─ page.html.twig       # Utilisé par le type \"page\"\n|  ├─ taxonomy\n|  |  ├─ tags.html.twig    # Utilisé par le type \"vocabulary\" de `tags` (liste des termes)\n|  |  └─ tag.html.twig     # Utilisé par le type \"term\" de `tags` (liste des pages)\n|  ├─ my-layout.html.twig  # Utilisé par les pages avec `layout: my-layout` dans le front-matter\n|  ├─ ...\n|  └─ partials\n|     ├─ footer.html.twig  # Template inclus\n|     └─ ...\n└─ themes                  # Layouts et templates des thèmes\n   └─ ...</code></pre>\n<h3 id=\"templates-integres\">Templates intégrés</h3>\n<p>Cecil est livré avec un ensemble de <a href=\"https://github.com/Cecilapp/Cecil/tree/main/resources/layouts\" target=\"_blank\" rel=\"noopener noreferrer\">templates intégrés</a>.</p>\n<aside class=\"note note-tip\"><p>Si vous avez besoin de modifier des templates intégrés, vous pouvez facilement les extraire via la commande suivante : ils seront copiés dans le répertoire <code translate=\"no\">layouts</code> de votre site.</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar util:templates:extract</code></pre></aside>\n<h2 id=\"regles-de-recherche\">Règles de recherche</h2>\n<p>Dans la plupart des cas <strong>vous n'avez pas besoin de préciser la layout</strong> : Cecil sélectionne la layout la plus appropriée, en fonction du <strong>type de la page</strong>.</p>\n<p>Par exemple, la sortie HTML de <strong>home page</strong> (<code translate=\"no\">index.md</code>) sera rendue :</p>\n<ol>\n<li>avec <code translate=\"no\">my-layout.html.twig</code> si la variable <code translate=\"no\">layout</code> est définie sur \"my-layout\" (dans le préambule)</li>\n<li>sinon, avec <code translate=\"no\">index.html.twig</code> si le fichier existe</li>\n<li>sinon, avec <code translate=\"no\">home.html.twig</code> si le fichier existe</li>\n<li>sinon, avec <code translate=\"no\">list.html.twig</code> si le fichier existe</li>\n</ol>\n<p>Toutes les règles sont détaillées ci-dessous, pour chaque type de page, par ordre de priorité.</p>\n<h3 id=\"type-homepage\">Type <em>homepage</em></h3>\n<ol>\n<li><code translate=\"no\">&lt;layout&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">index.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">home.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">list.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/&lt;layout&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/index.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/home.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/list.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/page.&lt;format&gt;.twig</code></li>\n</ol>\n<h3 id=\"type-page\">Type <em>page</em></h3>\n<ol>\n<li><code translate=\"no\">&lt;section&gt;/&lt;layout&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">&lt;layout&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">&lt;section&gt;/page.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/&lt;layout&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">page.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/page.&lt;format&gt;.twig</code></li>\n</ol>\n<h3 id=\"type-section\">Type <em>section</em></h3>\n<ol>\n<li><code translate=\"no\">&lt;layout&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">&lt;section&gt;/index.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">&lt;section&gt;/list.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">section/&lt;section&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">&lt;parent&gt;/index.&lt;format&gt;.twig</code>, <code translate=\"no\">&lt;parent&gt;/list.&lt;format&gt;.twig</code> et <code translate=\"no\">section/&lt;parent&gt;.&lt;format&gt;.twig</code>, pour chaque section parente d’une sous-section (la plus proche en premier)</li>\n<li><code translate=\"no\">_default/section.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">list.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/list.&lt;format&gt;.twig</code></li>\n</ol>\n<aside class=\"note note-tip\"><p>La <code translate=\"no\">&lt;section&gt;</code> d’une <a href=\"../content/1-pages.fr.md#sous-section\">sous-section</a> est son chemin complet (ex. : <code translate=\"no\">blog/2024</code>), et une sous-section se replie sur les templates de ses sections parentes : si <code translate=\"no\">blog/2024/list.html.twig</code> n’existe pas, la sous-section <code translate=\"no\">blog/2024</code> est rendue avec <code translate=\"no\">blog/list.html.twig</code>.</p></aside>\n<h3 id=\"type-vocabulary\">Type <em>vocabulary</em></h3>\n<ol>\n<li><code translate=\"no\">taxonomy/&lt;plural&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">vocabulary.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/vocabulary.&lt;format&gt;.twig</code></li>\n</ol>\n<h3 id=\"type-term\">Type <em>term</em></h3>\n<ol>\n<li><code translate=\"no\">taxonomy/&lt;plural&gt;/&lt;term&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">taxonomy/&lt;singular&gt;.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">term.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/term.&lt;format&gt;.twig</code></li>\n<li><code translate=\"no\">_default/list.&lt;format&gt;.twig</code></li>\n</ol>\n<aside class=\"note note-important\"><p>Le template du <strong>vocabulaire</strong> est nommé d’après le <strong>pluriel</strong> (ex. : <code translate=\"no\">taxonomy/categories.html.twig</code> pour <code translate=\"no\">/categories/</code>), tandis que le template d’un <strong>terme</strong> est nommé d’après le <strong>singulier</strong> (ex. : <code translate=\"no\">taxonomy/category.html.twig</code> pour <code translate=\"no\">/categories/data-sovereignty/</code>).</p></aside>\n<aside class=\"note note-tip\"><p><code translate=\"no\">&lt;term&gt;</code> est le nom du terme « slugifié » : un template dédié au terme « Data Sovereignty » du vocabulaire <code translate=\"no\">categories</code> est <code translate=\"no\">taxonomy/categories/data-sovereignty.html.twig</code>.</p></aside>\n<aside class=\"note note-info\"><p>La plupart de ces layouts sont disponibles par défaut, voir <a href=\"#templates-integres\">templates intégrés</a>.</p></aside>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/templates/reference/fonctions/",
      "url": "https://cecil-945.pages.dev/fr/documentation/templates/reference/fonctions/",
      "title": "Fonctions",
      "summary": "url, html, readtime, hash, cache_key, getenv, dump, etc.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Fonctions\n\nFonctions peut être appelée pour générer du contenu. Les fonctions sont appelées par leur nom suivi de parenthèses (()) et peuvent avoir des arguments.\n\nurl\nCrée une URL valide pour une page, une entrée de menu, un actif, un ID de page ou un chemin.\n{{ url(value, {options}) }}\n\n\n\nOptions\nDescriptif\nTapez\nPar défaut\n\n\n\n\ncanonique\nPréfixez l'URL avec baseurl ou utilisez canonical.url s'il existe.\nbooléen\nfalse\n\n\nformats\nDéfinit la page format de sortie (par exemple : json).\nchaîne\nhtml\n\n\nlangue\nDéfinit la page langue (ex. : fr).\nchaîne\nnul\n\n\n\nExemples :\n{# page #}\n{{ url(page) }}\n{{ url(page, {canonical: true}) }}\n{{ url(page, {format: json}) }}\n{{ url(page, {language: fr}) }}\n{# menu entry #}\n{{ url(site.menus.main.about) }}\n{# asset #}\n{{ url(asset('styles.css')) }}\n{# page ID #}\n{{ url('page-id') }}\n{# path #}\n{{ url('about-me\/') }}\n{{ url('tags\/' ~ tag) }}\nPour plus de commodité, la fonction url est également disponible sous forme de filtre :\n{# page #}\n{{ page|url }}\n{{ page|url({canonical: true, format: json, language: fr}) }}\n{# asset #}\n{{ asset('styles.css')|url }}\nLorsque la valeur est une chaîne, url() la « slugifie » pour trouver un ID de page correspondant (ex. : url('tags\/My Tag') retourne l’URL de la page tags\/my-tag). Si aucune page ne correspond, la chaîne est conservée comme chemin, avec les caractères invalides (ex. : espaces) encodés.\nhtml\nCrée un élément HTML à partir d'un actif (ou d'un tableau d'actifs avec des attributs personnalisés).\n{{ html(asset, {attributes}, {options}) }}\n{# dedicated functions for each common type of asset #}\n{{ css(asset) }}\n{{ js(asset) }}\n{{ image(asset) }}\n{{ audio(asset) }}\n{{ video(asset) }}\n\n\n\nOptions\nDescriptif\nTapez\n\n\n\n\nattributs\nAjoute le couple name=\"value\" à l'élément HTML.\ntableau\n\n\noptions\n{preload: boolean} : préchargements.Pour les images :{formats: array} : ajoute des formats alternatifs.{responsive: bool|string} : ajoute des images réactives (basées sur width ou des pixels density).{placeholder: string} : remplit l'arrière-plan de l'image avant son chargement (color ou lqip).\ntableau\n\n\n\nDepuis la version 8.42.0, la fonction html remplace le filtre html obsolète.\nVous pouvez définir un comportement global par défaut des options d'images (formats, responsive et placeholder) via la configuration des layouts.\nLorsque layouts.images.dark_suffix est configuré (par exemple .dark), Cecil recherche automatiquement une variante sombre de chaque image (par exemple photo.dark.jpg aux côtés de photo.jpg) et génère un élément &lt;picture&gt; avec un &lt;source media=\"(prefers-color-scheme: dark)\"&gt;.\nDe la même manière, lorsque layouts.images.mobile_suffix est configuré (par exemple .mobile), Cecil recherche une variante mobile de chaque image (par exemple photo.mobile.jpg) et ajoute un &lt;source&gt; avec la media query layouts.images.mobile_media_query. Si une variante sombre de l’image mobile existe (par exemple photo.mobile.dark.jpg), elle est utilisée sur mobile en mode sombre.\nExemples :\n{# CSS with an attribute #}\n{{ html(asset('print.css'), {media: 'print'}) }}\n{# CSS with an attribute and an option #}\n{{ html(asset('styles.css'), {title: 'Main theme'}, {preload: true}) }}\n{# Array of assets with media query #}\n{{ html([\n  {asset: asset('css\/style.css')},\n  {asset: asset('css\/style-dark.css'), attributes: {media: '(prefers-color-scheme: dark)'}}\n]) }}\n{# JavaScript #}\n{{ html(asset('script.js')) }}\n{# image without specific attributes nor options #}\n{{ html(asset('image.png')) }}\n{# image with specific attributes, responsive images and alternative formats #}\n{{ html(asset('image.jpg'), {alt: 'Description', loading: 'lazy'}, {responsive: true, formats: ['avif', 'webp']}) }}\n{# image with responsive pixels density images #}\n{{ html(asset('image.jpg'), options={responsive: 'density'}, attributes={width: 256}) }}\n{# image with a Low-Quality Image Placeholder #}\n{{ html(asset('image.jpg'), {alt: 'Description', loading: 'lazy'}, {placeholder: 'lqip'}) }}\n{# Audio #}\n{{ html(asset('audio.mp3')) }}\n{# Video #}\n{{ html(asset('video.mp4')) }}\nPour plus de commodité, la fonction html reste disponible en tant que filtre (mais est considérée comme obsolète) :\n{{ asset|html({attributes}, {options}) }}\nreadtime\nDétermine le temps de lecture d'un texte, en minutes.\n{{ readtime(value) }}\nExemple:\n{{ readtime(page.content) }} min\nhash\nCalcule le hachage d'un objet, d'un tableau ou d'une chaîne avec un algorithme donné.\n{{ hash(value, algorithm) }}\nalgorithm peut être n'importe quel algorithme pris en charge par la fonction hash() de PHP (par exemple : md5, sha256, etc.). La valeur par défaut est xxh128.\nExemple:\n{{ hash('my string', 'sha256') }}\ncache_key\nCalcule une clé de cache pour fragments cache en fonction d'un nom et d'une valeur facultative.\n{% cache cache_key(name, value) %}\n  {# cacheable content #}\n{% endcache %}\nLa fonction ajoute un hachage de la valeur (peut être une chaîne, un tableau ou un objet) au nom (ainsi que la langue actuelle et l'ID de build pour être sûr que la clé de cache générée est unique), donc si la valeur est modifiée, la clé de cache est également modifiée et le cache est automatiquement vidé.\ngetenv\nObtient la valeur d'une variable d'environnement à partir de sa clé.\n{{ getenv(var) }}\nExemple:\n{{ getenv('VAR') }}\ndump\nLa fonction dump affiche les informations sur une variable de modèle. Ceci est surtout utile pour déboguer un modèle qui ne se comporte pas comme prévu en introspectant ses variables :\n{{ dump(user) }}\nLe debug mode doit être activé.\nd\nLa fonction d() est la version HTML de dump() et utilise le Symfony VarDumper Component en arrière-plan.\n{{ d(variable, {theme: light}) }}\n\nSi variable n'est pas fourni, la fonction renvoie le contexte Twig actuel\nLes thèmes disponibles sont « clair » (par défaut) et « sombre »\n\nLe debug mode doit être activé.",
      "content_html": "<h1>Fonctions</h1>\n<blockquote>\n<p><a href=\"https://twig.symfony.com/doc/functions/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">Fonctions</a> peut être appelée pour générer du contenu. Les fonctions sont appelées par leur nom suivi de parenthèses (<code translate=\"no\">()</code>) et peuvent avoir des arguments.</p>\n</blockquote>\n<h2 id=\"url\">url</h2>\n<p>Crée une URL valide pour une page, une entrée de menu, un actif, un ID de page ou un chemin.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ url(value, {options}) }}</span></code></pre>\n<table>\n<thead>\n<tr>\n<th>Options</th>\n<th>Descriptif</th>\n<th>Tapez</th>\n<th>Par défaut</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>canonique</td>\n<td>Préfixez l'URL avec <a href=\"../../configuration/1-site.fr.md#baseurl\"><code translate=\"no\">baseurl</code></a> ou utilisez <a href=\"../../configuration/1-site.fr.md#options-metatags\"><code translate=\"no\">canonical.url</code></a> s'il existe.</td>\n<td>booléen</td>\n<td><code translate=\"no\">false</code></td>\n</tr>\n<tr>\n<td>formats</td>\n<td>Définit la page <a href=\"../../configuration/8-output.fr.md#output-formats\">format de sortie</a> (par exemple : <code translate=\"no\">json</code>).</td>\n<td>chaîne</td>\n<td><code translate=\"no\">html</code></td>\n</tr>\n<tr>\n<td>langue</td>\n<td>Définit la page <a href=\"../../configuration/2-languages.fr.md#language\">langue</a> (ex. : <code translate=\"no\">fr</code>).</td>\n<td>chaîne</td>\n<td>nul</td>\n</tr>\n</tbody>\n</table>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# page #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ url(page) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ url(page, {canonical: true}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ url(page, {format: json}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ url(page, {language: fr}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# menu entry #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ url(site.menus.main.about) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# asset #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ url(asset('styles.css')) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# page ID #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ url('page-id') }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# path #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ url('about-me/') }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ url('tags/' ~ tag) }}</span></code></pre>\n<aside class=\"note note-info\"><p>Pour plus de commodité, la fonction <code translate=\"no\">url</code> est également disponible sous forme de filtre :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# page #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ page|url }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ page|url({canonical: true, format: json, language: fr}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# asset #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ asset('styles.css')|url }}</span></code></pre></aside>\n<aside class=\"note note-tip\"><p>Lorsque la valeur est une chaîne, <code translate=\"no\">url()</code> la « slugifie » pour trouver un ID de page correspondant (ex. : <code translate=\"no\">url('tags/My Tag')</code> retourne l’URL de la page <code translate=\"no\">tags/my-tag</code>). Si aucune page ne correspond, la chaîne est conservée comme chemin, avec les caractères invalides (ex. : espaces) encodés.</p></aside>\n<h2 id=\"html\">html</h2>\n<p>Crée un élément HTML à partir d'un actif (ou d'un tableau d'actifs avec des attributs personnalisés).</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ html(asset, {attributes}, {options}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# dedicated functions for each common type of asset #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ css(asset) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ js(asset) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ image(asset) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ audio(asset) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ video(asset) }}</span></code></pre>\n<table>\n<thead>\n<tr>\n<th>Options</th>\n<th>Descriptif</th>\n<th>Tapez</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>attributs</td>\n<td>Ajoute le couple <code translate=\"no\">name=\"value\"</code> à l'élément HTML.</td>\n<td>tableau</td>\n</tr>\n<tr>\n<td>options</td>\n<td><code translate=\"no\">{preload: boolean}</code> : préchargements.<br>Pour les images :<br><code translate=\"no\">{formats: array}</code> : ajoute des formats alternatifs.<br><code translate=\"no\">{responsive: bool|string}</code> : ajoute des images réactives (basées sur <code translate=\"no\">width</code> ou des pixels <code translate=\"no\">density</code>).<br><code translate=\"no\">{placeholder: string}</code> : remplit l'arrière-plan de l'image avant son chargement (<code translate=\"no\">color</code> ou <code translate=\"no\">lqip</code>).</td>\n<td>tableau</td>\n</tr>\n</tbody>\n</table>\n<aside class=\"note note-warning\"><p>Depuis la version <ins>8.42.0</ins>, la fonction <code translate=\"no\">html</code> remplace le filtre <code translate=\"no\">html</code> obsolète.</p></aside>\n<aside class=\"note note-tip\"><p>Vous pouvez définir un comportement global par défaut des options d'images (<code translate=\"no\">formats</code>, <code translate=\"no\">responsive</code> et <code translate=\"no\">placeholder</code>) via la <a href=\"../../configuration/7-layouts.fr.md#layouts-images\">configuration des layouts</a>.</p>\n<p>Lorsque <a href=\"../../configuration/7-layouts.fr.md#layouts-images\"><code translate=\"no\">layouts.images.dark_suffix</code></a> est configuré (par exemple <code translate=\"no\">.dark</code>), Cecil recherche automatiquement une variante sombre de chaque image (par exemple <code translate=\"no\">photo.dark.jpg</code> aux côtés de <code translate=\"no\">photo.jpg</code>) et génère un élément <code translate=\"no\">&lt;picture&gt;</code> avec un <code translate=\"no\">&lt;source media=\"(prefers-color-scheme: dark)\"&gt;</code>.</p>\n<p>De la même manière, lorsque <a href=\"../../configuration/7-layouts.fr.md#layouts-images\"><code translate=\"no\">layouts.images.mobile_suffix</code></a> est configuré (par exemple <code translate=\"no\">.mobile</code>), Cecil recherche une variante mobile de chaque image (par exemple <code translate=\"no\">photo.mobile.jpg</code>) et ajoute un <code translate=\"no\">&lt;source&gt;</code> avec la media query <a href=\"../../configuration/7-layouts.fr.md#layouts-images\"><code translate=\"no\">layouts.images.mobile_media_query</code></a>. Si une variante sombre de l’image mobile existe (par exemple <code translate=\"no\">photo.mobile.dark.jpg</code>), elle est utilisée sur mobile en mode sombre.</p></aside>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# CSS with an attribute #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html(asset('print.css'), {media: 'print'}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# CSS with an attribute and an option #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html(asset('styles.css'), {title: 'Main theme'}, {preload: true}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# Array of assets with media query #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html([\n  {asset: asset('css/style.css')},\n  {asset: asset('css/style-dark.css'), attributes: {media: '(prefers-color-scheme: dark)'}}</span><span class=\"xml\">\n]) }}\n</span><span class=\"hljs-comment\">{# JavaScript #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html(asset('script.js')) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# image without specific attributes nor options #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html(asset('image.png')) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# image with specific attributes, responsive images and alternative formats #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html(asset('image.jpg'), {alt: 'Description', loading: 'lazy'}, {responsive: true, formats: ['avif', 'webp']}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# image with responsive pixels density images #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html(asset('image.jpg'), options={responsive: 'density'}, attributes={width: 256}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# image with a Low-Quality Image Placeholder #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html(asset('image.jpg'), {alt: 'Description', loading: 'lazy'}, {placeholder: 'lqip'}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# Audio #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html(asset('audio.mp3')) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# Video #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ html(asset('video.mp4')) }}</span></code></pre>\n<aside class=\"note note-info\"><p>Pour plus de commodité, la fonction <code translate=\"no\">html</code> reste disponible en tant que filtre (mais est considérée comme obsolète) :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset|html({attributes}, {options}) }}</span></code></pre></aside>\n<h2 id=\"readtime\">readtime</h2>\n<p>Détermine le temps de lecture d'un texte, en minutes.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ readtime(value) }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ readtime(page.content) }}</span><span class=\"xml\"> min</span></code></pre>\n<h2 id=\"hash\">hash</h2>\n<p>Calcule le hachage d'un objet, d'un tableau ou d'une chaîne avec un algorithme donné.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ hash(value, algorithm) }}</span></code></pre>\n<p><code translate=\"no\">algorithm</code> peut être n'importe quel algorithme pris en charge par la fonction <code translate=\"no\">hash()</code> de PHP (par exemple : <code translate=\"no\">md5</code>, <code translate=\"no\">sha256</code>, etc.). La valeur par défaut est <code translate=\"no\">xxh128</code>.</p>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ hash('my string', 'sha256') }}</span></code></pre>\n<h2 id=\"cache-key\">cache_key</h2>\n<p>Calcule une clé de cache pour <a href=\"../6-cache.fr.md#fragments-de-cache\"><em>fragments</em> cache</a> en fonction d'un nom et d'une valeur facultative.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">cache</span> cache_key(name, value) %}</span><span class=\"xml\">\n  </span><span class=\"hljs-comment\">{# cacheable content #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">endcache</span> %}</span></code></pre>\n<p>La fonction ajoute un hachage de la valeur (peut être une chaîne, un tableau ou un objet) au nom (ainsi que la langue actuelle et l'ID de build pour être sûr que la clé de cache générée est unique), donc si la valeur est modifiée, la clé de cache est également modifiée et le cache est automatiquement vidé.</p>\n<h2 id=\"getenv\">getenv</h2>\n<p>Obtient la valeur d'une variable d'environnement à partir de sa clé.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ getenv(var) }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ getenv('VAR') }}</span></code></pre>\n<h2 id=\"dump\">dump</h2>\n<p>La fonction <code translate=\"no\">dump</code> affiche les informations sur une variable de modèle. Ceci est surtout utile pour déboguer un modèle qui ne se comporte pas comme prévu en introspectant ses variables :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ <span class=\"hljs-name\">dump</span><span class=\"hljs-params\">(user)</span> }}</span></code></pre>\n<aside class=\"note note-important\"><p>Le <a href=\"../../configuration/1-site.fr.md#debug\"><em>debug mode</em></a> doit être activé.</p></aside>\n<h2 id=\"d\">d</h2>\n<p>La fonction <code translate=\"no\">d()</code> est la version HTML de <a href=\"#dump\"><code translate=\"no\">dump()</code></a> et utilise le <a href=\"https://symfony.com/doc/5.4/components/var_dumper.html\" target=\"_blank\" rel=\"noopener noreferrer\">Symfony VarDumper Component</a> en arrière-plan.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ d(variable, {theme: light}) }}</span></code></pre>\n<ul>\n<li>Si <em>variable</em> n'est pas fourni, la fonction renvoie le contexte Twig actuel</li>\n<li>Les thèmes disponibles sont « clair » (par défaut) et « sombre »</li>\n</ul>\n<aside class=\"note note-important\"><p>Le <a href=\"../../configuration/1-site.fr.md#debug\"><em>debug mode</em></a> doit être activé.</p></aside>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/assets/traitements/",
      "url": "https://cecil-945.pages.dev/fr/documentation/assets/traitements/",
      "title": "CSS, JavaScript et traitements",
      "summary": "Compilez Sass, minifiez, ajoutez une empreinte, intégrez ou embarquez les assets.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "CSS, JavaScript et traitements\nCecil fournit des filtres Twig pour compiler du Sass, minifier, ajouter une empreinte ou intégrer les assets CSS et JavaScript.\nfingerprint\nAjoutez l'empreinte digitale du contenu du fichier au nom du fichier.\n{{ asset(path)|fingerprint }}\n{{ path|fingerprint }}\nExemples :\n{{ asset('styles.css')|fingerprint }}\nminify\nRéduire un fichier CSS ou JavaScript.\n{{ asset(path)|minify }}\nExemples :\n{{ asset('styles.css')|minify }}\n{{ asset('scripts.js')|minify }}\nminify_css\nRéduire une chaîne CSS.\n{{ variable|minify_css }}\n{% apply minify_css %}\n{# CSS here #}\n{% endapply %}\nExemples :\n{% set styles = 'some CSS here' %}\n{{ styles|minify_css }}\n&lt;style&gt;\n{% apply minify_css %}\n  html {\n    background-color: #fcfcfc;\n    color: #444;\n  }\n{% endapply %}\n&lt;\/style&gt;\nminify_js\nRéduire une chaîne JavaScript.\n{{ variable|minify_js }}\n{% apply minify_js %}\n{# JavaScript here #}\n{% endapply %}\nExemples :\n{% set script = 'some JavaScript here' %}\n{{ script|minify_js }}\n&lt;script&gt;\n{% apply minify_js %}\n  var test = 'test';\n  console.log(test);\n{% endapply %}\n&lt;\/script&gt;\nscss_to_css\nCompile une chaîne Sass en CSS.\n{{ variable|scss_to_css }}\n{% apply scss_to_css %}\n{# SCSS here #}\n{% endapply %}\nAlias : sass_to_css.\nExemples :\n{% set scss = 'some SCSS here' %}\n{{ scss|scss_to_css }}\n&lt;style&gt;\n{% apply scss_to_css %}\n  $color: #fcfcfc;\n  div {\n    color: lighten($color, 20%);\n  }\n{% endapply %}\n&lt;\/style&gt;\nto_css\nCompile un fichier Sass en CSS.\n{{ asset(path)|to_css }}\n{{ path|to_css }}\nExemples :\n{{ asset('styles.scss')|to_css }}\ninline\nAffiche le contenu d'un Asset.\n{{ asset(path)|inline }}\nExemple:\n{{ asset('styles.css')|inline }}\ndataurl\nRenvoie l'URL de données d'un actif.\n{{ asset(path)|dataurl }}\n{{ asset(image_path)|dataurl }}",
      "content_html": "<h1>CSS, JavaScript et traitements</h1>\n<p>Cecil fournit des filtres Twig pour compiler du Sass, minifier, ajouter une empreinte ou intégrer les assets CSS et JavaScript.</p>\n<h2 id=\"fingerprint\">fingerprint</h2>\n<p>Ajoutez l'empreinte digitale du contenu du fichier au nom du fichier.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(path)|fingerprint }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ path|fingerprint }}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset('styles.css')|fingerprint }}</span></code></pre>\n<h2 id=\"minify\">minify</h2>\n<p>Réduire un fichier CSS ou JavaScript.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(path)|minify }}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset('styles.css')|minify }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ asset('scripts.js')|minify }}</span></code></pre>\n<h2 id=\"minify-css\">minify_css</h2>\n<p>Réduire une chaîne CSS.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ variable|minify_css }}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">apply</span></span> minify_css %}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# CSS here #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endapply</span></span> %}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> styles = 'some CSS here' %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ styles|minify_css }}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">style</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">apply</span></span> minify_css %}</span><span class=\"xml\"><span class=\"css\">\n  <span class=\"hljs-selector-tag\">html</span> {\n    <span class=\"hljs-attribute\">background-color</span>: <span class=\"hljs-number\">#fcfcfc</span>;\n    <span class=\"hljs-attribute\">color</span>: <span class=\"hljs-number\">#444</span>;\n  }\n</span></span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endapply</span></span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">style</span>&gt;</span></span></code></pre>\n<h2 id=\"minify-js\">minify_js</h2>\n<p>Réduire une chaîne JavaScript.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ variable|minify_js }}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">apply</span></span> minify_js %}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# JavaScript here #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endapply</span></span> %}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> script = 'some JavaScript here' %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ script|minify_js }}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">apply</span></span> minify_js %}</span><span class=\"xml\"><span class=\"javascript\">\n  <span class=\"hljs-keyword\">var</span> test = <span class=\"hljs-string\">'test'</span>;\n  <span class=\"hljs-built_in\">console</span>.log(test);\n</span></span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endapply</span></span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">script</span>&gt;</span></span></code></pre>\n<h2 id=\"scss-to-css\">scss_to_css</h2>\n<p>Compile une chaîne <a href=\"https://sass-lang.com\" target=\"_blank\" rel=\"noopener noreferrer\">Sass</a> en CSS.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ variable|scss_to_css }}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">apply</span></span> scss_to_css %}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# SCSS here #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endapply</span></span> %}</span></code></pre>\n<p>Alias : <code translate=\"no\">sass_to_css</code>.</p>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> scss = 'some SCSS here' %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ scss|scss_to_css }}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">style</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">apply</span></span> scss_to_css %}</span><span class=\"xml\">\n  $color: #fcfcfc;\n  div {\n    color: lighten($color, 20%);\n  }\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endapply</span></span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">style</span>&gt;</span></span></code></pre>\n<h2 id=\"to-css\">to_css</h2>\n<p>Compile un fichier <a href=\"https://sass-lang.com\" target=\"_blank\" rel=\"noopener noreferrer\">Sass</a> en CSS.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(path)|to_css }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ path|to_css }}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset('styles.scss')|to_css }}</span></code></pre>\n<h2 id=\"inline\">inline</h2>\n<p>Affiche le contenu d'un <em>Asset</em>.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(path)|inline }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset('styles.css')|inline }}</span></code></pre>\n<h2 id=\"dataurl\">dataurl</h2>\n<p>Renvoie l'<a href=\"https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/Data_URIs\" target=\"_blank\" rel=\"noopener noreferrer\">URL de données</a> d'un actif.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ asset(path)|dataurl }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ asset(image_path)|dataurl }}</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/templates/variables/",
      "url": "https://cecil-945.pages.dev/fr/documentation/templates/variables/",
      "title": "Variables",
      "summary": "Variables disponibles dans les templates : site, page et cecil.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-06T00:00:00+00:00","content_text": "Variables\n\nL'application transmet des variables aux templates pour manipulation dans le modèle. Les variables peuvent également avoir des attributs ou des éléments auxquels vous pouvez accéder.\nUtilisez un point (.) pour accéder aux attributs d'une variable : {{ foo.bar }}\n\nVous pouvez utiliser des variables de différentes portées : site, page, cecil.\nsite\nLa variable site contient des variables intégrées et celles définies dans la configuration.\n\n\n\nVariables\nDescriptif\n\n\n\n\nsite.pages\nCollection de toutes les pages, dans la langue actuelle.\n\n\nsite.allpages\nCollection de toutes les pages, dans toutes les langues.\n\n\nsite.page(id)\nUne page avec l'ID donné.\n\n\nsite.taxonomies\nRecueil de vocabulaires.\n\n\nsite.home\nID de la page d'accueil.\n\n\nsite.time\nActuel Timestamp.\n\n\nsite.debug\nÉtat du mode débogage (true ou false).\n\n\nsite.build\nID de build actuel.\n\n\n\nExemple:\ntitle: \"My amazing website!\"\nPeut être affiché dans un modèle avec :\n{{ site.title }}\nUtilisez la méthode showable sur la collection de pages pour renvoyer uniquement les pages publiées et non les pages virtuelles\/redirectes\/exclues.\nExemple:\n{% for page in site.pages.showable %}\n  &lt;a href=\"{{ url(page) }}\"&gt;{{ page.title }}&lt;\/a&gt;\n{% endfor %}\nDans certains cas, vous pouvez rencontrer des conflits entre la configuration et les variables intégrées (ex. : pages.default configuration), vous pouvez donc utiliser config.&lt;variable&gt; (avec &lt;variable&gt; est le nom\/chemin de la variable) pour accéder directement à la configuration brute.\nExemple:\n{{ config.pages.default.sitemap.priority }}\nsite.menus\nBouclez sur site.menus.&lt;menu&gt; pour obtenir chaque entrée de la collection &lt;menu&gt; (par exemple : main).\n\n\n\nVariables\nDescriptif\n\n\n\n\n&lt;entry&gt;.name\nNom de l'entrée.\n\n\n&lt;entry&gt;.url\nURL d'entrée.\n\n\n&lt;entry&gt;.weight\nPoids d'entrée (utile pour trier les entrées de menu).\n\n\n\nExemple:\n&lt;nav&gt;\n  &lt;ol&gt;\n  {% for entry in site.menus.main|sort_by_weight %}\n    &lt;li&gt;&lt;a href=\"{{ url(entry.url) }}\" data-weight=\"{{ entry.weight }}\"&gt;{{ entry.name }}&lt;\/a&gt;&lt;\/li&gt;\n  {% endfor %}\n  &lt;\/ol&gt;\n&lt;\/nav&gt;\nsite.language\nInformations sur la langue actuelle.\n\n\n\nVariables\nDescriptif\n\n\n\n\nsite.language\nCode de langue (ex. : en).\n\n\nsite.language.name\nNom de la langue (par exemple : English).\n\n\nsite.language.locale\nLangue code local (par exemple : en_US).\n\n\nsite.language.weight\nPosition de la langue dans la liste languages.\n\n\n\nVous pouvez récupérer name, locale et weight d'un langage spécifique en passant son code en paramètre.\npar exemple : site.language.name('fr').\nsite.static\nLa collection de fichiers statiques est accessible via site.static si le static load est activé.\nChaque fichier expose les propriétés suivantes :\n\npath : chemin relatif (ex. : \/images\/img-1.jpg)\ndate : date de création (timestamp)\nupdated : date de modification (timestamp)\nname : nom (ex. : img-1.jpg)\nbasename : nom sans extension (ex. : img-1)\next : poste (ex. : jpg)\ntype : type de média (ex. : image)\nsubtype : sous-type de média (ex. : image\/jpeg)\nexif : données EXIF ​​​​de l'image (array)\naudio : Mp3Info objet\nvideo : tableau d'informations vidéo de base (durée en secondes, largeur et hauteur)\n\nsite.data\nUne collection de données est accessible via site.data.&lt;filename&gt; (sans extension de fichier).\nExemples :\n\ndata\/authors.yml : site.data.authors\ndata\/authors.fr.yml : site.data.authors (si site.language = \"fr\")\ndata\/galleries\/gallery-1.json : site.data.galleries['gallery-1']\n\npage\nLa variable page contient les variables intégrées d'une page et celles définies dans le avant-plan.\n\n\n\nVariables\nDescriptif\nExemple\n\n\n\n\npage.id\nIdentifiant unique.\nblog\/post-1\n\n\npage.title\nNom du fichier (sans extension).\nPost 1\n\n\npage.date\nDate de création du fichier.\nDateHeure\n\n\npage.body\nCorps du fichier.\nMarquage\n\n\npage.content\nCorps du fichier converti en HTML.\nHTML\n\n\npage.section\nDossier racine du fichier (slugified).\nblog\n\n\npage.path\nChemin du fichier (slugified).\nblog\/post-1\n\n\npage.slug\nNom du fichier (slugified).\npost-1\n\n\npage.filepath\nChemin du système de fichiers.\nBlog\/Post 1.md\n\n\npage.type\nhomepage, page, section, vocabulary ou term.\npage\n\n\npage.pages\nCollection de toutes les sous-pages.\nCollection\n\n\npage.translations\nCollection de pages traduites.\nCollection\n\n\n\nUtilisez la méthode showable sur la collection de pages pour renvoyer uniquement les pages publiées et non les pages virtuelles\/redirectes\/exclues.\nExemple:\n{% for page in page.pages.showable %}\n  &lt;a href=\"{{ url(page) }}\"&gt;{{ page.title }}&lt;\/a&gt;\n{% endfor %}\nSections imbriquées\nDans un contexte de sections imbriquées, les propriétés page.parent, page.ancestors, page.sections et page.toplevel facilitent la construction de la navigation.\n\n\n\nVariables\nDescriptif\nExemple\n\n\n\n\npage.parent\nPage de la section parente (null si aucune).\nPage\n\n\npage.ancestors\nCollection des sections ancêtres (la plus proche en premier).\nCollection\n\n\npage.sections\nCollection des sections descendantes immédiates.\nCollection\n\n\npage.toplevel\ntrue si la page est une section de premier niveau.\nBoolean\n\n\n\nFil d'Ariane (de la page d'accueil à la page courante) :\n&lt;nav aria-label=\"breadcrumb\"&gt;\n  &lt;ul&gt;\n    &lt;li&gt;&lt;a href=\"{{ url(site.home) }}\"&gt;{{ site.title }}&lt;\/a&gt;&lt;\/li&gt;\n    {% for section in page.ancestors|reverse %}\n    &lt;li&gt;&lt;a href=\"{{ url(section) }}\"&gt;{{ section.title }}&lt;\/a&gt;&lt;\/li&gt;\n    {% endfor %}\n    {% if page.id != site.home %}\n    &lt;li&gt;&lt;a href=\"{{ url(page) }}\" aria-current=\"page\"&gt;{{ page.title }}&lt;\/a&gt;&lt;\/li&gt;\n    {% endif %}\n  &lt;\/ul&gt;\n&lt;\/nav&gt;\nUn partial breadcrumb.html.twig prêt à l'emploi est disponible :\n{{ include('partials\/breadcrumb.html.twig') }}\nMenu des sous-sections (sections descendantes immédiates de la section courante) :\n{% if page.sections|length %}\n&lt;ul&gt;\n  {% for section in page.sections|sort_by_title %}\n  &lt;li&gt;&lt;a href=\"{{ url(section) }}\"&gt;{{ section.title }}&lt;\/a&gt;&lt;\/li&gt;\n  {% endfor %}\n&lt;\/ul&gt;\n{% endif %}\nNavigation principale limitée aux sections de premier niveau (depuis n'importe quelle page) :\n&lt;nav&gt;\n  {% for section in site.page(site.home).sections|sort_by_title %}\n  &lt;a href=\"{{ url(section) }}\"&gt;{{ section.title }}&lt;\/a&gt;\n  {% endfor %}\n&lt;\/nav&gt;\nLien vers la section parente :\n{% if page.parent %}\n&lt;a href=\"{{ url(page.parent) }}\"&gt;← {{ page.parent.title }}&lt;\/a&gt;\n{% endif %}\npage.&lt;prev\/next&gt;\nNavigation entre les pages d'une même Section, triées selon le sortby de la section (ordre chronologique pour les dates).\nAvec des sous-sections, la navigation suit l'arbre des sections : les pages d'une Section de premier niveau et de toutes ses sous-sections sont enchaînées, chaque sous-section (sa page d'index) étant placée parmi les pages de sa Section parente et suivie de ses propres pages.\n\n\n\nVariables\nDescriptif\nExemple\n\n\n\n\npage.prev\nPage précédente.\nPage\n\n\npage.next\nPage suivante.\nPage\n\n\n\nExemple:\n&lt;a href=\"{{ url(page.prev) }}\"&gt;{{ page.prev.title }}&lt;\/a&gt;\npage.paginator\nPaginator vous aide à créer une navigation pour les pages de la liste : page d'accueil, sections et taxonomies.\n\n\n\nVariables\nDescriptif\n\n\n\n\npage.paginator.pages\nCollection de pages.\n\n\npage.paginator.pages_total\nNombre total de pages.\n\n\npage.paginator.count\nNombre de pages du paginateur.\n\n\npage.paginator.current\nIndex de position de la page actuelle.\n\n\npage.paginator.links.first\nID de page de la première page.\n\n\npage.paginator.links.prev\nID de page de la page précédente.\n\n\npage.paginator.links.self\nID de page de la page actuelle.\n\n\npage.paginator.links.next\nID de page de la page suivante.\n\n\npage.paginator.links.last\nID de page de la dernière page.\n\n\npage.paginator.links.path\nID de page sans l'index de position.\n\n\n\nÉtant donné que les entrées de liens sont des ID de page, vous devez utiliser la fonction url() pour créer des liens fonctionnels.\npar exemple : {{ url(page.paginator.links.next) }}\nExemple:\n{% if page.paginator %}\n&lt;div&gt;\n  {% if page.paginator.links.prev is defined %}\n  &lt;a href=\"{{ url(page.paginator.links.prev) }}\"&gt;Previous&lt;\/a&gt;\n  {% endif %}\n  {% if page.paginator.links.next is defined %}\n  &lt;a href=\"{{ url(page.paginator.links.next) }}\"&gt;Next&lt;\/a&gt;\n  {% endif %}\n&lt;\/div&gt;\n{% endif %}\nExemple:\n{% if page.paginator %}\n&lt;div&gt;\n  {% for paginator_index in 1..page.paginator.count %}\n    {% if paginator_index != page.paginator.current %}\n      {% if paginator_index == 1 %}\n  &lt;a href=\"{{ url(page.paginator.links.first) }}\"&gt;{{ paginator_index }}&lt;\/a&gt;\n      {% else %}\n  &lt;a href=\"{{ url(page.paginator.links.path ~ '\/' ~ paginator_index) }}\"&gt;{{ paginator_index }}&lt;\/a&gt;\n      {% endif %}\n    {% else %}\n  {{ paginator_index }}\n    {% endif %}\n  {% endfor %}\n&lt;\/div&gt;\n{% endif %}\nTaxonomie\nVariables disponibles dans les templates vocabulary et term.\nVocabulaire\nPage \/&lt;plural&gt;\/ (ex. : \/categories\/).\n\n\n\nVariables\nDescriptif\n\n\n\n\npage.plural\nNom de vocabulaire au pluriel.\n\n\npage.singular\nNom de vocabulaire au singulier.\n\n\npage.terms\nListe de termes (Collection).\n\n\n\nChaque terme de page.terms fournit term.id (identifiant du terme, ex. : categories\/php), term.name (nom du terme, ex. : PHP) et le nombre de ses pages avec term|length.\nTerme\nPage \/&lt;plural&gt;\/&lt;term&gt;\/ (ex. : \/categories\/php\/).\n\n\n\nVariables\nDescriptif\n\n\n\n\npage.title\nNom du terme.\n\n\npage.term\nIdentifiant du terme (ex. : categories\/php).\n\n\npage.plural\nNom de vocabulaire au pluriel.\n\n\npage.singular\nNom de vocabulaire au singulier.\n\n\npage.pages\nListe des pages dans ce terme, triées par date (Collection).\n\n\n\nExemple de taxonomie\nConfiguration :\ntaxonomies:\n  categories: category\nFront matter d’une page :\n---\ncategories: [\"Data Sovereignty\"]\n---\nListe des termes (\/categories\/), dans layouts\/taxonomy\/categories.html.twig :\n{% extends 'page.html.twig' %}\n\n{% block content %}\n  &lt;h1&gt;{{ page.title }}&lt;\/h1&gt;\n  &lt;ul&gt;\n  {% for term in page.terms %}\n    &lt;li&gt;&lt;a href=\"{{ url(term.id) }}\"&gt;{{ term.name }}&lt;\/a&gt; ({{ term|length }})&lt;\/li&gt;\n  {% endfor %}\n  &lt;\/ul&gt;\n{% endblock %}\nListe des pages d’un terme (\/categories\/data-sovereignty\/), dans layouts\/taxonomy\/category.html.twig :\n{% extends 'page.html.twig' %}\n\n{% block content %}\n  &lt;h1&gt;{{ page.title }}&lt;\/h1&gt;\n  {% for p in page.paginator.pages ?? page.pages %}\n    &lt;article&gt;\n      &lt;h2&gt;&lt;a href=\"{{ url(p) }}\"&gt;{{ p.title }}&lt;\/a&gt;&lt;\/h2&gt;\n    &lt;\/article&gt;\n  {% endfor %}\n  &lt;a href=\"{{ url(page.plural) }}\"&gt;Toutes les {{ page.plural }}&lt;\/a&gt;\n{% endblock %}\nLiens vers les termes de la page courante, dans un template de page :\n{% for category in page.categories ?? [] %}\n  &lt;a href=\"{{ url('categories\/' ~ category) }}\"&gt;{{ category }}&lt;\/a&gt;\n{% endfor %}\nLa fonction url() « slugifie » la chaîne fournie pour trouver la page correspondante : url('categories\/Data Sovereignty') retourne \/categories\/data-sovereignty\/.\nVous pouvez aussi utiliser le partial intégré {{ include('partials\/terms-list.html.twig', {vocabulary: 'categories'}) }}.\ncecil\n\n\n\nVariables\nDescriptif\n\n\n\n\ncecil.url\nURL du site Cecil.\n\n\ncecil.version\nVersion actuelle de Cecil.\n\n\ncecil.poweredby\nImprimez Cecil v%s, avec %s est la version actuelle.\n\n\n",
      "content_html": "<h1>Variables</h1>\n<blockquote>\n<p>L'application transmet des variables aux templates pour manipulation dans le modèle. Les variables peuvent également avoir des attributs ou des éléments auxquels vous pouvez accéder.\nUtilisez un point (.) pour accéder aux attributs d'une variable : <code translate=\"no\">{{ foo.bar }}</code></p>\n</blockquote>\n<p>Vous pouvez utiliser des variables de différentes portées : <a href=\"#site\"><code translate=\"no\">site</code></a>, <a href=\"#page\"><code translate=\"no\">page</code></a>, <a href=\"#cecil\"><code translate=\"no\">cecil</code></a>.</p>\n<h2 id=\"site\">site</h2>\n<p>La variable <code translate=\"no\">site</code> contient des variables intégrées <strong>et</strong> celles définies dans la <a href=\"../configuration/index.fr.md\">configuration</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">site.pages</code></td>\n<td>Collection de toutes les pages, dans la langue actuelle.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.allpages</code></td>\n<td>Collection de toutes les pages, dans toutes les langues.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.page(id)</code></td>\n<td>Une page avec l'ID donné.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.taxonomies</code></td>\n<td>Recueil de vocabulaires.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.home</code></td>\n<td>ID de la page d'accueil.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.time</code></td>\n<td>Actuel <a href=\"https://wikipedia.org/wiki/Unix_time\" target=\"_blank\" rel=\"noopener noreferrer\"><em>Timestamp</em></a>.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.debug</code></td>\n<td>État du mode débogage (<code translate=\"no\">true</code> ou <code translate=\"no\">false</code>).</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.build</code></td>\n<td>ID de build actuel.</td>\n</tr>\n</tbody>\n</table>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">\"My amazing website!\"</span></code></pre>\n<p>Peut être affiché dans un modèle avec :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ site.title }}</span></code></pre>\n<aside class=\"note note-important\"><p>Utilisez la méthode <code translate=\"no\">showable</code> sur la collection de pages pour renvoyer uniquement les pages publiées et non les pages <em>virtuelles/redirectes/exclues</em>.</p>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> page in site.pages.showable %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ page.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span></code></pre></aside>\n<aside class=\"note note-warning\"><p>Dans certains cas, vous pouvez rencontrer des conflits entre la configuration et les variables intégrées (ex. : <code translate=\"no\">pages.default</code> configuration), vous pouvez donc utiliser <code translate=\"no\">config.&lt;variable&gt;</code> (avec <code translate=\"no\">&lt;variable&gt;</code> est le nom/chemin de la variable) pour accéder directement à la configuration brute.</p>\n<p>Exemple:</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ config.pages.default.sitemap.priority }}</span></code></pre></aside>\n<h3 id=\"site-menus\">site.menus</h3>\n<p>Bouclez sur <code translate=\"no\">site.menus.&lt;menu&gt;</code> pour obtenir chaque entrée de la collection <code translate=\"no\">&lt;menu&gt;</code> (par exemple : <code translate=\"no\">main</code>).</p>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">&lt;entry&gt;.name</code></td>\n<td>Nom de l'entrée.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">&lt;entry&gt;.url</code></td>\n<td>URL d'entrée.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">&lt;entry&gt;.weight</code></td>\n<td>Poids d'entrée (utile pour trier les entrées de menu).</td>\n</tr>\n</tbody>\n</table>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ol</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> entry in site.menus.main|sort_by_weight %}</span><span class=\"xml\">\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(entry.url) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">data-weight</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ entry.weight }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ entry.name }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">ol</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">nav</span>&gt;</span></span></code></pre>\n<h3 id=\"site-language\">site.language</h3>\n<p>Informations sur la langue actuelle.</p>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">site.language</code></td>\n<td>Code de langue (ex. : <code translate=\"no\">en</code>).</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.language.name</code></td>\n<td>Nom de la langue (par exemple : <code translate=\"no\">English</code>).</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.language.locale</code></td>\n<td>Langue <a href=\"../configuration/3-locale-codes.fr.md\">code local</a> (par exemple : <code translate=\"no\">en_US</code>).</td>\n</tr>\n<tr>\n<td><code translate=\"no\">site.language.weight</code></td>\n<td>Position de la langue dans la liste <code translate=\"no\">languages</code>.</td>\n</tr>\n</tbody>\n</table>\n<aside class=\"note note-tip\"><p>Vous pouvez récupérer <code translate=\"no\">name</code>, <code translate=\"no\">locale</code> et <code translate=\"no\">weight</code> d'un langage spécifique en passant son code en paramètre.\npar exemple : <code translate=\"no\">site.language.name('fr')</code>.</p></aside>\n<h3 id=\"site-static\">site.static</h3>\n<p>La collection de fichiers statiques est accessible via <code translate=\"no\">site.static</code> si le <a href=\"../configuration/5-data-static.fr.md#static-load\"><em>static load</em></a> est activé.</p>\n<p>Chaque fichier expose les propriétés suivantes :</p>\n<ul>\n<li><code translate=\"no\">path</code> : chemin relatif (ex. : <code translate=\"no\">/images/img-1.jpg</code>)</li>\n<li><code translate=\"no\">date</code> : date de création (<em>timestamp</em>)</li>\n<li><code translate=\"no\">updated</code> : date de modification (<em>timestamp</em>)</li>\n<li><code translate=\"no\">name</code> : nom (ex. : <code translate=\"no\">img-1.jpg</code>)</li>\n<li><code translate=\"no\">basename</code> : nom sans extension (ex. : <code translate=\"no\">img-1</code>)</li>\n<li><code translate=\"no\">ext</code> : poste (ex. : <code translate=\"no\">jpg</code>)</li>\n<li><code translate=\"no\">type</code> : type de média (ex. : <code translate=\"no\">image</code>)</li>\n<li><code translate=\"no\">subtype</code> : sous-type de média (ex. : <code translate=\"no\">image/jpeg</code>)</li>\n<li><code translate=\"no\">exif</code> : données EXIF ​​​​de l'image (<em>array</em>)</li>\n<li><code translate=\"no\">audio</code> : <a href=\"https://github.com/wapmorgan/Mp3Info#audio-information\" target=\"_blank\" rel=\"noopener noreferrer\">Mp3Info</a> objet</li>\n<li><code translate=\"no\">video</code> : tableau d'informations vidéo de base (durée en secondes, largeur et hauteur)</li>\n</ul>\n<h3 id=\"site-data\">site.data</h3>\n<p>Une collection de données est accessible via <code translate=\"no\">site.data.&lt;filename&gt;</code> (sans extension de fichier).</p>\n<p><em>Exemples :</em></p>\n<ul>\n<li><code translate=\"no\">data/authors.yml</code> : <code translate=\"no\">site.data.authors</code></li>\n<li><code translate=\"no\">data/authors.fr.yml</code> : <code translate=\"no\">site.data.authors</code> (si <code translate=\"no\">site.language</code> = \"fr\")</li>\n<li><code translate=\"no\">data/galleries/gallery-1.json</code> : <code translate=\"no\">site.data.galleries['gallery-1']</code></li>\n</ul>\n<h2 id=\"page\">page</h2>\n<p>La variable <code translate=\"no\">page</code> contient les variables intégrées d'une page <strong>et</strong> celles définies dans le <a href=\"../content/1-pages.fr.md#front-matter\">avant-plan</a>.</p>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n<th>Exemple</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">page.id</code></td>\n<td>Identifiant unique.</td>\n<td><code translate=\"no\">blog/post-1</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.title</code></td>\n<td>Nom du fichier (sans extension).</td>\n<td><code translate=\"no\">Post 1</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.date</code></td>\n<td>Date de création du fichier.</td>\n<td><em>DateHeure</em></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.body</code></td>\n<td>Corps du fichier.</td>\n<td><em>Marquage</em></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.content</code></td>\n<td>Corps du fichier converti en HTML.</td>\n<td><em>HTML</em></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.section</code></td>\n<td>Dossier racine du fichier (<em>slugified</em>).</td>\n<td><code translate=\"no\">blog</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.path</code></td>\n<td>Chemin du fichier (<em>slugified</em>).</td>\n<td><code translate=\"no\">blog/post-1</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.slug</code></td>\n<td>Nom du fichier (<em>slugified</em>).</td>\n<td><code translate=\"no\">post-1</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.filepath</code></td>\n<td>Chemin du système de fichiers.</td>\n<td><code translate=\"no\">Blog/Post 1.md</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.type</code></td>\n<td><code translate=\"no\">homepage</code>, <code translate=\"no\">page</code>, <code translate=\"no\">section</code>, <code translate=\"no\">vocabulary</code> ou <code translate=\"no\">term</code>.</td>\n<td><code translate=\"no\">page</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.pages</code></td>\n<td>Collection de toutes les sous-pages.</td>\n<td><em>Collection</em></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.translations</code></td>\n<td>Collection de pages traduites.</td>\n<td><em>Collection</em></td>\n</tr>\n</tbody>\n</table>\n<aside class=\"note note-important\"><p>Utilisez la méthode <code translate=\"no\">showable</code> sur la collection de pages pour renvoyer uniquement les pages publiées et non les pages <em>virtuelles/redirectes/exclues</em>.</p>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> page in page.pages.showable %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ page.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span></code></pre></aside>\n<h3 id=\"sections-imbriquees\">Sections imbriquées</h3>\n<p>Dans un contexte de <a href=\"../content/1-pages.fr.md#sous-section\">sections imbriquées</a>, les propriétés <code translate=\"no\">page.parent</code>, <code translate=\"no\">page.ancestors</code>, <code translate=\"no\">page.sections</code> et <code translate=\"no\">page.toplevel</code> facilitent la construction de la navigation.</p>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n<th>Exemple</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">page.parent</code></td>\n<td>Page de la <em>section</em> parente (<code translate=\"no\">null</code> si aucune).</td>\n<td><em>Page</em></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.ancestors</code></td>\n<td>Collection des <em>sections</em> ancêtres (la plus proche en premier).</td>\n<td><em>Collection</em></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.sections</code></td>\n<td>Collection des <em>sections</em> descendantes immédiates.</td>\n<td><em>Collection</em></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.toplevel</code></td>\n<td><code translate=\"no\">true</code> si la page est une <em>section</em> de premier niveau.</td>\n<td><em>Boolean</em></td>\n</tr>\n</tbody>\n</table>\n<p><em>Fil d'Ariane (de la page d'accueil à la page courante) :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav</span> <span class=\"hljs-attr\">aria-label</span>=<span class=\"hljs-string\">\"breadcrumb\"</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(site.home) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ site.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n    </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> section in page.ancestors|<span class=\"hljs-keyword\">reverse</span> %}</span><span class=\"xml\">\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(section) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ section.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n    </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span><span class=\"xml\">\n    </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> page.id != site.home %}</span><span class=\"xml\">\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">aria-current</span>=<span class=\"hljs-string\">\"page\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ page.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n    </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">ul</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">nav</span>&gt;</span></span></code></pre>\n<aside class=\"note note-tip\"><p>Un partial <a href=\"https://github.com/Cecilapp/Cecil/blob/main/resources/layouts/partials/breadcrumb.html.twig\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">breadcrumb.html.twig</code></a> prêt à l'emploi est disponible :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ <span class=\"hljs-name\">include</span><span class=\"hljs-params\">('partials/breadcrumb.html.twig')</span> }}</span></code></pre></aside>\n<p><em>Menu des sous-sections (sections descendantes immédiates de la section courante) :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> page.sections|<span class=\"hljs-keyword\">length</span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> section in page.sections|sort_by_title %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(section) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ section.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">ul</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span></code></pre>\n<p><em>Navigation principale limitée aux sections de premier niveau (depuis n'importe quelle page) :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> section in site.page(site.home).sections|sort_by_title %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(section) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ section.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">nav</span>&gt;</span></span></code></pre>\n<p><em>Lien vers la section parente :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> page.<span class=\"hljs-name\">parent</span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page.<span class=\"hljs-name\">parent</span>) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span>← </span><span class=\"hljs-template-variable\">{{ page.<span class=\"hljs-name\">parent</span>.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span></code></pre>\n<h3 id=\"page-prev-next\">page.&lt;prev/next&gt;</h3>\n<p>Navigation entre les pages d'une même <em>Section</em>, triées selon le <code translate=\"no\">sortby</code> de la section (ordre chronologique pour les dates).</p>\n<p>Avec des <a href=\"../content/1-pages.fr.md#sous-section\">sous-sections</a>, la navigation suit l'arbre des sections : les pages d'une <em>Section</em> de premier niveau et de toutes ses sous-sections sont enchaînées, chaque sous-section (sa page d'index) étant placée parmi les pages de sa <em>Section</em> parente et suivie de ses propres pages.</p>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n<th>Exemple</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">page.prev</code></td>\n<td>Page précédente.</td>\n<td><em>Page</em></td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.next</code></td>\n<td>Page suivante.</td>\n<td><em>Page</em></td>\n</tr>\n</tbody>\n</table>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page.prev) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ page.prev.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span></span></code></pre>\n<h3 id=\"page-paginator\">page.paginator</h3>\n<p><em>Paginator</em> vous aide à créer une navigation pour les pages de la liste : page d'accueil, sections et taxonomies.</p>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">page.paginator.pages</code></td>\n<td>Collection de pages.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.paginator.pages_total</code></td>\n<td>Nombre total de pages.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.paginator.count</code></td>\n<td>Nombre de pages du paginateur.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.paginator.current</code></td>\n<td>Index de position de la page actuelle.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.paginator.links.first</code></td>\n<td>ID de page de la première page.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.paginator.links.prev</code></td>\n<td>ID de page de la page précédente.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.paginator.links.self</code></td>\n<td>ID de page de la page actuelle.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.paginator.links.next</code></td>\n<td>ID de page de la page suivante.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.paginator.links.last</code></td>\n<td>ID de page de la dernière page.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.paginator.links.path</code></td>\n<td>ID de page sans l'index de position.</td>\n</tr>\n</tbody>\n</table>\n<aside class=\"note note-important\"><p>Étant donné que les entrées de liens sont des ID de page, vous devez utiliser la fonction <code translate=\"no\">url()</code> pour créer des liens fonctionnels.\npar exemple : <code translate=\"no\">{{ url(page.paginator.links.next) }}</code></p></aside>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> page.paginator %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> page.paginator.links.prev is defined %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page.paginator.links.prev) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span>Previous<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span><span class=\"xml\">\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> page.paginator.links.next is defined %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page.paginator.links.next) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span>Next<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> page.paginator %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> paginator_index in 1..page.paginator.count %}</span><span class=\"xml\">\n    </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> paginator_index != page.paginator.current %}</span><span class=\"xml\">\n      </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> paginator_index == 1 %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page.paginator.links.first) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ paginator_index }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n      </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">else</span> %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page.paginator.links.path ~ '/' ~ paginator_index) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ paginator_index }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n      </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span><span class=\"xml\">\n    </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">else</span> %}</span><span class=\"xml\">\n  </span><span class=\"hljs-template-variable\">{{ paginator_index }}</span><span class=\"xml\">\n    </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span><span class=\"xml\">\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span></code></pre>\n<h3 id=\"taxonomie\">Taxonomie</h3>\n<p>Variables disponibles dans les templates <em>vocabulary</em> et <em>term</em>.</p>\n<h4>Vocabulaire</h4>\n<p>Page <code translate=\"no\">/&lt;plural&gt;/</code> (ex. : <code translate=\"no\">/categories/</code>).</p>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">page.plural</code></td>\n<td>Nom de vocabulaire au pluriel.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.singular</code></td>\n<td>Nom de vocabulaire au singulier.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.terms</code></td>\n<td>Liste de termes (<em>Collection</em>).</td>\n</tr>\n</tbody>\n</table>\n<p>Chaque terme de <code translate=\"no\">page.terms</code> fournit <code translate=\"no\">term.id</code> (identifiant du terme, ex. : <code translate=\"no\">categories/php</code>), <code translate=\"no\">term.name</code> (nom du terme, ex. : <code translate=\"no\">PHP</code>) et le nombre de ses pages avec <code translate=\"no\">term|length</code>.</p>\n<h4>Terme</h4>\n<p>Page <code translate=\"no\">/&lt;plural&gt;/&lt;term&gt;/</code> (ex. : <code translate=\"no\">/categories/php/</code>).</p>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">page.title</code></td>\n<td>Nom du terme.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.term</code></td>\n<td>Identifiant du terme (ex. : <code translate=\"no\">categories/php</code>).</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.plural</code></td>\n<td>Nom de vocabulaire au pluriel.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.singular</code></td>\n<td>Nom de vocabulaire au singulier.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">page.pages</code></td>\n<td>Liste des pages dans ce terme, triées par date (<em>Collection</em>).</td>\n</tr>\n</tbody>\n</table>\n<h4>Exemple de taxonomie</h4>\n<p>Configuration :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">taxonomies:</span>\n  <span class=\"hljs-attr\">categories:</span> <span class=\"hljs-string\">category</span></code></pre>\n<p>Front matter d’une page :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">categories:</span> <span class=\"hljs-string\">[\"Data</span> <span class=\"hljs-string\">Sovereignty\"]</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<p>Liste des termes (<code translate=\"no\">/categories/</code>), dans <code translate=\"no\">layouts/taxonomy/categories.html.twig</code> :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">extends</span></span> 'page.html.twig' %}</span><span class=\"xml\">\n\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">block</span></span> content %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ page.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">h1</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> term in page.terms %}</span><span class=\"xml\">\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(term.id) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ term.name }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span> (</span><span class=\"hljs-template-variable\">{{ term|<span class=\"hljs-keyword\">length</span> }}</span><span class=\"xml\">)<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">ul</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endblock</span></span> %}</span></code></pre>\n<p>Liste des pages d’un terme (<code translate=\"no\">/categories/data-sovereignty/</code>), dans <code translate=\"no\">layouts/taxonomy/category.html.twig</code> :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">extends</span></span> 'page.html.twig' %}</span><span class=\"xml\">\n\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">block</span></span> content %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ page.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">h1</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> p in page.paginator.pages ?? page.pages %}</span><span class=\"xml\">\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">article</span>&gt;</span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(p) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ p.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">h2</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">article</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(page.plural) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span>Toutes les </span><span class=\"hljs-template-variable\">{{ page.plural }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endblock</span></span> %}</span></code></pre>\n<p>Liens vers les termes de la page courante, dans un template de page :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> category in page.categories ?? [] %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url('categories/' ~ category) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ category }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span></code></pre>\n<aside class=\"note note-tip\"><p>La fonction <a href=\"reference/1-functions.fr.md#url\"><code translate=\"no\">url()</code></a> « slugifie » la chaîne fournie pour trouver la page correspondante : <code translate=\"no\">url('categories/Data Sovereignty')</code> retourne <code translate=\"no\">/categories/data-sovereignty/</code>.</p>\n<p>Vous pouvez aussi utiliser le partial intégré <code translate=\"no\">{{ include('partials/terms-list.html.twig', {vocabulary: 'categories'}) }}</code>.</p></aside>\n<h2 id=\"cecil\">cecil</h2>\n<table>\n<thead>\n<tr>\n<th>Variables</th>\n<th>Descriptif</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">cecil.url</code></td>\n<td>URL du site Cecil.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">cecil.version</code></td>\n<td>Version actuelle de Cecil.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">cecil.poweredby</code></td>\n<td>Imprimez <code translate=\"no\">Cecil v%s</code>, avec <code translate=\"no\">%s</code> est la version actuelle.</td>\n</tr>\n</tbody>\n</table>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/templates/reference/tris/",
      "url": "https://cecil-945.pages.dev/fr/documentation/templates/reference/tris/",
      "title": "Tris",
      "summary": "Triez des collections de pages, menus ou taxonomies.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Tris\nTri des collections (de pages, menus ou taxonomies).\nsort_by_title\nTrie une collection par titre (avec tri naturel).\n{{ collection|sort_by_title }}\nExemple:\n{{ site.pages|sort_by_title }}\nsort_by_date\nTrie une collection par date (la plus récente en premier).\n{{ collection|sort_by_date(variable='date', desc_title=false) }}\nExemple:\n{# sort by date #}\n{{ site.pages|sort_by_date }}\n{# sort by updated variable instead of date #}\n{{ site.pages|sort_by_date(variable='updated') }}\n{# sort items with the same date by desc title #}\n{{ site.pages|sort_by_date(desc_title=true) }}\n{# reverse sort #}\n{{ site.pages|sort_by_date|reverse }}\nsort_by_weight\nTrie une collection par poids (le plus léger en premier).\n{{ collection|sort_by_weight }}\nExemple:\n{{ site.menus.main|sort_by_weight }}\nsort\nPour les cas plus complexes, vous devez utiliser le sort natif de Twig.\nExemple:\n{% set files = site.static|sort((a, b) =&gt; a.date|date('U') &lt; b.date|date('U')) %}",
      "content_html": "<h1>Tris</h1>\n<p>Tri des collections (de pages, menus ou taxonomies).</p>\n<h2 id=\"sort-by-title\">sort_by_title</h2>\n<p>Trie une collection par titre (avec <a href=\"https://en.wikipedia.org/wiki/Natural_sort_order\" target=\"_blank\" rel=\"noopener noreferrer\">tri naturel</a>).</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ collection|sort_by_title }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ site.pages|sort_by_title }}</span></code></pre>\n<h2 id=\"sort-by-date\">sort_by_date</h2>\n<p>Trie une collection par date (la plus récente en premier).</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ collection|sort_by_date(variable='<span class=\"hljs-name\">date</span>', desc_title=false) }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# sort by date #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ site.pages|sort_by_date }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# sort by updated variable instead of date #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ site.pages|sort_by_date(variable='updated') }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# sort items with the same date by desc title #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ site.pages|sort_by_date(desc_title=true) }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# reverse sort #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ site.pages|sort_by_date|<span class=\"hljs-keyword\">reverse</span> }}</span></code></pre>\n<h2 id=\"sort-by-weight\">sort_by_weight</h2>\n<p>Trie une collection par poids (le plus léger en premier).</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ collection|sort_by_weight }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ site.menus.main|sort_by_weight }}</span></code></pre>\n<h2 id=\"sort\">sort</h2>\n<p>Pour les cas plus complexes, vous devez utiliser <a href=\"https://twig.symfony.com/doc/filters/sort.html\" target=\"_blank\" rel=\"noopener noreferrer\">le <code translate=\"no\">sort</code></a> natif de Twig.</p>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> files = site.static|<span class=\"hljs-keyword\">sort</span>((a, b) =&gt; a.<span class=\"hljs-name\">date</span>|<span class=\"hljs-keyword\">date</span>('U') &lt; b.<span class=\"hljs-name\">date</span>|<span class=\"hljs-keyword\">date</span>('U')) %}</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/templates/reference/filtres/",
      "url": "https://cecil-945.pages.dev/fr/documentation/templates/reference/filtres/",
      "title": "Filtres",
      "summary": "filter_by, markdown_to_html, toc, slugify, excerpt, highlight, preg_*, etc.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Filtres\nLes variables peuvent être modifiées par filtres. Les filtres sont séparés de la variable par un symbole de barre verticale (|). Plusieurs filtres peuvent être chaînés. La sortie d’un filtre est appliquée au suivant.\n{{ page.title|truncate(25)|capitalize }}\nfilter_by\nFiltre une collection de pages par nom\/valeur de variable.\n{{ collection|filter_by(variable, value) }}\nExemple:\n{{ pages|filter_by('section', 'blog') }}\nfilter\nPour les cas plus complexes, vous devez utiliser le filter natif de Twig.\nExemple:\n{% pages|filter(p =&gt; p.virtual == false and p.id not in ['page-1', 'page-2']) %}\nmarkdown_to_html\nConvertit une chaîne Markdown en HTML.\n{{ markdown|markdown_to_html }}\n{% apply markdown_to_html %}\n{# Markdown here #}\n{% endapply %}\nExemples :\n{% set markdown = '**This is bold text**' %}\n{{ markdown|markdown_to_html }}\n{% apply markdown_to_html %}\n**This is bold text**\n{% endapply %}\ntoc\nExtrait uniquement les en-têtes correspondant au selectors donné (h2, h3, etc.), ou à ceux définis dans la configuration pages.body.toc s'ils ne sont pas spécifiés.\nLe paramètre format définit le format de sortie : html ou json.\nLe paramètre url est utilisé pour créer des liens vers des titres.\n{{ markdown|toc(format, selectors, url) }}\nExemples :\n{{ page.body|toc }}\n{{ page.body|toc('html') }}\n{{ page.body|toc(selectors=['h2']) }}\n{{ page.body|toc(url=url(page)) }}\njson_decode\nConvertit une chaîne JSON en tableau.\n{{ json|json_decode }}\nExemple:\n{% set json = '{\"foo\": \"bar\"}' %}\n{% set array = json|json_decode %}\n{{ array.foo }}\nyaml_parse\nConvertit une chaîne YAML en tableau.\n{{ yaml|yaml_parse }}\nExemple:\n{% set yaml = 'key: value' %}\n{% set array = yaml|yaml_parse %}\n{{ array.key }}\nslugify\nConvertit une chaîne en slug.\n{{ string|slugify }}\nu\nLe filtre u enveloppe un texte dans un objet Unicode (une instance Symfony UnicodeString) qui expose des méthodes pour « manipuler » la chaîne.\nExemple:\n{{ 'cecil_string with twig'|u.camel.title }}\n\nCecilStringAvecTwig\n\nsingular\nLe filtre singular transforme un nom donné au pluriel en sa version singulière.\n{{ string|singular(locale)}}\nExemple:\n{# English (en) rules are used by default #}\n{{ 'partitions'|singular }}\n\npartition\n\n{{ 'partitions'|singular('fr') }}\n\npartition\n\nplural\nLe filtre plural transforme un nom donné au singulier en sa version plurielle.\n{{ string|plural(locale)}}\nExemple:\n{# English (en) rules are used by default #}\n{{ 'animal'|plural }}\n\nanimaux\n\n{{ 'animal'|plural('fr') }}\n\nanimaux\n\nexcerpt\nTronque une chaîne et ajoute un suffixe.\n{{ string|excerpt(length, suffix) }}\n\n\n\nOptions\nDescriptif\nTapez\nPar défaut\n\n\n\n\nlongueur\nTronque après ce nombre de caractères.\nentier\n450\n\n\nsuffixe\nAjoute des caractères.\nchaîne\n…\n\n\n\nExemples :\n{{ variable|excerpt }}\n{{ variable|excerpt(250, '...') }}\nexcerpt_html\nLit les caractères avant ou après la balise &lt;!-- excerpt --&gt; ou &lt;!-- break --&gt;.\nVoir Documentation de contenu pour plus de détails.\n{{ string|excerpt_html({separator, capture}) }}\n\n\n\nOptions\nDescriptif\nTapez\nPar défaut\n\n\n\n\nséparateur\nChaîne à utiliser comme séparateur.\nchaîne\nexcerpt|break\n\n\ncapturer\nPièce à capturer, before ou after le séparateur.\nchaîne\nbefore\n\n\n\nExemples :\n{{ variable|excerpt_html }}\n{{ variable|excerpt_html({separator: 'excerpt|break', capture: 'before'}) }}\n{{ variable|excerpt_html({capture: 'after'}) }}\nhighlight\nMet en surbrillance une chaîne de code avec highlight.php.\n{{ code|highlight(language) }}\nExemples :\n{{ '&lt;?php echo $highlighted-&gt;value; ?&gt;'|highlight('php') }}\npreg_split\nDivise une chaîne en un tableau à l'aide d'une expression régulière.\n{{ string|preg_split(pattern, limit) }}\nExemple:\n{% set headers = page.content|preg_split('\/&lt;br[^&gt;]*&gt;\/') %}\npreg_match_all\nEffectue une correspondance d'expression régulière et renvoie le groupe pour toutes les correspondances.\n{{ string|preg_match_all(pattern, group) }}\nExemple:\n{% set tags = page.content|preg_match_all('\/&lt;[^&gt;]+&gt;(.*)&lt;\\\/[^&gt;]+&gt;\/') %}\nhex_to_rgb\nConvertit une couleur hexadécimale en RVB.\n{{ color|hex_to_rgb }}",
      "content_html": "<h1>Filtres</h1>\n<p>Les variables peuvent être modifiées par <a href=\"https://twig.symfony.com/doc/filters/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">filtres</a>. Les filtres sont séparés de la variable par un symbole de barre verticale (<code translate=\"no\">|</code>). Plusieurs filtres peuvent être chaînés. La sortie d’un filtre est appliquée au suivant.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ page.title|truncate(25)|<span class=\"hljs-keyword\">capitalize</span> }}</span></code></pre>\n<h2 id=\"filter-by\">filter_by</h2>\n<p>Filtre une collection de pages par nom/valeur de variable.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ collection|filter_by(variable, value) }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ pages|filter_by('section', 'blog') }}</span></code></pre>\n<h2 id=\"filter\">filter</h2>\n<p>Pour les cas plus complexes, vous devez utiliser <a href=\"https://twig.symfony.com/doc/filters/filter.html\" target=\"_blank\" rel=\"noopener noreferrer\">le <code translate=\"no\">filter</code></a> natif de Twig.</p>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">pages</span>|<span class=\"hljs-keyword\">filter</span>(p =&gt; p.virtual == false and p.id not in ['page-1', 'page-2']) %}</span></code></pre>\n<h2 id=\"markdown-to-html\">markdown_to_html</h2>\n<p>Convertit une chaîne Markdown en HTML.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ markdown|markdown_to_html }}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">apply</span></span> markdown_to_html %}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# Markdown here #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endapply</span></span> %}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> markdown = '**This is bold text**' %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ markdown|markdown_to_html }}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">apply</span></span> markdown_to_html %}</span><span class=\"xml\">\n**This is bold text**\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endapply</span></span> %}</span></code></pre>\n<h2 id=\"toc\">toc</h2>\n<p>Extrait uniquement les en-têtes correspondant au <code translate=\"no\">selectors</code> donné (h2, h3, etc.), ou à ceux définis dans la configuration <code translate=\"no\">pages.body.toc</code> s'ils ne sont pas spécifiés.\nLe paramètre <code translate=\"no\">format</code> définit le format de sortie : <code translate=\"no\">html</code> ou <code translate=\"no\">json</code>.\nLe paramètre <code translate=\"no\">url</code> est utilisé pour créer des liens vers des titres.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ markdown|toc(format, selectors, url) }}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ page.body|toc }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ page.body|toc('html') }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ page.body|toc(selectors=['h2']) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ page.body|toc(url=url(page)) }}</span></code></pre>\n<h2 id=\"json-decode\">json_decode</h2>\n<p>Convertit une chaîne JSON en tableau.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ json|json_decode }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> json = '{\"foo\": \"bar\"}' %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> array = json|json_decode %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ array.foo }}</span></code></pre>\n<h2 id=\"yaml-parse\">yaml_parse</h2>\n<p>Convertit une chaîne YAML en tableau.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ yaml|yaml_parse }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> yaml = 'key: value' %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> array = yaml|yaml_parse %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ array.key }}</span></code></pre>\n<h2 id=\"slugify\">slugify</h2>\n<p>Convertit une chaîne en slug.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ string|slugify }}</span></code></pre>\n<h2 id=\"u\">u</h2>\n<p>Le filtre <code translate=\"no\">u</code> enveloppe un texte dans un objet Unicode (une <a href=\"https://symfony.com/doc/current/components/string.html\" target=\"_blank\" rel=\"noopener noreferrer\">instance Symfony UnicodeString</a>) qui expose des méthodes pour « manipuler » la chaîne.</p>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ 'cecil_string with twig'|u.camel.title }}</span></code></pre>\n<blockquote>\n<p>CecilStringAvecTwig</p>\n</blockquote>\n<h2 id=\"singular\">singular</h2>\n<p>Le filtre <code translate=\"no\">singular</code> transforme un nom donné au pluriel en sa version singulière.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ string|singular(locale)}}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# English (en) rules are used by default #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ 'partitions'|singular }}</span></code></pre>\n<blockquote>\n<p>partition</p>\n</blockquote>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ 'partitions'|singular('fr') }}</span></code></pre>\n<blockquote>\n<p>partition</p>\n</blockquote>\n<h2 id=\"plural\">plural</h2>\n<p>Le filtre <code translate=\"no\">plural</code> transforme un nom donné au singulier en sa version plurielle.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ string|plural(locale)}}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# English (en) rules are used by default #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ 'animal'|plural }}</span></code></pre>\n<blockquote>\n<p>animaux</p>\n</blockquote>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ 'animal'|plural('fr') }}</span></code></pre>\n<blockquote>\n<p>animaux</p>\n</blockquote>\n<h2 id=\"excerpt\">excerpt</h2>\n<p>Tronque une chaîne et ajoute un suffixe.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ string|excerpt(length, suffix) }}</span></code></pre>\n<table>\n<thead>\n<tr>\n<th>Options</th>\n<th>Descriptif</th>\n<th>Tapez</th>\n<th>Par défaut</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>longueur</td>\n<td>Tronque après ce nombre de caractères.</td>\n<td>entier</td>\n<td>450</td>\n</tr>\n<tr>\n<td>suffixe</td>\n<td>Ajoute des caractères.</td>\n<td>chaîne</td>\n<td><code translate=\"no\">…</code></td>\n</tr>\n</tbody>\n</table>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ variable|excerpt }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ variable|excerpt(250, '...') }}</span></code></pre>\n<h2 id=\"excerpt-html\">excerpt_html</h2>\n<p>Lit les caractères avant ou après la balise <code translate=\"no\">&lt;!-- excerpt --&gt;</code> ou <code translate=\"no\">&lt;!-- break --&gt;</code>.\nVoir <a href=\"../../content/3-markdown.fr.md#extrait\">Documentation de contenu</a> pour plus de détails.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ string|excerpt_html({separator, capture}) }}</span></code></pre>\n<table>\n<thead>\n<tr>\n<th>Options</th>\n<th>Descriptif</th>\n<th>Tapez</th>\n<th>Par défaut</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>séparateur</td>\n<td>Chaîne à utiliser comme séparateur.</td>\n<td>chaîne</td>\n<td><code translate=\"no\">excerpt|break</code></td>\n</tr>\n<tr>\n<td>capturer</td>\n<td>Pièce à capturer, <code translate=\"no\">before</code> ou <code translate=\"no\">after</code> le séparateur.</td>\n<td>chaîne</td>\n<td><code translate=\"no\">before</code></td>\n</tr>\n</tbody>\n</table>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ variable|excerpt_html }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ variable|excerpt_html({separator: 'excerpt|break', capture: 'before'}) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ variable|excerpt_html({capture: 'after'}) }}</span></code></pre>\n<h2 id=\"highlight\">highlight</h2>\n<p>Met en surbrillance une chaîne de code avec <a href=\"https://github.com/scrivo/highlight.php\" target=\"_blank\" rel=\"noopener noreferrer\">highlight.php</a>.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ code|highlight(language) }}</span></code></pre>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ '&lt;?php echo $highlighted-&gt;value; ?&gt;'|highlight('php') }}</span></code></pre>\n<h2 id=\"preg-split\">preg_split</h2>\n<p>Divise une chaîne en un tableau à l'aide d'une expression régulière.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ string|preg_split(pattern, limit) }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> headers = page.content|preg_split('/&lt;br[^&gt;]*&gt;/') %}</span></code></pre>\n<h2 id=\"preg-match-all\">preg_match_all</h2>\n<p>Effectue une correspondance d'expression régulière et renvoie le groupe pour toutes les correspondances.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ string|preg_match_all(pattern, group) }}</span></code></pre>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> tags = page.content|preg_match_all('/&lt;[^&gt;]+&gt;(.*)&lt;\\/[^&gt;]+&gt;/') %}</span></code></pre>\n<h2 id=\"hex-to-rgb\">hex_to_rgb</h2>\n<p>Convertit une couleur hexadécimale en RVB.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ color|hex_to_rgb }}</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/templates/composants/",
      "url": "https://cecil-945.pages.dev/fr/documentation/templates/composants/",
      "title": "Composants",
      "summary": "Créez des composants de template réutilisables.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Composants\nCecil fournit une logique de composants pour vous donner le pouvoir de créer des \"unités\" de templates réutilisables.\nLa fonctionnalité des composants est fournie par l'extension de composants Twig créée par Giorgio Pogliani.\nSyntaxe des composants\nLes composants ne sont que des templates Twig stockés dans le sous-répertoire components\/ et peuvent être utilisés n'importe où dans vos templates :\n{# \/components\/button.twig #}\n&lt;button {{ attributes.merge({class: 'rounded px-4'}) }}&gt;\n    {{ slot }}\n&lt;\/button&gt;\n\nLa variable slot correspond à tout contenu que vous ajouterez entre la balise d'ouverture et la balise de fermeture.\n\nPour accéder à un composant vous devez utiliser la balise dédiée x suivie de : et du nom de fichier de votre composant sans extension :\n{# \/index.twig #}\n{% x:button with {class: 'text-white'} %}\n    &lt;strong&gt;Click me&lt;\/strong&gt;\n{% endx %}\nIl rendra :\n&lt;button class=\"text-white rounded px-4\"&gt;\n    &lt;strong&gt;Click me&lt;\/strong&gt;\n&lt;\/button&gt;",
      "content_html": "<h1>Composants</h1>\n<p>Cecil fournit une logique de composants pour vous donner le pouvoir de créer des \"unités\" de templates réutilisables.</p>\n<aside class=\"note note-info\"><p>La fonctionnalité des composants est fournie par l'<a href=\"https://github.com/giorgiopogliani/twig-components\" target=\"_blank\" rel=\"noopener noreferrer\"><em>extension de composants Twig</em></a> créée par Giorgio Pogliani.</p></aside>\n<h2 id=\"syntaxe-des-composants\">Syntaxe des composants</h2>\n<p>Les composants ne sont que des templates Twig stockés dans le sous-répertoire <code translate=\"no\">components/</code> et peuvent être utilisés n'importe où dans vos templates :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# /components/button.twig #}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button</span> </span></span><span class=\"hljs-template-variable\">{{ attributes.merge({class: 'rounded px-4'}) }}</span><span class=\"xml\"><span class=\"hljs-tag\">&gt;</span>\n    </span><span class=\"hljs-template-variable\">{{ slot }}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">button</span>&gt;</span></span></code></pre>\n<blockquote>\n<p>La variable slot correspond à tout contenu que vous ajouterez entre la balise d'ouverture et la balise de fermeture.</p>\n</blockquote>\n<p>Pour accéder à un composant vous devez utiliser la balise dédiée <code translate=\"no\">x</code> suivie de <code translate=\"no\">:</code> et du nom de fichier de votre composant sans extension :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# /index.twig #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">x</span>:button with {class: 'text-white'} %}</span><span class=\"xml\">\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong</span>&gt;</span>Click me<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">strong</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">endx</span> %}</span></code></pre>\n<p>Il rendra :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button</span> <span class=\"hljs-attr\">class</span>=<span class=\"hljs-string\">\"text-white rounded px-4\"</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong</span>&gt;</span>Click me<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">strong</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">button</span>&gt;</span></span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/templates/localisation/",
      "url": "https://cecil-945.pages.dev/fr/documentation/templates/localisation/",
      "title": "Localisation",
      "summary": "Traduisez les textes et localisez les dates dans les templates.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Localisation\nCecil prend en charge traduction du texte et localisation de la date.\nTraduction de texte\nUtilise le trans tag ou filter pour traduire des textes dans des templates.\n{% trans with variables into locale %}{% endtrans %}\n{{ message|trans(variables = []) }}\nExemples\n{% trans %}Hello World!{% endtrans %}\n{{ message|trans }}\nInclure des variables :\n{% trans with {'%name%': 'Arnaud'} %}Hello %name%!{% endtrans %}\n{{ message|trans({'%name%': 'Arnaud'}) }}\nForcer les paramètres régionaux :\n{% trans into 'fr_FR' %}Hello World!{% endtrans %}\nPluraliser :\n{% trans with {'%count%': 42}%}{0}I don't have apples|{1}I have one apple|]1,Inf[I have %count% apples{% endtrans %}\nFichiers de traduction\nLes fichiers de traduction doivent être nommés messages.&lt;locale&gt;.&lt;extension&gt; et stockés dans le répertoire translations.\nLes extensions prises en charge sont définies pour chaque format de traduction dans layouts.translations.formats.\nLe code locale (ex. : fr_FR) d'une langue est défini dans les entrées languages de la configuration.\nExemple:\n&lt;mywebsite&gt;\n└─ translations\n   ├─ messages.fr_FR.mo   &lt;- Machine Object format\n   └─ messages.fr_FR.yaml &lt;- Yaml format\nVous pouvez facilement extraire les traductions de vos templates avec la commande suivante :\nphp cecil.phar util:translations:extract --locale=&lt;code&gt; --show\nUtilisez --save à la place (ou en plus) de --show pour enregistrer les traductions dans un fichier. L'option --locale est obligatoire. Le format de sortie par défaut est yaml (utilisez --format=po pour le format gettext PO).\nPoedit est un éditeur de traduction simple et multiplateforme pour gettext (PO), et Poedit Pro prend en charge l'extraction de chaînes de traduction à partir de templates prêts à l'emploi.\nFaites attention au cache lorsque vous mettez à jour les fichiers de traduction.\nLe cache peut être vidé avec la commande suivante :\nphp cecil.phar cache:clear:translations`\nLocalisation de la date\nUtilise le filtre Twig format_date pour localiser une date dans les templates.\n{{ page.date|format_date('long') }}\n{# September 30, 2022 #}\nLes valeurs prises en charge sont : short, medium, long et full.\nSi vous souhaitez utiliser le filtre format_date avec des paramètres régionaux autres que \"en\", vous devez installer l'extension PHP internationale.",
      "content_html": "<h1>Localisation</h1>\n<p>Cecil prend en charge <a href=\"#traduction-de-texte\">traduction du texte</a> et <a href=\"#localisation-de-la-date\">localisation de la date</a>.</p>\n<h2 id=\"traduction-de-texte\">Traduction de texte</h2>\n<p>Utilise le <code translate=\"no\">trans</code> <em>tag</em> ou <em>filter</em> pour traduire des textes dans des templates.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">trans</span> with variables into locale %}</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">endtrans</span> %}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ message|trans(variables = []) }}</span></code></pre>\n<h3 id=\"exemples\">Exemples</h3>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">trans</span> %}</span><span class=\"xml\">Hello World!</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">endtrans</span> %}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ message|trans }}</span></code></pre>\n<p>Inclure des variables :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">trans</span> with {'%name%': 'Arnaud'} %}</span><span class=\"xml\">Hello %name%!</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">endtrans</span> %}</span></code></pre>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ message|trans({'%name%': 'Arnaud'}) }}</span></code></pre>\n<p>Forcer les paramètres régionaux :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">trans</span> into 'fr_FR' %}</span><span class=\"xml\">Hello World!</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">endtrans</span> %}</span></code></pre>\n<p>Pluraliser :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">trans</span> with {'%count%': 42}%}</span><span class=\"xml\">{0}I don't have apples|{1}I have one apple|]1,Inf[I have %count% apples</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">endtrans</span> %}</span></code></pre>\n<h2 id=\"fichiers-de-traduction\">Fichiers de traduction</h2>\n<p>Les fichiers de traduction doivent être nommés <code translate=\"no\">messages.&lt;locale&gt;.&lt;extension&gt;</code> et stockés dans le répertoire <a href=\"../configuration/7-layouts.fr.md\"><code translate=\"no\">translations</code></a>.\nLes extensions prises en charge sont définies pour chaque format de traduction dans <a href=\"../configuration/7-layouts.fr.md#layouts-translations\"><code translate=\"no\">layouts.translations.formats</code></a>.</p>\n<p>Le code locale (ex. : <code translate=\"no\">fr_FR</code>) d'une langue est défini dans les entrées <a href=\"../configuration/2-languages.fr.md#languages\"><code translate=\"no\">languages</code></a> de la configuration.</p>\n<p><em>Exemple:</em></p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">&lt;mywebsite&gt;\n└─ translations\n   ├─ messages.fr_FR.mo   &lt;- Machine Object format\n   └─ messages.fr_FR.yaml &lt;- Yaml format</code></pre>\n<aside class=\"note note-info\"><p>Vous pouvez facilement extraire les traductions de vos templates avec la commande suivante :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar util:translations:extract --locale=&lt;code&gt; --show</code></pre>\n<p>Utilisez <code translate=\"no\">--save</code> à la place (ou en plus) de <code translate=\"no\">--show</code> pour enregistrer les traductions dans un fichier. L'option <code translate=\"no\">--locale</code> est obligatoire. Le format de sortie par défaut est <code translate=\"no\">yaml</code> (utilisez <code translate=\"no\">--format=po</code> pour le format gettext PO).</p></aside>\n<aside class=\"note note-tip\"><p><a href=\"https://poedit.net\" target=\"_blank\" rel=\"noopener noreferrer\"><em>Poedit</em></a> est un éditeur de traduction simple et multiplateforme pour gettext (PO), et <a href=\"https://poedit.net/pro\" target=\"_blank\" rel=\"noopener noreferrer\"><em>Poedit Pro</em></a> prend en charge l'extraction de chaînes de traduction à partir de templates prêts à l'emploi.</p></aside>\n<aside class=\"note note-important\"><p>Faites attention au <a href=\"6-cache.fr.md\">cache</a> lorsque vous mettez à jour les fichiers de traduction.</p>\n<p>Le cache peut être vidé avec la commande suivante :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar cache:clear:translations`</code></pre></aside>\n<h2 id=\"localisation-de-la-date\">Localisation de la date</h2>\n<p>Utilise le filtre Twig <a href=\"https://twig.symfony.com/doc/3.x/filters/format_date.html\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">format_date</code></a> pour localiser une date dans les templates.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ page.<span class=\"hljs-name\">date</span>|format_date('long') }}</span><span class=\"xml\">\n</span><span class=\"hljs-comment\">{# September 30, 2022 #}</span></code></pre>\n<p>Les valeurs prises en charge sont : <code translate=\"no\">short</code>, <code translate=\"no\">medium</code>, <code translate=\"no\">long</code> et <code translate=\"no\">full</code>.</p>\n<aside class=\"note note-important\"><p>Si vous souhaitez utiliser le filtre <code translate=\"no\">format_date</code> <strong>avec des paramètres régionaux autres que \"en\"</strong>, vous devez <a href=\"https://php.net/intl.setup\" target=\"_blank\" rel=\"noopener noreferrer\">installer l'extension PHP internationale</a>.</p></aside>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/templates/cache/",
      "url": "https://cecil-945.pages.dev/fr/documentation/templates/cache/",
      "title": "Cache",
      "summary": "Cache des templates et cache de fragments.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Cache\nCecil utilise un système de cache pour accélérer le processus de génération, il peut être désactivé ou effacé.\nIl existe trois types de cache dans le cas du rendu des templates : les templates eux-mêmes, assets et translations.\nVider le cache\nVous pouvez vider le cache avec les commandes suivantes :\nphp cecil.phar cache:clear               # clear all caches\nphp cecil.phar cache:clear:assets        # clear assets cache\nphp cecil.phar cache:clear:templates     # clear templates cache\nphp cecil.phar cache:clear:translations  # clear translations cache\nEn pratique, vous n'avez pas besoin de vider le cache manuellement, Cecil le fait pour vous en cas de besoin (par exemple lorsque des fichiers changent).\nFragments de cache\nCecil fournit un moyen de mettre en cache des parties du rendu des templates pour éviter de restituer plusieurs fois le même contenu partiel.\nPour utiliser les fragments de cache, vous devez envelopper le contenu que vous souhaitez mettre en cache avec la balise cache.\n{% cache 'unique-key' %}\n  {# cacheable content #}\n{% endcache %}\nVous devez utiliser la fonction cache_key pour être sûr d'avoir une clé de cache unique pour chaque contenu que vous souhaitez mettre en cache.\nLes fragments de cache sont persistants, donc si la clé de cache est trop générique, vous risquez de vous retrouver avec un mauvais contenu affiché.\nPour vider uniquement le cache des fragments, vous pouvez utiliser la commande suivante :\nphp cecil.phar cache:clear:templates --fragments\nDésactiver le cache\nVous pouvez désactiver le cache avec la configuration.\nLa désactivation du cache peut ralentir le processus de génération, ce n'est donc pas recommandé.\nLors du développement local, si vous devez vider le cache avant chaque génération, vous pouvez utiliser l'option suivante :\nphp cecil.phar serve --clear-cache          # clear all caches\nphp cecil.phar serve --clear-cache=&lt;regex&gt;  # clear cache for cache key matches with the regular expression &lt;regex&gt;\nExemple:\nphp cecil.phar serve --clear-cache=css  # clear cache for all CSS files",
      "content_html": "<h1>Cache</h1>\n<p>Cecil utilise un système de cache pour accélérer le processus de génération, il peut être désactivé ou effacé.</p>\n<p>Il existe trois types de cache dans le cas du rendu des templates : les templates eux-mêmes, <a href=\"../assets/index.fr.md#asset\">assets</a> et <a href=\"5-localization.fr.md#fichiers-de-traduction\">translations</a>.</p>\n<h2 id=\"vider-le-cache\">Vider le cache</h2>\n<p>Vous pouvez vider le cache avec les commandes suivantes :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar cache:clear               <span class=\"hljs-comment\"># clear all caches</span>\nphp cecil.phar cache:clear:assets        <span class=\"hljs-comment\"># clear assets cache</span>\nphp cecil.phar cache:clear:templates     <span class=\"hljs-comment\"># clear templates cache</span>\nphp cecil.phar cache:clear:translations  <span class=\"hljs-comment\"># clear translations cache</span></code></pre>\n<aside class=\"note note-important\"><p>En pratique, vous n'avez pas besoin de vider le cache manuellement, Cecil le fait pour vous en cas de besoin (par exemple lorsque des fichiers changent).</p></aside>\n<h2 id=\"fragments-de-cache\">Fragments de cache</h2>\n<p>Cecil fournit un moyen de mettre en cache des parties du rendu des templates pour éviter de restituer plusieurs fois le même contenu partiel.</p>\n<p>Pour utiliser les <em>fragments</em> de cache, vous devez envelopper le contenu que vous souhaitez mettre en cache avec la balise <a href=\"https://twig.symfony.com/doc/tags/cache.html\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">cache</code></a>.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">cache</span> 'unique-key' %}</span><span class=\"xml\">\n  </span><span class=\"hljs-comment\">{# cacheable content #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">endcache</span> %}</span></code></pre>\n<aside class=\"note note-tip\"><p>Vous devez utiliser la fonction <a href=\"reference/1-functions.fr.md#cache-key\"><code translate=\"no\">cache_key</code></a> pour être sûr d'avoir une clé de cache unique pour chaque contenu que vous souhaitez mettre en cache.</p></aside>\n<aside class=\"note note-warning\"><p>Les <em>fragments</em> de cache sont persistants, donc si la clé de cache est trop générique, vous risquez de vous retrouver avec un mauvais contenu affiché.</p></aside>\n<p>Pour vider uniquement le cache des fragments, vous pouvez utiliser la commande suivante :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar cache:clear:templates --fragments</code></pre>\n<h2 id=\"desactiver-le-cache\">Désactiver le cache</h2>\n<p>Vous pouvez désactiver le cache avec la <a href=\"../configuration/9-cache.fr.md\">configuration</a>.</p>\n<aside class=\"note note-warning\"><p>La désactivation du cache peut ralentir le processus de génération, ce n'est donc pas recommandé.</p>\n<p>Lors du développement local, si vous devez vider le cache avant chaque génération, vous pouvez utiliser l'option suivante :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar serve --clear-cache          <span class=\"hljs-comment\"># clear all caches</span>\nphp cecil.phar serve --clear-cache=&lt;regex&gt;  <span class=\"hljs-comment\"># clear cache for cache key matches with the regular expression &lt;regex&gt;</span></code></pre>\n<p>Exemple:</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar serve --clear-cache=css  <span class=\"hljs-comment\"># clear cache for all CSS files</span></code></pre></aside>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/templates/etendre/",
      "url": "https://cecil-945.pages.dev/fr/documentation/templates/etendre/",
      "title": "Étendre",
      "summary": "Ajoutez des fonctions et filtres personnalisés, ou utilisez un thème.",
      "date_published": "2026-05-26T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Étendre\nLes templates peuvent être étendus avec des fonctions et filtres personnalisés, ou regroupés dans un thème réutilisable.\nFonctions et filtres\nVous pouvez ajouter des fonctions et des filtres personnalisés avec une extension Twig.\nThème\nC'est simple de construire un thème, il suffit de créer un dossier &lt;theme&gt; avec la structure suivante (comme un site web mais sans pages) :\n&lt;mywebsite&gt;\n└─ themes\n   └─ &lt;theme&gt;\n      ├─ config.yml\n      ├─ assets\n      ├─ layouts\n      ├─ static\n      └─ translations",
      "content_html": "<h1>Étendre</h1>\n<p>Les templates peuvent être étendus avec des fonctions et filtres personnalisés, ou regroupés dans un thème réutilisable.</p>\n<h2 id=\"fonctions-et-filtres\">Fonctions et filtres</h2>\n<p>Vous pouvez ajouter des <a href=\"reference/1-functions.fr.md\">fonctions</a> et des <a href=\"reference/3-filters.fr.md\">filtres</a> personnalisés avec une <a href=\"../developers/1-extend.fr.md#extension-twig\"><strong><em>extension Twig</em></strong></a>.</p>\n<h2 id=\"theme\">Thème</h2>\n<p>C'est simple de construire un thème, il suffit de créer un dossier <code translate=\"no\">&lt;theme&gt;</code> avec la structure suivante (comme un site web mais sans pages) :</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">&lt;mywebsite&gt;\n└─ themes\n   └─ &lt;theme&gt;\n      ├─ config.yml\n      ├─ assets\n      ├─ layouts\n      ├─ static\n      └─ translations</code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/commandes/new-site/",
      "url": "https://cecil-945.pages.dev/fr/documentation/commandes/new-site/",
      "title": "new:site",
      "summary": "Créer un nouveau site.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "new:site\nCrée un nouveau site.\nUtilisation\nDescription:\n  Creates a new website\n\nUsage:\n  new:site [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                  Use the given path as working directory\n\nOptions:\n  -f, --force           Override directory if it already exists\n      --demo            Add demo content (pages, templates and assets)\n  -h, --help            Display help for the given command. When no command is given display help for the list command\n  -q, --quiet           Do not output any message\n  -V, --version         Display this application version\n      --ansi|--no-ansi  Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction  Do not ask any interactive question\n  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The new:site command creates a new website in the current directory, or in &lt;path&gt; if provided.\n  If you run this command without any options, it will ask you for the website title, baseline, base URL, description, etc.\n\n    cecil.phar new:site\n    cecil.phar new:site path\/to\/the\/working\/directory\n\n  To create a new website with demo content, run:\n\n    cecil.phar new:site --demo\n\n  To override an existing website, run:\n\n    cecil.phar new:site --force",
      "content_html": "<h1>new:site</h1>\n<p>Crée un nouveau site.</p>\n<h2 id=\"utilisation\">Utilisation</h2>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Creates a new website\n\nUsage:\n  new:site [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                  Use the given path as working directory\n\nOptions:\n  -f, --force           Override directory if it already exists\n      --demo            Add demo content (pages, templates and assets)\n  -h, --help            Display help for the given command. When no command is given display help for the list command\n  -q, --quiet           Do not output any message\n  -V, --version         Display this application version\n      --ansi|--no-ansi  Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction  Do not ask any interactive question\n  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The new:site command creates a new website in the current directory, or in &lt;path&gt; if provided.\n  If you run this command without any options, it will ask you for the website title, baseline, base URL, description, etc.\n\n    cecil.phar new:site\n    cecil.phar new:site path/to/the/working/directory\n\n  To create a new website with demo content, run:\n\n    cecil.phar new:site --demo\n\n  To override an existing website, run:\n\n    cecil.phar new:site --force</code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/site/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/site/",
      "title": "Options du site",
      "summary": "title, baseurl, menus, taxonomies, theme, date, metatags, debug, etc.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Options du site\nCes options définissent les réglages principaux du site : titre, URL, description, menus, taxonomies, thème, métadonnées, etc.\ntitle\nTitre principal du site.\ntitle: \"&lt;site title&gt;\"\nbaseline\nDescription courte (~ 20 caractères).\nbaseline: \"&lt;baseline&gt;\"\nbaseurl\nURL de base.\nbaseurl: &lt;url&gt;\nExemple :\nbaseurl: http:\/\/localhost:8000\/\nbaseurl doit se terminer par un slash final (\/).\ncanonicalurl\nSi la valeur est true, la fonction url() renverra l’URL absolue (false par défaut).\ncanonicalurl: &lt;true|false&gt; # false by default\ndescription\nDescription du site (~ 250 caractères).\ndescription: \"&lt;description&gt;\"\nmenus\nLes menus sont utilisés pour créer des liens de navigation dans les templates.\nUn menu est composé d’un identifiant unique et des propriétés des entrées (nom, URL, poids).\nmenus:\n  &lt;name&gt;:\n    - id: &lt;unique-id&gt;   # unique identifier (required)\n      name: \"&lt;name&gt;\"    # name displayed in templates\n      url: &lt;url&gt;        # relative or absolute URL\n      weight: &lt;integer&gt; # integer value used to sort entries (lighter first)\nExemple :\nmenus:\n  main:\n    - id: about\n      name: \"About\"\n      url: \/about\/\n      weight: 1\n  footer:\n    - id: author\n      name: The author\n      url: https:\/\/arnaudligny.fr\n      weight: 99\nUn menu main est créé automatiquement avec l’entrée de la page d’accueil et toutes les entrées de sections (Voir la gestion du contenu).\nUne page peut être ajoutée à un menu en définissant la variable menu dans son front matter.\nSurcharger une entrée\nUne entrée de menu de page peut être surchargée : utilisez l’ID de la page comme id.\nExemple :\nmenus:\n  main:\n    - id: index\n      name: \"My amazing homepage!\"\n      weight: 1\nDésactiver une entrée\nUne entrée de menu peut être désactivée avec enabled: false.\nExemple :\nmenus:\n  main:\n    - id: about\n      enabled: false\ntaxonomies\nListe des vocabulaires, associant une valeur au pluriel à une valeur au singulier.\ntaxonomies:\n  &lt;plural&gt;: &lt;singular&gt;\nExemple :\ntaxonomies:\n  categories: category\n  tags: tag\nVous pouvez ensuite utiliser ces vocabulaires dans le front matter de votre contenu.\nDepuis la version 8.37.0, les vocabulaires par défaut category et tag ont été supprimés. Vous devez les définir dans le fichier de configuration si vous souhaitez les utiliser.\nUn vocabulaire peut être désactivé avec la valeur spéciale disabled. Exemple : tags: disabled.\ntheme\nThème à utiliser, ou liste de thèmes.\ntheme: &lt;theme&gt; # theme name\n# or\ntheme:\n  - &lt;theme1&gt; # theme name\n  - &lt;theme2&gt;\nLe premier thème surcharge les suivants, et ainsi de suite.\nExemples :\ntheme: hyde\ntheme:\n  - serviceworker\n  - hyde\nVoir les thèmes sur GitHub ou la section thèmes du site.\ndate\nFormat de date et fuseau horaire.\ndate:\n  format: &lt;format&gt;     # date format (optional, `F j, Y` by default)\n  timezone: &lt;timezone&gt; # date timezone (optional, local time zone by default)\n\nformat : spécificateur de format de date PHP\ntimezone : voir les fuseaux horaires\n\nExemple :\ndate:\n  format: 'j F, Y'\n  timezone: 'Europe\/Paris'\nmetatags\nLes metatags sont des aides SEO et réseaux sociaux qui peuvent être injectées automatiquement dans le &lt;head&gt;, via le template partials\/metatags.html.twig.\nCe template ajoute les balises meta suivantes :\n\nTitre de page + titre du site, ou titre du site + baseline du site\nDescription de la page\/du site\nMots-clés de la page\/du site\nAuteur de la page\/du site\nDirectives des robots des moteurs de recherche (robots)\nLiens de favicon\nLiens de navigation (premier, précédent, suivant, dernier)\nURL canonique\nLiens alternatifs (ex. : flux RSS, autres langues)\nLiens rel=me\nOpen Graph\nIdentifiant de profil Facebook\nTwitter\/X Card\nFediverse tag\nDublin Core\nStructured data (JSON-LD)\n\noptions metatags\nCecil utilise le front matter de la page pour alimenter les meta tags, avec repli sur les options du site si nécessaire.\ntitle: \"Page\/Site title\"              # used by title meta\ndescription: \"Page\/Site description\"  # used by description meta\ntags: [tag1, tag2]                    # used by keywords meta\nkeywords: [keyword1, keyword2]        # obsolete\nauthor:                               # used by author meta\n  name: &lt;name&gt;                          # author name\n  url: &lt;url&gt;                            # author URL\n  email: &lt;email&gt;                        # author email\nimage: image.jpg                      # used by Open Graph and social networks cards\ncanonical:                            # used to override the generated canonical URL\n  url: &lt;URL&gt;                            # absolute URL\n  title: \"&lt;URL title&gt;\"                  # optional canonical title\nsocial:                               # used by social networks meta\n  twitter:                              # used by Twitter\/X Card\n    url: &lt;URL&gt;                            # used for `rel=me` link\n    site: username                        # site username\n    creator: username                     # page author username\n  mastodon:                             # used by Mastodon meta\n    url: &lt;URL&gt;                            # used for `rel=me` link\n    creator: handle                       # page author account\n  facebook:                             # used by Facebook meta\n    url: &lt;URL&gt;                            # used for `rel=me` link\n    id: 123456789                         # Facebook profile ID\n    username: username                    # page author username\nSi besoin, title et image peuvent être surchargés :\n{{ include('partials\/metatags.html.twig', {title: 'Custom title', image: og_image}) }}\nconfiguration metatags\nmetatags:\n  title:                   # title options\n    divider: \" &amp;middot; \"    # string between page title and site title\n    only: false              # displays page title only (`false` by default)\n    pagination:              # pagination options\n      shownumber: true         # displays page number in title (`true` by default)\n      label: \"Page %s\"         # how to display page number (`Page %s` by default)\n  robots: \"index,follow\"   # web crawlers directives (`index,follow` by default)\n  favicon:                 # favicon options\n    enabled: true            # includes favicon (`true` by default)\n    image: favicon.png       # path to favicon image\n    sizes:                   # sizes by device\n      - \"icon\": [32, 57, 76, 96, 128, 192, 228]  # web browsers\n      - \"shortcut icon\": [196]                   # Android\n      - \"apple-touch-icon\": [120, 152, 180]      # iOS\n  navigation: true         # includes previous and next links (`true` by default)\n  image: true              # includes image (`true` by default)\n  og: true                 # includes Open Graph meta tags (`true` by default)\n  articles: \"blog\"         # articles' section (`blog` by default)\n  twitter: true            # includes Twitter\/X Card meta tags (`true` by default)\n  mastodon: true           # includes Mastodon meta tags (`true` by default)\n  dc: false                # includes Dublin Core meta tags (`false` by default)\n  data: false              # includes JSON-LD structured data (`false` by default)\ndebug\nActive le mode debug, utilisé pour afficher des informations de débogage comme des journaux très verbeux, le dump Twig, le profileur Twig, le sourcemap SCSS, etc.\ndebug: true\nIl existe deux autres façons d’activer le mode debug :\n\nExécuter une commande avec l’option -vvv\nDéfinir la variable d’environnement CECIL_DEBUG à true\n\n",
      "content_html": "<h1>Options du site</h1>\n<p>Ces options définissent les réglages principaux du site : titre, URL, description, menus, taxonomies, thème, métadonnées, etc.</p>\n<h2 id=\"title\">title</h2>\n<p>Titre principal du site.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">\"&lt;site title&gt;\"</span></code></pre>\n<h2 id=\"baseline\">baseline</h2>\n<p>Description courte (~ 20 caractères).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">baseline:</span> <span class=\"hljs-string\">\"&lt;baseline&gt;\"</span></code></pre>\n<h2 id=\"baseurl\">baseurl</h2>\n<p>URL de base.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">baseurl:</span> <span class=\"hljs-string\">&lt;url&gt;</span></code></pre>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">baseurl:</span> <span class=\"hljs-string\">http://localhost:8000/</span></code></pre>\n<aside class=\"note note-important\"><p><code translate=\"no\">baseurl</code> doit se terminer par un slash final (<code translate=\"no\">/</code>).</p></aside>\n<h2 id=\"canonicalurl\">canonicalurl</h2>\n<p>Si la valeur est <code translate=\"no\">true</code>, la fonction <a href=\"../templates/reference/1-functions.fr.md#url\"><code translate=\"no\">url()</code></a> renverra l’URL absolue (<code translate=\"no\">false</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">canonicalurl:</span> <span class=\"hljs-string\">&lt;true|false&gt;</span> <span class=\"hljs-comment\"># false by default</span></code></pre>\n<h2 id=\"description\">description</h2>\n<p>Description du site (~ 250 caractères).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">description:</span> <span class=\"hljs-string\">\"&lt;description&gt;\"</span></code></pre>\n<h2 id=\"menus\">menus</h2>\n<p>Les menus sont utilisés pour créer des <a href=\"../templates/2-variables.fr.md#site-menus\">liens de navigation dans les templates</a>.</p>\n<p>Un menu est composé d’un identifiant unique et des propriétés des entrées (nom, URL, poids).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">menus:</span>\n  <span class=\"hljs-string\">&lt;name&gt;:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">id:</span> <span class=\"hljs-string\">&lt;unique-id&gt;</span>   <span class=\"hljs-comment\"># unique identifier (required)</span>\n      <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">\"&lt;name&gt;\"</span>    <span class=\"hljs-comment\"># name displayed in templates</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">&lt;url&gt;</span>        <span class=\"hljs-comment\"># relative or absolute URL</span>\n      <span class=\"hljs-attr\">weight:</span> <span class=\"hljs-string\">&lt;integer&gt;</span> <span class=\"hljs-comment\"># integer value used to sort entries (lighter first)</span></code></pre>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">menus:</span>\n  <span class=\"hljs-attr\">main:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">id:</span> <span class=\"hljs-string\">about</span>\n      <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">\"About\"</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">/about/</span>\n      <span class=\"hljs-attr\">weight:</span> <span class=\"hljs-number\">1</span>\n  <span class=\"hljs-attr\">footer:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">id:</span> <span class=\"hljs-string\">author</span>\n      <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">The</span> <span class=\"hljs-string\">author</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">https://arnaudligny.fr</span>\n      <span class=\"hljs-attr\">weight:</span> <span class=\"hljs-number\">99</span></code></pre>\n<aside class=\"note note-info\"><p>Un menu <code translate=\"no\">main</code> est créé automatiquement avec l’entrée de la page d’accueil et toutes les entrées de sections (<a href=\"../content/index.fr.md\">Voir la gestion du contenu</a>).</p></aside>\n<aside class=\"note note-tip\"><p>Une page peut être ajoutée à un menu en définissant la variable <a href=\"../content/2-front-matter.fr.md#menu\"><code translate=\"no\">menu</code></a> dans son front matter.</p></aside>\n<h3 id=\"surcharger-une-entree\">Surcharger une entrée</h3>\n<p>Une entrée de menu de page peut être surchargée : utilisez l’ID de la page comme <code translate=\"no\">id</code>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">menus:</span>\n  <span class=\"hljs-attr\">main:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">id:</span> <span class=\"hljs-string\">index</span>\n      <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">\"My amazing homepage!\"</span>\n      <span class=\"hljs-attr\">weight:</span> <span class=\"hljs-number\">1</span></code></pre>\n<h3 id=\"desactiver-une-entree\">Désactiver une entrée</h3>\n<p>Une entrée de menu peut être désactivée avec <code translate=\"no\">enabled: false</code>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">menus:</span>\n  <span class=\"hljs-attr\">main:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">id:</span> <span class=\"hljs-string\">about</span>\n      <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">false</span></code></pre>\n<h2 id=\"taxonomies\">taxonomies</h2>\n<p>Liste des vocabulaires, associant une valeur au pluriel à une valeur au singulier.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">taxonomies:</span>\n  <span class=\"hljs-string\">&lt;plural&gt;:</span> <span class=\"hljs-string\">&lt;singular&gt;</span></code></pre>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">taxonomies:</span>\n  <span class=\"hljs-attr\">categories:</span> <span class=\"hljs-string\">category</span>\n  <span class=\"hljs-attr\">tags:</span> <span class=\"hljs-string\">tag</span></code></pre>\n<p>Vous pouvez ensuite utiliser ces vocabulaires dans le <a href=\"../content/2-front-matter.fr.md#taxonomie\">front matter</a> de votre contenu.</p>\n<aside class=\"note note-warning\"><p>Depuis la <ins>version 8.37.0</ins>, les vocabulaires par défaut <code translate=\"no\">category</code> et <code translate=\"no\">tag</code> ont été supprimés. Vous devez les définir dans le fichier de configuration si vous souhaitez les utiliser.</p></aside>\n<aside class=\"note note-tip\"><p>Un vocabulaire peut être désactivé avec la valeur spéciale <code translate=\"no\">disabled</code>. Exemple : <code translate=\"no\">tags: disabled</code>.</p></aside>\n<h2 id=\"theme\">theme</h2>\n<p>Thème à utiliser, ou liste de thèmes.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">theme:</span> <span class=\"hljs-string\">&lt;theme&gt;</span> <span class=\"hljs-comment\"># theme name</span>\n<span class=\"hljs-comment\"># or</span>\n<span class=\"hljs-attr\">theme:</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">&lt;theme1&gt;</span> <span class=\"hljs-comment\"># theme name</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">&lt;theme2&gt;</span></code></pre>\n<aside class=\"note note-info\"><p>Le premier thème surcharge les suivants, et ainsi de suite.</p></aside>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">theme:</span> <span class=\"hljs-string\">hyde</span></code></pre>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">theme:</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">serviceworker</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">hyde</span></code></pre>\n<aside class=\"note note-info\"><p>Voir les <a href=\"https://github.com/Cecilapp?q=theme#org-repositories\" target=\"_blank\" rel=\"noopener noreferrer\">thèmes sur GitHub</a> ou la <a href=\"https://cecil.app/themes/\" target=\"_blank\" rel=\"noopener noreferrer\">section thèmes</a> du site.</p></aside>\n<h2 id=\"date\">date</h2>\n<p>Format de date et fuseau horaire.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">date:</span>\n  <span class=\"hljs-attr\">format:</span> <span class=\"hljs-string\">&lt;format&gt;</span>     <span class=\"hljs-comment\"># date format (optional, `F j, Y` by default)</span>\n  <span class=\"hljs-attr\">timezone:</span> <span class=\"hljs-string\">&lt;timezone&gt;</span> <span class=\"hljs-comment\"># date timezone (optional, local time zone by default)</span></code></pre>\n<ul>\n<li><code translate=\"no\">format</code> : spécificateur de format de <a href=\"https://php.net/date\" target=\"_blank\" rel=\"noopener noreferrer\">date PHP</a></li>\n<li><code translate=\"no\">timezone</code> : voir les <a href=\"https://php.net/timezones\" target=\"_blank\" rel=\"noopener noreferrer\">fuseaux horaires</a></li>\n</ul>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">date:</span>\n  <span class=\"hljs-attr\">format:</span> <span class=\"hljs-string\">'j F, Y'</span>\n  <span class=\"hljs-attr\">timezone:</span> <span class=\"hljs-string\">'Europe/Paris'</span></code></pre>\n<h2 id=\"metatags\">metatags</h2>\n<p>Les <em>metatags</em> sont des aides SEO et réseaux sociaux qui peuvent être injectées automatiquement dans le <code translate=\"no\">&lt;head&gt;</code>, via le template <a href=\"https://github.com/Cecilapp/Cecil/blob/main/resources/layouts/partials/metatags.html.twig\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">partials/metatags.html.twig</code></a>.</p>\n<p>Ce template ajoute les balises meta suivantes :</p>\n<ul>\n<li>Titre de page + titre du site, ou titre du site + baseline du site</li>\n<li>Description de la page/du site</li>\n<li>Mots-clés de la page/du site</li>\n<li>Auteur de la page/du site</li>\n<li>Directives des robots des moteurs de recherche (<em>robots</em>)</li>\n<li>Liens de favicon</li>\n<li>Liens de navigation (premier, précédent, suivant, dernier)</li>\n<li>URL canonique</li>\n<li>Liens alternatifs (ex. : flux RSS, autres langues)</li>\n<li>Liens <a href=\"https://developer.mozilla.org/docs/Web/HTML/Reference/Attributes/rel/me\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">rel=me</code></a></li>\n<li><a href=\"https://ogp.me\" target=\"_blank\" rel=\"noopener noreferrer\">Open Graph</a></li>\n<li>Identifiant de profil Facebook</li>\n<li><a href=\"https://developer.x.com/docs/x-for-websites/cards/guides/getting-started\" target=\"_blank\" rel=\"noopener noreferrer\">Twitter/X Card</a></li>\n<li><a href=\"https://blog.joinmastodon.org/2024/07/highlighting-journalism-on-mastodon/\" target=\"_blank\" rel=\"noopener noreferrer\">Fediverse tag</a></li>\n<li><a href=\"https://www.dublincore.org/specifications/dublin-core/dcmi-terms/\" target=\"_blank\" rel=\"noopener noreferrer\">Dublin Core</a></li>\n<li><a href=\"https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data\" target=\"_blank\" rel=\"noopener noreferrer\">Structured data</a> (JSON-LD)</li>\n</ul>\n<h3 id=\"options-metatags\">options metatags</h3>\n<p>Cecil utilise le front matter de la page pour alimenter les meta tags, avec repli sur les options du site si nécessaire.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">\"Page/Site title\"</span>              <span class=\"hljs-comment\"># used by title meta</span>\n<span class=\"hljs-attr\">description:</span> <span class=\"hljs-string\">\"Page/Site description\"</span>  <span class=\"hljs-comment\"># used by description meta</span>\n<span class=\"hljs-attr\">tags:</span> <span class=\"hljs-string\">[tag1,</span> <span class=\"hljs-string\">tag2]</span>                    <span class=\"hljs-comment\"># used by keywords meta</span>\n<span class=\"hljs-attr\">keywords:</span> <span class=\"hljs-string\">[keyword1,</span> <span class=\"hljs-string\">keyword2]</span>        <span class=\"hljs-comment\"># obsolete</span>\n<span class=\"hljs-attr\">author:</span>                               <span class=\"hljs-comment\"># used by author meta</span>\n  <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">&lt;name&gt;</span>                          <span class=\"hljs-comment\"># author name</span>\n  <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">&lt;url&gt;</span>                            <span class=\"hljs-comment\"># author URL</span>\n  <span class=\"hljs-attr\">email:</span> <span class=\"hljs-string\">&lt;email&gt;</span>                        <span class=\"hljs-comment\"># author email</span>\n<span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">image.jpg</span>                      <span class=\"hljs-comment\"># used by Open Graph and social networks cards</span>\n<span class=\"hljs-attr\">canonical:</span>                            <span class=\"hljs-comment\"># used to override the generated canonical URL</span>\n  <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">&lt;URL&gt;</span>                            <span class=\"hljs-comment\"># absolute URL</span>\n  <span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">\"&lt;URL title&gt;\"</span>                  <span class=\"hljs-comment\"># optional canonical title</span>\n<span class=\"hljs-attr\">social:</span>                               <span class=\"hljs-comment\"># used by social networks meta</span>\n  <span class=\"hljs-attr\">twitter:</span>                              <span class=\"hljs-comment\"># used by Twitter/X Card</span>\n    <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">&lt;URL&gt;</span>                            <span class=\"hljs-comment\"># used for `rel=me` link</span>\n    <span class=\"hljs-attr\">site:</span> <span class=\"hljs-string\">username</span>                        <span class=\"hljs-comment\"># site username</span>\n    <span class=\"hljs-attr\">creator:</span> <span class=\"hljs-string\">username</span>                     <span class=\"hljs-comment\"># page author username</span>\n  <span class=\"hljs-attr\">mastodon:</span>                             <span class=\"hljs-comment\"># used by Mastodon meta</span>\n    <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">&lt;URL&gt;</span>                            <span class=\"hljs-comment\"># used for `rel=me` link</span>\n    <span class=\"hljs-attr\">creator:</span> <span class=\"hljs-string\">handle</span>                       <span class=\"hljs-comment\"># page author account</span>\n  <span class=\"hljs-attr\">facebook:</span>                             <span class=\"hljs-comment\"># used by Facebook meta</span>\n    <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">&lt;URL&gt;</span>                            <span class=\"hljs-comment\"># used for `rel=me` link</span>\n    <span class=\"hljs-attr\">id:</span> <span class=\"hljs-number\">123456789</span>                         <span class=\"hljs-comment\"># Facebook profile ID</span>\n    <span class=\"hljs-attr\">username:</span> <span class=\"hljs-string\">username</span>                    <span class=\"hljs-comment\"># page author username</span></code></pre>\n<aside class=\"note note-tip\"><p>Si besoin, <code translate=\"no\">title</code> et <code translate=\"no\">image</code> peuvent être surchargés :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ <span class=\"hljs-name\">include</span><span class=\"hljs-params\">('partials/metatags.html.twig', {title: 'Custom title', image: og_image})</span> }}</span></code></pre></aside>\n<h3 id=\"configuration-metatags\">configuration metatags</h3>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">metatags:</span>\n  <span class=\"hljs-attr\">title:</span>                   <span class=\"hljs-comment\"># title options</span>\n    <span class=\"hljs-attr\">divider:</span> <span class=\"hljs-string\">\" &amp;middot; \"</span>    <span class=\"hljs-comment\"># string between page title and site title</span>\n    <span class=\"hljs-attr\">only:</span> <span class=\"hljs-literal\">false</span>              <span class=\"hljs-comment\"># displays page title only (`false` by default)</span>\n    <span class=\"hljs-attr\">pagination:</span>              <span class=\"hljs-comment\"># pagination options</span>\n      <span class=\"hljs-attr\">shownumber:</span> <span class=\"hljs-literal\">true</span>         <span class=\"hljs-comment\"># displays page number in title (`true` by default)</span>\n      <span class=\"hljs-attr\">label:</span> <span class=\"hljs-string\">\"Page %s\"</span>         <span class=\"hljs-comment\"># how to display page number (`Page %s` by default)</span>\n  <span class=\"hljs-attr\">robots:</span> <span class=\"hljs-string\">\"index,follow\"</span>   <span class=\"hljs-comment\"># web crawlers directives (`index,follow` by default)</span>\n  <span class=\"hljs-attr\">favicon:</span>                 <span class=\"hljs-comment\"># favicon options</span>\n    <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>            <span class=\"hljs-comment\"># includes favicon (`true` by default)</span>\n    <span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">favicon.png</span>       <span class=\"hljs-comment\"># path to favicon image</span>\n    <span class=\"hljs-attr\">sizes:</span>                   <span class=\"hljs-comment\"># sizes by device</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">\"icon\":</span> <span class=\"hljs-string\">[32,</span> <span class=\"hljs-number\">57</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">76</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">96</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">128</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">192</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">228</span><span class=\"hljs-string\">]</span>  <span class=\"hljs-comment\"># web browsers</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">\"shortcut icon\":</span> <span class=\"hljs-string\">[196]</span>                   <span class=\"hljs-comment\"># Android</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">\"apple-touch-icon\":</span> <span class=\"hljs-string\">[120,</span> <span class=\"hljs-number\">152</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">180</span><span class=\"hljs-string\">]</span>      <span class=\"hljs-comment\"># iOS</span>\n  <span class=\"hljs-attr\">navigation:</span> <span class=\"hljs-literal\">true</span>         <span class=\"hljs-comment\"># includes previous and next links (`true` by default)</span>\n  <span class=\"hljs-attr\">image:</span> <span class=\"hljs-literal\">true</span>              <span class=\"hljs-comment\"># includes image (`true` by default)</span>\n  <span class=\"hljs-attr\">og:</span> <span class=\"hljs-literal\">true</span>                 <span class=\"hljs-comment\"># includes Open Graph meta tags (`true` by default)</span>\n  <span class=\"hljs-attr\">articles:</span> <span class=\"hljs-string\">\"blog\"</span>         <span class=\"hljs-comment\"># articles' section (`blog` by default)</span>\n  <span class=\"hljs-attr\">twitter:</span> <span class=\"hljs-literal\">true</span>            <span class=\"hljs-comment\"># includes Twitter/X Card meta tags (`true` by default)</span>\n  <span class=\"hljs-attr\">mastodon:</span> <span class=\"hljs-literal\">true</span>           <span class=\"hljs-comment\"># includes Mastodon meta tags (`true` by default)</span>\n  <span class=\"hljs-attr\">dc:</span> <span class=\"hljs-literal\">false</span>                <span class=\"hljs-comment\"># includes Dublin Core meta tags (`false` by default)</span>\n  <span class=\"hljs-attr\">data:</span> <span class=\"hljs-literal\">false</span>              <span class=\"hljs-comment\"># includes JSON-LD structured data (`false` by default)</span></code></pre>\n<h2 id=\"debug\">debug</h2>\n<p>Active le <em>mode debug</em>, utilisé pour afficher des informations de débogage comme des journaux très verbeux, le dump Twig, le profileur Twig, le sourcemap SCSS, etc.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">debug:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<p>Il existe deux autres façons d’activer le <em>mode debug</em> :</p>\n<ol>\n<li>Exécuter une commande avec l’option <code translate=\"no\">-vvv</code></li>\n<li>Définir la variable d’environnement <code translate=\"no\">CECIL_DEBUG</code> à <code translate=\"no\">true</code></li>\n</ol>\n<hr>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/contenu/pages/",
      "url": "https://cecil-945.pages.dev/fr/documentation/contenu/pages/",
      "title": "Pages et sections",
      "summary": "Anatomie d’une page, préfixe de fichier, sections, sous-sections et page d’accueil.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-06T00:00:00+00:00","content_text": "Pages et sections\nUne page est un fichier composé d’un front matter et d’un body.\nFront matter\nLe front matter est une collection de variables (au format clé\/valeur) entourée par ---.\nExemple :\n---\ntitle: \"The title\"\ndate: 2019-02-21\ntags: [tag 1, tag 2]\ncustomvar: \"Value of customvar\"\n---\nVous pouvez aussi utiliser &lt;!-- --&gt; ou +++ comme séparateur.\nCorps (body)\nLe body est le contenu principal d’une page ; il peut être écrit en Markdown ou en texte brut.\nExemple :\n# Header\n\n[toc]\n\n## Sub-Header 1\n\nLorem ipsum dolor [sit amet](https:\/\/example.com), consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n&lt;!-- excerpt --&gt;\nUt enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n\n## Sub-Header 2\n\n![Description](\/image.jpg \"Title\")\n\n## Sub-Header 3\n\n:::tip\nThis is advice.\n:::\nPréfixe de fichier\nLe nom de fichier peut contenir un préfixe pour définir les variables date ou weight de la page (utilisé par sortby).\nSéparateurs de préfixe par défaut : _ et -.\nVous pouvez les personnaliser avec l’option pages.prefix.separator.\ndate\nLe date prefix est utilisé pour définir la date de la page et doit être un format de date valide (c.-à-d. : « YYYY-MM-DD »).\nExemple :\nDans « 2019-04-23_My blog post.md » :\n\nle préfixe est « 2019-04-23 »\nla date de la page est « 2019-04-23 »\nle title de la page est « My blog post »\n\nweight\nLe weight prefix est utilisé pour définir l’ordre de tri de la page et doit être une valeur entière valide.\nExemple :\nDans « 1_The first project.md » :\n\nle préfixe est « 1 »\nle weight de la page est « 1 »\nle title de la page est « The first project »\n\nSection\nCertaines variables dédiées peuvent être utilisées dans une Section personnalisée (c.-à-d. : &lt;section&gt;\/index.md).\nsortby\nL’ordre des pages dans une Section peut être modifié.\nValeurs disponibles :\n\ndate: plus récentes en premier\ntitle: ordre alphabétique\nweight: plus léger en premier\n\nExemple :\n---\nsortby: title\n---\nMore options:\n---\nsortby:\n  variable: date    # \"date\", \"updated\", \"title\" or \"weight\"\n  desc_title: false # used with \"date\" or \"updated\" variable value to sort by desc title order if items have the same date\n  reverse: false    # reversed if true\n---\npagination\nLa configuration globale de pagination est utilisée par défaut, mais vous pouvez la modifier pour une Section donnée.\nExemple :\n---\npagination:\n  max: 5\n  path: \"page\"\n---\nLa pagination peut être désactivée pour une Section :\n---\npagination: false\n---\ncascade\nToutes les variables de cascade sont ajoutées au front matter de toutes les sous-pages.\nExemple :\n---\ncascade:\n  banner: image.jpg\n---\nLes variables existantes ne sont pas écrasées.\ncircular\nDéfinissez circular à true pour activer la navigation circulaire avec page.&lt;prev\/next&gt;.\nAvec des sous-sections, seule la valeur circular de la Section de premier niveau est utilisée.\nExemple :\n---\ncircular: true\n---\nSous-section\nUn dossier imbriqué qui contient explicitement un fichier index.md devient une sous-section de sa Section parente.\n&lt;monsiteweb&gt;\n└─ pages\n   └─ blog                 &lt;- Section\n      ├─ index.md\n      ├─ post-1.md         &lt;- Page de la Section « blog »\n      └─ 2024              &lt;- Sous-section (contient un « index.md »)\n         ├─ index.md\n         └─ post-2.md      &lt;- Page de la Section « blog » *et* de la sous-section « blog\/2024 »\nUne sous-section :\n\nest une Section (même type, mêmes variables et même résolution de gabarit) accessible à sa propre URL (ex. : \/blog\/2024\/)\nest rendue avec les gabarits de ses Sections parentes si elle n'a pas les siens (ex. : blog\/list.html.twig)\npeut être imbriquée à n'importe quelle profondeur (ex. : blog\/2024\/06\/)\nliste ses propres pages, et ses pages appartiennent aussi à chacune de leurs Sections parentes\nn'est pas listée dans sa Section parente\nest placée dans la navigation page.&lt;prev\/next&gt; de sa Section parente (selon son sortby), suivie de ses propres pages\n\nUn dossier imbriqué sans fichier index.md n'est pas une sous-section : ses pages appartiennent simplement à la Section parente.\nPage d'accueil\nComme une autre section, la Page d'accueil prend en charge la configuration sortby et pagination.\npagesfrom\nDéfinissez un nom de Section valide dans pagesfrom pour utiliser la collection de pages de cette Section dans la Page d'accueil.\nExemple :\n---\npagesfrom: blog\n---",
      "content_html": "<h1>Pages et sections</h1>\n<p>Une page est un fichier composé d’un <a href=\"#front-matter\"><strong>front matter</strong></a> et d’un <a href=\"#corps-body\"><strong>body</strong></a>.</p>\n<h2 id=\"front-matter\">Front matter</h2>\n<p>Le <em>front matter</em> est une collection de <a href=\"2-front-matter.fr.md\">variables</a> (au format <em>clé/valeur</em>) entourée par <code translate=\"no\">---</code>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">\"The title\"</span>\n<span class=\"hljs-attr\">date:</span> <span class=\"hljs-number\">2019</span><span class=\"hljs-number\">-02</span><span class=\"hljs-number\">-21</span>\n<span class=\"hljs-attr\">tags:</span> <span class=\"hljs-string\">[tag</span> <span class=\"hljs-number\">1</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">tag</span> <span class=\"hljs-number\">2</span><span class=\"hljs-string\">]</span>\n<span class=\"hljs-attr\">customvar:</span> <span class=\"hljs-string\">\"Value of customvar\"</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<aside class=\"note note-info\"><p>Vous pouvez aussi utiliser <code translate=\"no\">&lt;!-- --&gt;</code> ou <code translate=\"no\">+++</code> comme séparateur.</p></aside>\n<h2 id=\"corps-body\">Corps (body)</h2>\n<p>Le <em>body</em> est le contenu principal d’une page ; il peut être écrit en <a href=\"3-markdown.fr.md\">Markdown</a> ou en texte brut.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\"><span class=\"hljs-section\"># Header</span>\n\n[toc]\n\n<span class=\"hljs-section\">## Sub-Header 1</span>\n\nLorem ipsum dolor [<span class=\"hljs-string\">sit amet</span>](<span class=\"hljs-link\">https://example.com</span>), consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n<span class=\"xml\"><span class=\"hljs-comment\">&lt;!-- excerpt --&gt;</span></span>\nUt enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n\n<span class=\"hljs-section\">## Sub-Header 2</span>\n\n![<span class=\"hljs-string\">Description</span>](<span class=\"hljs-link\">/image.jpg \"Title\"</span>)\n\n<span class=\"hljs-section\">## Sub-Header 3</span>\n\n:::tip\nThis is advice.\n:::</code></pre>\n<h2 id=\"prefixe-de-fichier\">Préfixe de fichier</h2>\n<p>Le nom de fichier peut contenir un préfixe pour définir les variables <code translate=\"no\">date</code> ou <code translate=\"no\">weight</code> de la page (utilisé par <a href=\"../templates/reference/2-sorts.fr.md#sort-by-date\"><code translate=\"no\">sortby</code></a>).</p>\n<aside class=\"note note-info\"><p>Séparateurs de préfixe par défaut : <code translate=\"no\">_</code> et <code translate=\"no\">-</code>.</p>\n<p>Vous pouvez les personnaliser avec l’option <a href=\"../configuration/4-pages.fr.md#pages-prefix-separator\"><code translate=\"no\">pages.prefix.separator</code></a>.</p></aside>\n<h3 id=\"date\">date</h3>\n<p>Le <em>date prefix</em> est utilisé pour définir la <code translate=\"no\">date</code> de la page et doit être un format de date valide (c.-à-d. : « YYYY-MM-DD »).</p>\n<p><em>Exemple :</em></p>\n<p>Dans « 2019-04-23_My blog post.md » :</p>\n<ul>\n<li>le préfixe est « 2019-04-23 »</li>\n<li>la <code translate=\"no\">date</code> de la page est « 2019-04-23 »</li>\n<li>le <code translate=\"no\">title</code> de la page est « My blog post »</li>\n</ul>\n<h3 id=\"weight\">weight</h3>\n<p>Le <em>weight prefix</em> est utilisé pour définir l’ordre de tri de la page et doit être une valeur entière valide.</p>\n<p><em>Exemple :</em></p>\n<p>Dans « 1_The first project.md » :</p>\n<ul>\n<li>le préfixe est « 1 »</li>\n<li>le <code translate=\"no\">weight</code> de la page est « 1 »</li>\n<li>le <code translate=\"no\">title</code> de la page est « The first project »</li>\n</ul>\n<h2 id=\"section\">Section</h2>\n<p>Certaines variables dédiées peuvent être utilisées dans une <em>Section</em> personnalisée (c.-à-d. : <code translate=\"no\">&lt;section&gt;/index.md</code>).</p>\n<h3 id=\"sortby\">sortby</h3>\n<p>L’ordre des pages dans une <em>Section</em> peut être modifié.</p>\n<p>Valeurs disponibles :</p>\n<ul>\n<li><code translate=\"no\">date</code>: plus récentes en premier</li>\n<li><code translate=\"no\">title</code>: ordre alphabétique</li>\n<li><code translate=\"no\">weight</code>: plus léger en premier</li>\n</ul>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">sortby:</span> <span class=\"hljs-string\">title</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<p><strong>More options:</strong></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">sortby:</span>\n  <span class=\"hljs-attr\">variable:</span> <span class=\"hljs-string\">date</span>    <span class=\"hljs-comment\"># \"date\", \"updated\", \"title\" or \"weight\"</span>\n  <span class=\"hljs-attr\">desc_title:</span> <span class=\"hljs-literal\">false</span> <span class=\"hljs-comment\"># used with \"date\" or \"updated\" variable value to sort by desc title order if items have the same date</span>\n  <span class=\"hljs-attr\">reverse:</span> <span class=\"hljs-literal\">false</span>    <span class=\"hljs-comment\"># reversed if true</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<h3 id=\"pagination\">pagination</h3>\n<p>La <a href=\"../configuration/4-pages.fr.md#pages-pagination\">configuration globale de pagination</a> est utilisée par défaut, mais vous pouvez la modifier pour une <em>Section</em> donnée.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">pagination:</span>\n  <span class=\"hljs-attr\">max:</span> <span class=\"hljs-number\">5</span>\n  <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">\"page\"</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<p>La pagination peut être désactivée pour une <em>Section</em> :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">pagination:</span> <span class=\"hljs-literal\">false</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<h3 id=\"cascade\">cascade</h3>\n<p>Toutes les variables de <code translate=\"no\">cascade</code> sont ajoutées au front matter de toutes les <em>sous-pages</em>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">cascade:</span>\n  <span class=\"hljs-attr\">banner:</span> <span class=\"hljs-string\">image.jpg</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<aside class=\"note note-info\"><p>Les variables existantes ne sont pas écrasées.</p></aside>\n<h3 id=\"circular\">circular</h3>\n<p>Définissez <code translate=\"no\">circular</code> à <code translate=\"no\">true</code> pour activer la navigation circulaire avec <a href=\"../templates/2-variables.fr.md#page-prev-next\"><em>page.&lt;prev/next&gt;</em></a>.</p>\n<aside class=\"note note-info\"><p>Avec des <a href=\"#sous-section\">sous-sections</a>, seule la valeur <code translate=\"no\">circular</code> de la <em>Section</em> de premier niveau est utilisée.</p></aside>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">circular:</span> <span class=\"hljs-literal\">true</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<h3 id=\"sous-section\">Sous-section</h3>\n<p>Un dossier imbriqué qui contient explicitement un fichier <code translate=\"no\">index.md</code> devient une <em>sous-section</em> de sa <em>Section</em> parente.</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">&lt;monsiteweb&gt;\n└─ pages\n   └─ blog                 &lt;- Section\n      ├─ index.md\n      ├─ post-1.md         &lt;- Page de la Section « blog »\n      └─ 2024              &lt;- Sous-section (contient un « index.md »)\n         ├─ index.md\n         └─ post-2.md      &lt;- Page de la Section « blog » *et* de la sous-section « blog/2024 »</code></pre>\n<p>Une <em>sous-section</em> :</p>\n<ul>\n<li>est une <em>Section</em> (même type, mêmes variables et même résolution de <a href=\"../templates/1-lookup-rules.fr.md#type-section\">gabarit</a>) accessible à sa propre URL (ex. : <code translate=\"no\">/blog/2024/</code>)</li>\n<li>est rendue avec les gabarits de ses <em>Sections</em> parentes si elle n'a pas les siens (ex. : <code translate=\"no\">blog/list.html.twig</code>)</li>\n<li>peut être imbriquée à n'importe quelle profondeur (ex. : <code translate=\"no\">blog/2024/06/</code>)</li>\n<li>liste ses propres pages, et ses pages appartiennent aussi à chacune de leurs <em>Sections</em> parentes</li>\n<li>n'est <strong>pas</strong> listée dans sa <em>Section</em> parente</li>\n<li>est placée dans la navigation <a href=\"../templates/2-variables.fr.md#page-prev-next\"><em>page.&lt;prev/next&gt;</em></a> de sa <em>Section</em> parente (selon son <code translate=\"no\">sortby</code>), suivie de ses propres pages</li>\n</ul>\n<aside class=\"note note-info\"><p>Un dossier imbriqué <strong>sans</strong> fichier <code translate=\"no\">index.md</code> n'est pas une <em>sous-section</em> : ses pages appartiennent simplement à la <em>Section</em> parente.</p></aside>\n<h2 id=\"page-d-accueil\">Page d'accueil</h2>\n<p>Comme une autre section, la <em>Page d'accueil</em> prend en charge la configuration <code translate=\"no\">sortby</code> et <code translate=\"no\">pagination</code>.</p>\n<h3 id=\"pagesfrom\">pagesfrom</h3>\n<p>Définissez un nom de <em>Section</em> valide dans <code translate=\"no\">pagesfrom</code> pour utiliser la collection de pages de cette <em>Section</em> dans la <em>Page d'accueil</em>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">pagesfrom:</span> <span class=\"hljs-string\">blog</span>\n<span class=\"hljs-meta\">---</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/deployer/plateformes-jamstack/",
      "url": "https://cecil-945.pages.dev/fr/documentation/deployer/plateformes-jamstack/",
      "title": "Plateformes Jamstack",
      "summary": "Netlify, Vercel, statichost, Cloudflare Pages, Render.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-14T00:00:00+00:00","content_text": "Plateformes Jamstack\nLes plateformes Jamstack peuvent construire et déployer automatiquement votre site Cecil à chaque push dans votre dépôt Git.\nNetlify\n\nUne puissante plateforme serverless avec un flux de travail intuitif basé sur Git. Déploiements automatisés, aperçus partageables, et bien plus encore.\n\n➡️ https:\/\/www.netlify.com\nnetlify.toml:\n[build]\n  publish = \"_site\"\n  command = \"curl -sSOL https:\/\/cecil.app\/build.sh &amp;&amp; bash .\/build.sh\"\n[context.production.environment]\n  CECIL_ENV = \"production\"\n[context.deploy-preview.environment]\n  CECIL_ENV = \"preview\"\nDocumentation officielle\nVercel\n\nVercel associe une excellente expérience développeur à une attention obsessionnelle portée aux performances côté utilisateur final.\n\n➡️ https:\/\/vercel.com\nvercel.json:\n{\n  \"buildCommand\": \"curl -sSOL https:\/\/cecil.app\/build.sh &amp;&amp; bash .\/build.sh\",\n  \"outputDirectory\": \"_site\"\n}\nDocumentation officielle\nstatichost\n\nHébergement moderne de sites statiques avec des serveurs européens et absolument aucune collecte de données personnelles !\n\n➡️ https:\/\/statichost.eu\nstatichost.yml:\nimage: wordpress:cli-php8.4\ncommand: curl -sSOL https:\/\/cecil.app\/build.sh &amp;&amp; bash .\/build.sh\npublic: _site\nDocumentation officielle\nCloudflare Pages\nCloudflare Pages ne fournit pas PHP : le script de build utilise alors le binaire autonome de Cecil, et installe les thèmes à partir de composer.lock.\n\nCloudflare Pages est une plateforme JAMstack qui permet aux développeurs frontend de collaborer et de déployer des sites web.\n\n➡️ https:\/\/pages.cloudflare.com\nConfigurations de build :\n\nPréréglage de framework : None\nCommande de build : curl -sSOL https:\/\/cecil.app\/build.sh &amp;&amp; bash .\/build.sh\nRépertoire de sortie du build : _site\n\nDocumentation officielle\nRender\nRender ne fournit que PHP 7.3 : le script de build utilise alors le binaire autonome de Cecil, et installe les thèmes à partir de composer.lock.\n\nRender est un cloud unifié pour créer et exécuter toutes vos applications et tous vos sites web, avec certificats TLS gratuits, CDN global, réseaux privés et déploiements automatiques depuis Git.\n\n➡️ https:\/\/render.com\nrender.yaml:\npreviewsEnabled: true\nservices:\n  - type: web\n    name: Cecil\n    env: static\n    buildCommand: curl -sSOL https:\/\/cecil.app\/build.sh &amp;&amp; bash .\/build.sh\n    staticPublishPath: _site\n    pullRequestPreviewsEnabled: true\nDocumentation officielle",
      "content_html": "<h1>Plateformes Jamstack</h1>\n<p>Les plateformes Jamstack peuvent construire et déployer automatiquement votre site Cecil à chaque push dans votre dépôt Git.</p>\n<h2 id=\"netlify\">Netlify</h2>\n<blockquote>\n<p>Une puissante plateforme serverless avec un flux de travail intuitif basé sur Git. Déploiements automatisés, aperçus partageables, et bien plus encore.</p>\n</blockquote>\n<p>➡️ <a href=\"https://www.netlify.com\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.netlify.com</a></p>\n<p><em>netlify.toml</em>:</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">[build]\n  publish = <span class=\"hljs-string\">\"_site\"</span>\n  <span class=\"hljs-built_in\">command</span> = <span class=\"hljs-string\">\"curl -sSOL https://cecil.app/build.sh &amp;&amp; bash ./build.sh\"</span>\n[context.production.environment]\n  CECIL_ENV = <span class=\"hljs-string\">\"production\"</span>\n[context.deploy-preview.environment]\n  CECIL_ENV = <span class=\"hljs-string\">\"preview\"</span></code></pre>\n<p><a href=\"https://www.netlify.com/docs/continuous-deployment/\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation officielle</a></p>\n<h2 id=\"vercel\">Vercel</h2>\n<blockquote>\n<p>Vercel associe une excellente expérience développeur à une attention obsessionnelle portée aux performances côté utilisateur final.</p>\n</blockquote>\n<p>➡️ <a href=\"https://vercel.com\" target=\"_blank\" rel=\"noopener noreferrer\">https://vercel.com</a></p>\n<p><em>vercel.json</em>:</p>\n<pre><code class=\"language-json hljs json\" translate=\"no\">{\n  <span class=\"hljs-attr\">\"buildCommand\"</span>: <span class=\"hljs-string\">\"curl -sSOL https://cecil.app/build.sh &amp;&amp; bash ./build.sh\"</span>,\n  <span class=\"hljs-attr\">\"outputDirectory\"</span>: <span class=\"hljs-string\">\"_site\"</span>\n}</code></pre>\n<p><a href=\"https://vercel.com/docs/concepts/deployments/build-step#build-command\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation officielle</a></p>\n<h2 id=\"statichost\">statichost</h2>\n<blockquote>\n<p>Hébergement moderne de sites statiques avec des serveurs européens et absolument aucune collecte de données personnelles !</p>\n</blockquote>\n<p>➡️ <a href=\"https://statichost.eu\" target=\"_blank\" rel=\"noopener noreferrer\">https://statichost.eu</a></p>\n<p><em>statichost.yml</em>:</p>\n<pre><code class=\"language-yml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">wordpress:cli-php8.4</span>\n<span class=\"hljs-attr\">command:</span> <span class=\"hljs-string\">curl</span> <span class=\"hljs-string\">-sSOL</span> <span class=\"hljs-string\">https://cecil.app/build.sh</span> <span class=\"hljs-string\">&amp;&amp;</span> <span class=\"hljs-string\">bash</span> <span class=\"hljs-string\">./build.sh</span>\n<span class=\"hljs-attr\">public:</span> <span class=\"hljs-string\">_site</span></code></pre>\n<p><a href=\"https://www.statichost.eu/docs/\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation officielle</a></p>\n<h2 id=\"cloudflare-pages\">Cloudflare Pages</h2>\n<aside class=\"note note-info\"><p>Cloudflare Pages ne fournit pas PHP : le script de build utilise alors le <a href=\"../getting-started/2-installation.fr.md#standalone-binary\">binaire autonome</a> de Cecil, et installe les thèmes à partir de <code translate=\"no\">composer.lock</code>.</p></aside>\n<blockquote>\n<p>Cloudflare Pages est une plateforme JAMstack qui permet aux développeurs frontend de collaborer et de déployer des sites web.</p>\n</blockquote>\n<p>➡️ <a href=\"https://pages.cloudflare.com\" target=\"_blank\" rel=\"noopener noreferrer\">https://pages.cloudflare.com</a></p>\n<p>Configurations de build :</p>\n<ul>\n<li>Préréglage de framework : <code translate=\"no\">None</code></li>\n<li>Commande de build : <code translate=\"no\">curl -sSOL https://cecil.app/build.sh &amp;&amp; bash ./build.sh</code></li>\n<li>Répertoire de sortie du build : <code translate=\"no\">_site</code></li>\n</ul>\n<p><a href=\"https://developers.cloudflare.com/pages/\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation officielle</a></p>\n<h2 id=\"render\">Render</h2>\n<aside class=\"note note-info\"><p>Render ne fournit que PHP 7.3 : le script de build utilise alors le <a href=\"../getting-started/2-installation.fr.md#standalone-binary\">binaire autonome</a> de Cecil, et installe les thèmes à partir de <code translate=\"no\">composer.lock</code>.</p></aside>\n<blockquote>\n<p>Render est un cloud unifié pour créer et exécuter toutes vos applications et tous vos sites web, avec certificats TLS gratuits, CDN global, réseaux privés et déploiements automatiques depuis Git.</p>\n</blockquote>\n<p>➡️ <a href=\"https://render.com\" target=\"_blank\" rel=\"noopener noreferrer\">https://render.com</a></p>\n<p><em>render.yaml</em>:</p>\n<pre><code class=\"language-yml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">previewsEnabled:</span> <span class=\"hljs-literal\">true</span>\n<span class=\"hljs-attr\">services:</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">type:</span> <span class=\"hljs-string\">web</span>\n    <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Cecil</span>\n    <span class=\"hljs-attr\">env:</span> <span class=\"hljs-string\">static</span>\n    <span class=\"hljs-attr\">buildCommand:</span> <span class=\"hljs-string\">curl</span> <span class=\"hljs-string\">-sSOL</span> <span class=\"hljs-string\">https://cecil.app/build.sh</span> <span class=\"hljs-string\">&amp;&amp;</span> <span class=\"hljs-string\">bash</span> <span class=\"hljs-string\">./build.sh</span>\n    <span class=\"hljs-attr\">staticPublishPath:</span> <span class=\"hljs-string\">_site</span>\n    <span class=\"hljs-attr\">pullRequestPreviewsEnabled:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<p><a href=\"https://render.com/docs/static-sites\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation officielle</a></p>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/developpeurs/etendre/",
      "url": "https://cecil-945.pages.dev/fr/documentation/developpeurs/etendre/",
      "title": "Étendre",
      "summary": "Créez des générateurs de pages, ajoutez des extensions Twig et post-traitez les fichiers de sortie.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-02T00:00:00+00:00","content_text": "Étendre\nComme Cecil repose sur PHP, il est facile d'en étendre les capacités.\nGénérateur de pages\nUn générateur permet de créer des pages sans fichiers Markdown (avec des données provenant d'une API ou d'une base de données, par exemple), ou de modifier des pages existantes.\nCréez simplement une nouvelle classe PHP dans l'espace de noms Cecil\\Generator, puis ajoutez le nom de la classe à la liste pages.generators.\nExemple:\n\/extensions\/Cecil\/Generator\/DummyPage.php\n&lt;?php\nnamespace Cecil\\Generator;\n\nuse Cecil\\Collection\\Page\\Page;\nuse Cecil\\Collection\\Page\\Type;\n\nclass DummyPage extends AbstractGenerator implements GeneratorInterface\n{\n    public function generate(): void\n    {\n        \/\/ create a new page $page, then add it to the site collection\n        $page = (new Page('my-page'))\n            -&gt;setType(Type::PAGE-&gt;value)\n            -&gt;setPath('mypage')\n            -&gt;setBodyHtml('&lt;p&gt;My page body&lt;\/p&gt;')\n            -&gt;setVariable('language', 'en')\n            -&gt;setVariable('title', 'My page')\n            -&gt;setVariable('date', now())\n            -&gt;setVariable('menu', ['main' =&gt; ['weight' =&gt; 99]]);\n        $this-&gt;generatedPages-&gt;add($page);\n    }\n}\n\/extensions\/Cecil\/Generator\/Database.php\n&lt;?php\nnamespace Cecil\\Generator;\n\nuse Cecil\\Collection\\Page\\Page;\nuse Cecil\\Collection\\Page\\Type;\n\nclass Database extends AbstractGenerator implements GeneratorInterface\n{\n    public function generate(): void\n    {\n        \/\/ create pages from a SQLite database\n        $db = new SQLite3('database.sqlite');\n        $statement = $db-&gt;prepare('SELECT * FROM blog');\n        $result = $statement-&gt;execute();\n        while ($row = $result-&gt;fetchArray(SQLITE3_ASSOC)) {\n            $page = (new Page($row['page-id']))\n                -&gt;setType(Type::PAGE-&gt;value)\n                -&gt;setPath($row['path'])\n                -&gt;setBodyHtml($row['html'])\n                -&gt;setVariable('title', $row['title'])\n                -&gt;setVariable('date', $row['date']);\n            $this-&gt;generatedPages-&gt;add($page);\n        }\n        $result-&gt;finalize();\n        $db-&gt;close();\n    }\n}\nconfiguration\npages:\n  generators:\n    # priority: class name\n    99: Cecil\\Generator\\DummyPage\n    35: Cecil\\Generator\\Database\nExtension Twig\nVous pouvez ajouter des fonctions et des filtres personnalisés :\n\ncréez une extension Twig dans l'espace de noms Cecil\\Renderer\\Extension\najoutez le fichier PHP dans le répertoire extensions\najoutez le nom de la classe à la configuration\n\nExemple:\n\/extensions\/Cecil\/Renderer\/Extension\/MyTwigExtension.php\n&lt;?php\nnamespace Cecil\\Renderer\\Extension;\n\nclass MyTwigExtension extends \\Twig\\Extension\\AbstractExtension\n{\n    public function getFilters()\n    {\n        \/\/ add a new filter named 'md5'\n        return [\n            new \\Twig\\TwigFilter('md5', 'md5'),\n        ];\n    }\n}\nconfiguration\nlayouts:\n  extensions:\n    MyExtension: Cecil\\Renderer\\Extension\\MyTwigExtension\nPost-processeur de rendu\nVous pouvez post-traiter le rendu des pages.\nCréez simplement une nouvelle classe PHP dans l'espace de noms Cecil\\Renderer\\PostProcessor et ajoutez le nom de la classe à la liste output.postprocessors.\nExemple:\n\/extensions\/Cecil\/Renderer\/PostProcessor\/MyProcessor.php\n&lt;?php\nnamespace Cecil\\Renderer\\PostProcessor;\n\nuse Cecil\\Collection\\Page\\Page;\n\nclass MyProcessor extends AbstractPostProcessor\n{\n    public function process(Page $page, string $output, string $format): string\n    {\n        \/\/ add a meta tag to the head of the HTML output\n        if ($format == 'html') {\n            if (!preg_match('\/&lt;meta name=\"test\".*\/i', $output)) {\n                $meta = \\sprintf('&lt;meta name=\"test\" content=\"Test\"&gt;');\n                $output = preg_replace_callback('\/([[:blank:]]*)(&lt;\\\/head&gt;)\/i', function ($matches) use ($meta) {\n                    return str_repeat($matches[1] ?: ' ', 2) . $meta . \"\\n\" . $matches[1] . $matches[2];\n                }, $output);\n            }\n        }\n\n        return $output;\n    }\n}\nconfiguration\noutput:\n  postprocessors:\n    MyProcessor: Cecil\\Renderer\\PostProcessor\\MyProcessor",
      "content_html": "<h1>Étendre</h1>\n<p>Comme Cecil repose sur PHP, il est facile d'en étendre les capacités.</p>\n<h2 id=\"generateur-de-pages\">Générateur de pages</h2>\n<p>Un générateur permet de créer des pages sans fichiers Markdown (avec des données provenant d'une API ou d'une base de données, par exemple), ou de modifier des pages existantes.</p>\n<p>Créez simplement une nouvelle classe PHP dans l'espace de noms <code translate=\"no\">Cecil\\Generator</code>, puis ajoutez le nom de la classe à la liste <a href=\"../configuration/4-pages.fr.md#pages-generators\"><code translate=\"no\">pages.generators</code></a>.</p>\n<p><strong>Exemple:</strong></p>\n<p><em>/extensions/Cecil/Generator/DummyPage.php</em></p>\n<pre><code class=\"language-php hljs php\" translate=\"no\"><span class=\"hljs-meta\">&lt;?php</span>\n<span class=\"hljs-keyword\">namespace</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Generator</span>;\n\n<span class=\"hljs-keyword\">use</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Collection</span>\\<span class=\"hljs-title\">Page</span>\\<span class=\"hljs-title\">Page</span>;\n<span class=\"hljs-keyword\">use</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Collection</span>\\<span class=\"hljs-title\">Page</span>\\<span class=\"hljs-title\">Type</span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">DummyPage</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">AbstractGenerator</span> <span class=\"hljs-keyword\">implements</span> <span class=\"hljs-title\">GeneratorInterface</span>\n</span>{\n    <span class=\"hljs-keyword\">public</span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-title\">generate</span><span class=\"hljs-params\">()</span>: <span class=\"hljs-title\">void</span>\n    </span>{\n        <span class=\"hljs-comment\">// create a new page $page, then add it to the site collection</span>\n        $page = (<span class=\"hljs-keyword\">new</span> Page(<span class=\"hljs-string\">'my-page'</span>))\n            -&gt;setType(Type::PAGE-&gt;value)\n            -&gt;setPath(<span class=\"hljs-string\">'mypage'</span>)\n            -&gt;setBodyHtml(<span class=\"hljs-string\">'&lt;p&gt;My page body&lt;/p&gt;'</span>)\n            -&gt;setVariable(<span class=\"hljs-string\">'language'</span>, <span class=\"hljs-string\">'en'</span>)\n            -&gt;setVariable(<span class=\"hljs-string\">'title'</span>, <span class=\"hljs-string\">'My page'</span>)\n            -&gt;setVariable(<span class=\"hljs-string\">'date'</span>, now())\n            -&gt;setVariable(<span class=\"hljs-string\">'menu'</span>, [<span class=\"hljs-string\">'main'</span> =&gt; [<span class=\"hljs-string\">'weight'</span> =&gt; <span class=\"hljs-number\">99</span>]]);\n        <span class=\"hljs-keyword\">$this</span>-&gt;generatedPages-&gt;add($page);\n    }\n}</code></pre>\n<p><em>/extensions/Cecil/Generator/Database.php</em></p>\n<pre><code class=\"language-php hljs php\" translate=\"no\"><span class=\"hljs-meta\">&lt;?php</span>\n<span class=\"hljs-keyword\">namespace</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Generator</span>;\n\n<span class=\"hljs-keyword\">use</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Collection</span>\\<span class=\"hljs-title\">Page</span>\\<span class=\"hljs-title\">Page</span>;\n<span class=\"hljs-keyword\">use</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Collection</span>\\<span class=\"hljs-title\">Page</span>\\<span class=\"hljs-title\">Type</span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">Database</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">AbstractGenerator</span> <span class=\"hljs-keyword\">implements</span> <span class=\"hljs-title\">GeneratorInterface</span>\n</span>{\n    <span class=\"hljs-keyword\">public</span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-title\">generate</span><span class=\"hljs-params\">()</span>: <span class=\"hljs-title\">void</span>\n    </span>{\n        <span class=\"hljs-comment\">// create pages from a SQLite database</span>\n        $db = <span class=\"hljs-keyword\">new</span> SQLite3(<span class=\"hljs-string\">'database.sqlite'</span>);\n        $statement = $db-&gt;prepare(<span class=\"hljs-string\">'SELECT * FROM blog'</span>);\n        $result = $statement-&gt;execute();\n        <span class=\"hljs-keyword\">while</span> ($row = $result-&gt;fetchArray(SQLITE3_ASSOC)) {\n            $page = (<span class=\"hljs-keyword\">new</span> Page($row[<span class=\"hljs-string\">'page-id'</span>]))\n                -&gt;setType(Type::PAGE-&gt;value)\n                -&gt;setPath($row[<span class=\"hljs-string\">'path'</span>])\n                -&gt;setBodyHtml($row[<span class=\"hljs-string\">'html'</span>])\n                -&gt;setVariable(<span class=\"hljs-string\">'title'</span>, $row[<span class=\"hljs-string\">'title'</span>])\n                -&gt;setVariable(<span class=\"hljs-string\">'date'</span>, $row[<span class=\"hljs-string\">'date'</span>]);\n            <span class=\"hljs-keyword\">$this</span>-&gt;generatedPages-&gt;add($page);\n        }\n        $result-&gt;finalize();\n        $db-&gt;close();\n    }\n}</code></pre>\n<p><em>configuration</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">generators:</span>\n    <span class=\"hljs-comment\"># priority: class name</span>\n    <span class=\"hljs-attr\">99:</span> <span class=\"hljs-string\">Cecil\\Generator\\DummyPage</span>\n    <span class=\"hljs-attr\">35:</span> <span class=\"hljs-string\">Cecil\\Generator\\Database</span></code></pre>\n<h2 id=\"extension-twig\">Extension Twig</h2>\n<p>Vous pouvez ajouter des <a href=\"../templates/reference/1-functions.fr.md\">fonctions</a> et des <a href=\"../templates/reference/3-filters.fr.md\">filtres</a> personnalisés :</p>\n<ol>\n<li><a href=\"https://twig.symfony.com/doc/advanced.html#creating-an-extension\" target=\"_blank\" rel=\"noopener noreferrer\">créez une extension Twig</a> dans l'espace de noms <code translate=\"no\">Cecil\\Renderer\\Extension</code></li>\n<li>ajoutez le fichier PHP dans le répertoire <code translate=\"no\">extensions</code></li>\n<li>ajoutez le nom de la classe à la configuration</li>\n</ol>\n<p><strong>Exemple:</strong></p>\n<p><em>/extensions/Cecil/Renderer/Extension/MyTwigExtension.php</em></p>\n<pre><code class=\"language-php hljs php\" translate=\"no\"><span class=\"hljs-meta\">&lt;?php</span>\n<span class=\"hljs-keyword\">namespace</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Renderer</span>\\<span class=\"hljs-title\">Extension</span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyTwigExtension</span> <span class=\"hljs-keyword\">extends</span> \\<span class=\"hljs-title\">Twig</span>\\<span class=\"hljs-title\">Extension</span>\\<span class=\"hljs-title\">AbstractExtension</span>\n</span>{\n    <span class=\"hljs-keyword\">public</span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-title\">getFilters</span><span class=\"hljs-params\">()</span>\n    </span>{\n        <span class=\"hljs-comment\">// add a new filter named 'md5'</span>\n        <span class=\"hljs-keyword\">return</span> [\n            <span class=\"hljs-keyword\">new</span> \\Twig\\TwigFilter(<span class=\"hljs-string\">'md5'</span>, <span class=\"hljs-string\">'md5'</span>),\n        ];\n    }\n}</code></pre>\n<p><em>configuration</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">layouts:</span>\n  <span class=\"hljs-attr\">extensions:</span>\n    <span class=\"hljs-attr\">MyExtension:</span> <span class=\"hljs-string\">Cecil\\Renderer\\Extension\\MyTwigExtension</span></code></pre>\n<h2 id=\"post-processeur-de-rendu\">Post-processeur de rendu</h2>\n<p>Vous pouvez post-traiter le rendu des pages.</p>\n<p>Créez simplement une nouvelle classe PHP dans l'espace de noms <code translate=\"no\">Cecil\\Renderer\\PostProcessor</code> et ajoutez le nom de la classe à la liste <code translate=\"no\">output.postprocessors</code>.</p>\n<p><strong>Exemple:</strong></p>\n<p><em>/extensions/Cecil/Renderer/PostProcessor/MyProcessor.php</em></p>\n<pre><code class=\"language-php hljs php\" translate=\"no\"><span class=\"hljs-meta\">&lt;?php</span>\n<span class=\"hljs-keyword\">namespace</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Renderer</span>\\<span class=\"hljs-title\">PostProcessor</span>;\n\n<span class=\"hljs-keyword\">use</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Collection</span>\\<span class=\"hljs-title\">Page</span>\\<span class=\"hljs-title\">Page</span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class</span> <span class=\"hljs-title\">MyProcessor</span> <span class=\"hljs-keyword\">extends</span> <span class=\"hljs-title\">AbstractPostProcessor</span>\n</span>{\n    <span class=\"hljs-keyword\">public</span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-title\">process</span><span class=\"hljs-params\">(Page $page, string $output, string $format)</span>: <span class=\"hljs-title\">string</span>\n    </span>{\n        <span class=\"hljs-comment\">// add a meta tag to the head of the HTML output</span>\n        <span class=\"hljs-keyword\">if</span> ($format == <span class=\"hljs-string\">'html'</span>) {\n            <span class=\"hljs-keyword\">if</span> (!preg_match(<span class=\"hljs-string\">'/&lt;meta name=\"test\".*/i'</span>, $output)) {\n                $meta = \\sprintf(<span class=\"hljs-string\">'&lt;meta name=\"test\" content=\"Test\"&gt;'</span>);\n                $output = preg_replace_callback(<span class=\"hljs-string\">'/([[:blank:]]*)(&lt;\\/head&gt;)/i'</span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function</span> <span class=\"hljs-params\">($matches)</span> <span class=\"hljs-title\">use</span> <span class=\"hljs-params\">($meta)</span> </span>{\n                    <span class=\"hljs-keyword\">return</span> str_repeat($matches[<span class=\"hljs-number\">1</span>] ?: <span class=\"hljs-string\">' '</span>, <span class=\"hljs-number\">2</span>) . $meta . <span class=\"hljs-string\">\"\\n\"</span> . $matches[<span class=\"hljs-number\">1</span>] . $matches[<span class=\"hljs-number\">2</span>];\n                }, $output);\n            }\n        }\n\n        <span class=\"hljs-keyword\">return</span> $output;\n    }\n}</code></pre>\n<p><em>configuration</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">output:</span>\n  <span class=\"hljs-attr\">postprocessors:</span>\n    <span class=\"hljs-attr\">MyProcessor:</span> <span class=\"hljs-string\">Cecil\\Renderer\\PostProcessor\\MyProcessor</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/commandes/new-page/",
      "url": "https://cecil-945.pages.dev/fr/documentation/commandes/new-page/",
      "title": "new:page",
      "summary": "Créer une nouvelle page, éventuellement à partir d’un modèle.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "new:page\nCrée une nouvelle page.\nUtilisation\nDescription:\n  Creates a new page\n\nUsage:\n  new:page [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                        Use the given path as working directory\n\nOptions:\n      --name=NAME             Page path name\n      --slugify|--no-slugify  Slugify file name (or disable --no-slugify)\n  -p, --prefix                Prefix the file name with the current date (`YYYY-MM-DD`)\n  -f, --force                 Override the file if already exist\n  -o, --open                  Open editor automatically\n      --editor=EDITOR         Editor to use with open option\n  -h, --help                  Display help for the given command. When no command is given display help for the list command\n  -q, --quiet                 Do not output any message\n  -V, --version               Display this application version\n      --ansi|--no-ansi        Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction        Do not ask any interactive question\n  -v|vv|vvv, --verbose        Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The new:page command creates a new page file.\n  If you run this command without any options, it will ask you for the page name and other options.\n\n    cecil.phar new:page\n    cecil.phar new:page --name=path\/to\/a-page.md\n    cecil.phar new:page --name=path\/to\/A Page.md --slugify\n\n  To create a new page with a date prefix (i.e: `YYYY-MM-DD`), run:\n\n    cecil.phar new:page --prefix\n\n  To create a new page and open it with an editor, run:\n\n    cecil.phar new:page --open --editor=editor\n\n  To override an existing page, run:\n\n    cecil.phar new:page --force\nModèles de page\nVous pouvez définir vos propres modèles pour vos nouvelles pages dans le répertoire models :\n\nLe nom doit être basé sur le nom de la section (par exemple : blog.md)\nLe modèle par défaut doit être nommé default.md (pour les pages racine ou les sections de pages sans modèle)\n\nDeux variables dynamiques sont disponibles :\n\n%title% : le nom du fichier\n%date% : la date actuelle\n\nOuvrir avec votre éditeur\nAvec l’option --open, l’éditeur s’ouvrira automatiquement. Utilisez donc la clé editor dans votre fichier de configuration pour définir l’éditeur par défaut (par exemple : editor: typora).",
      "content_html": "<h1>new:page</h1>\n<p>Crée une nouvelle page.</p>\n<h2 id=\"utilisation\">Utilisation</h2>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Creates a new page\n\nUsage:\n  new:page [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                        Use the given path as working directory\n\nOptions:\n      --name=NAME             Page path name\n      --slugify|--no-slugify  Slugify file name (or disable --no-slugify)\n  -p, --prefix                Prefix the file name with the current date (`YYYY-MM-DD`)\n  -f, --force                 Override the file if already exist\n  -o, --open                  Open editor automatically\n      --editor=EDITOR         Editor to use with open option\n  -h, --help                  Display help for the given command. When no command is given display help for the list command\n  -q, --quiet                 Do not output any message\n  -V, --version               Display this application version\n      --ansi|--no-ansi        Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction        Do not ask any interactive question\n  -v|vv|vvv, --verbose        Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The new:page command creates a new page file.\n  If you run this command without any options, it will ask you for the page name and other options.\n\n    cecil.phar new:page\n    cecil.phar new:page --name=path/to/a-page.md\n    cecil.phar new:page --name=path/to/A Page.md --slugify\n\n  To create a new page with a date prefix (i.e: `YYYY-MM-DD`), run:\n\n    cecil.phar new:page --prefix\n\n  To create a new page and open it with an editor, run:\n\n    cecil.phar new:page --open --editor=editor\n\n  To override an existing page, run:\n\n    cecil.phar new:page --force</code></pre>\n<h2 id=\"modeles-de-page\">Modèles de page</h2>\n<p>Vous pouvez définir vos propres modèles pour vos nouvelles pages dans le répertoire <code translate=\"no\">models</code> :</p>\n<ol>\n<li>Le nom doit être basé sur le nom de la section (par exemple : <code translate=\"no\">blog.md</code>)</li>\n<li>Le modèle par défaut doit être nommé <code translate=\"no\">default.md</code> (pour les pages racine ou les sections de pages sans modèle)</li>\n</ol>\n<p>Deux variables dynamiques sont disponibles :</p>\n<ol>\n<li><code translate=\"no\">%title%</code> : le nom du fichier</li>\n<li><code translate=\"no\">%date%</code> : la date actuelle</li>\n</ol>\n<h2 id=\"ouvrir-avec-votre-editeur\">Ouvrir avec votre éditeur</h2>\n<p>Avec l’option <code translate=\"no\">--open</code>, l’éditeur s’ouvrira automatiquement. Utilisez donc la clé <code translate=\"no\">editor</code> dans votre fichier de configuration pour définir l’éditeur par défaut (par exemple : <code translate=\"no\">editor: typora</code>).</p>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/langues/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/langues/",
      "title": "Langues",
      "summary": "Langue principale et langues supplémentaires d’un site multilingue.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Langues\nCes options définissent la langue principale du site et, pour un site multilingue, ses langues supplémentaires.\nlanguage\nLangue principale, définie par son code.\nlanguage: &lt;code&gt; # unique code (`en` by default)\nPar défaut, seuls les chemins des pages des autres langues sont préfixés par leur code de langue, mais vous pouvez préfixer le chemin des pages de la langue principale avec l’option suivante :\n#language: &lt;code&gt;\nlanguage:\n  code: &lt;code&gt;\n  prefix: true\nQuand prefix est défini à true, un alias est automatiquement créé pour la page d’accueil afin de rediriger de \/ vers \/&lt;code&gt;\/.\nlanguages\nOptions des langues disponibles, utilisées pour la localisation des pages et des templates.\nlanguages:\n  - code: &lt;code&gt;          # unique code (e.g.: `en`, `fr`, 'en-US', `fr-CA`)\n    name: &lt;name&gt;          # human readable name (e.g.: `Français`)\n    locale: &lt;locale&gt;      # locale code (`language_COUNTRY`, e.g.: `en_US`, `fr_FR`, `fr_CA`)\n    enabled: &lt;true|false&gt; # enabled or not (`true` by default)\nExemple :\nlanguage: en\nlanguages:\n  - code: en\n    name: English\n    locale: en_US\n  - code: fr\n    name: Français\n    locale: fr_FR\nUne liste des codes de locale est disponible si nécessaire.\nLocaliser\nPour localiser des options de configuration, vous devez les stocker sous la clé config de la langue.\nExemple :\ntitle: \"Cecil in english\"\nlanguages:\n  - code: en\n    name: English\n    locale: en_US\n  - code: fr\n    name: Français\n    locale: fr_FR\n    config:\n      title: \"Cecil en français\"\nDans les templates, vous pouvez accéder à une option avec {{ site.&lt;option&gt; }}, par exemple {{ site.title }}.\nSi une option n’est pas disponible dans la langue actuelle (ex. : fr), elle revient à la valeur globale (ex. : en).",
      "content_html": "<h1>Langues</h1>\n<p>Ces options définissent la langue principale du site et, pour un site multilingue, ses langues supplémentaires.</p>\n<h2 id=\"language\">language</h2>\n<p>Langue principale, définie par son code.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">language:</span> <span class=\"hljs-string\">&lt;code&gt;</span> <span class=\"hljs-comment\"># unique code (`en` by default)</span></code></pre>\n<p>Par défaut, seuls les chemins des pages des autres <a href=\"#languages\">langues</a> sont préfixés par leur code de langue, mais vous pouvez préfixer le chemin des pages de la langue principale avec l’option suivante :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-comment\">#language: &lt;code&gt;</span>\n<span class=\"hljs-attr\">language:</span>\n  <span class=\"hljs-attr\">code:</span> <span class=\"hljs-string\">&lt;code&gt;</span>\n  <span class=\"hljs-attr\">prefix:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<aside class=\"note note-info\"><p>Quand <code translate=\"no\">prefix</code> est défini à <code translate=\"no\">true</code>, un alias est automatiquement créé pour la page d’accueil afin de rediriger de <code translate=\"no\">/</code> vers <code translate=\"no\">/&lt;code&gt;/</code>.</p></aside>\n<h2 id=\"languages\">languages</h2>\n<p>Options des langues disponibles, utilisées pour la localisation des <a href=\"../content/4-multilingual.fr.md\">pages</a> et des <a href=\"../templates/5-localization.fr.md\">templates</a>.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">languages:</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">code:</span> <span class=\"hljs-string\">&lt;code&gt;</span>          <span class=\"hljs-comment\"># unique code (e.g.: `en`, `fr`, 'en-US', `fr-CA`)</span>\n    <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">&lt;name&gt;</span>          <span class=\"hljs-comment\"># human readable name (e.g.: `Français`)</span>\n    <span class=\"hljs-attr\">locale:</span> <span class=\"hljs-string\">&lt;locale&gt;</span>      <span class=\"hljs-comment\"># locale code (`language_COUNTRY`, e.g.: `en_US`, `fr_FR`, `fr_CA`)</span>\n    <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-string\">&lt;true|false&gt;</span> <span class=\"hljs-comment\"># enabled or not (`true` by default)</span></code></pre>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">language:</span> <span class=\"hljs-string\">en</span>\n<span class=\"hljs-attr\">languages:</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">code:</span> <span class=\"hljs-string\">en</span>\n    <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">English</span>\n    <span class=\"hljs-attr\">locale:</span> <span class=\"hljs-string\">en_US</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">code:</span> <span class=\"hljs-string\">fr</span>\n    <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Français</span>\n    <span class=\"hljs-attr\">locale:</span> <span class=\"hljs-string\">fr_FR</span></code></pre>\n<aside class=\"note note-info\"><p>Une <a href=\"3-locale-codes.fr.md\">liste des codes de locale</a> est disponible si nécessaire.</p></aside>\n<h3 id=\"localiser\">Localiser</h3>\n<p>Pour localiser des options de configuration, vous devez les stocker sous la clé <code translate=\"no\">config</code> de la langue.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">\"Cecil in english\"</span>\n<span class=\"hljs-attr\">languages:</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">code:</span> <span class=\"hljs-string\">en</span>\n    <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">English</span>\n    <span class=\"hljs-attr\">locale:</span> <span class=\"hljs-string\">en_US</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">code:</span> <span class=\"hljs-string\">fr</span>\n    <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Français</span>\n    <span class=\"hljs-attr\">locale:</span> <span class=\"hljs-string\">fr_FR</span>\n    <span class=\"hljs-attr\">config:</span>\n      <span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">\"Cecil en français\"</span></code></pre>\n<aside class=\"note note-info\"><p>Dans les <a href=\"../templates/index.fr.md\">templates</a>, vous pouvez accéder à une option avec <code translate=\"no\">{{ site.&lt;option&gt; }}</code>, par exemple <code translate=\"no\">{{ site.title }}</code>.<br>\nSi une option n’est pas disponible dans la langue actuelle (ex. : <code translate=\"no\">fr</code>), elle revient à la valeur globale (ex. : <code translate=\"no\">en</code>).</p></aside>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/contenu/front-matter/",
      "url": "https://cecil-945.pages.dev/fr/documentation/contenu/front-matter/",
      "title": "Front matter",
      "summary": "Variables de page personnalisées et prédéfinies : menu, taxonomie, planification, redirection, alias, sortie, etc.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-03T00:00:00+00:00","content_text": "Front matter\nLe front matter peut contenir des variables personnalisées appliquées à la page courante.\nIl doit se trouver au tout début du fichier et être un YAML valide.\nVariables prédéfinies\n\n\n\nVariable\nDescription\nValeur par défaut\nExemple\n\n\n\n\ntitle\nTitre\nNom de fichier sans extension.\nPost 1\n\n\nlayout\nTemplate\nVoir Lookup rules.\n404\n\n\ndate\nDate de création\nDate de création du fichier (objet PHP DateTime).\n2019\/04\/15\n\n\nsection\nSection\nSection de la page.\nblog\n\n\npath\nChemin\nPath de la page.\nblog\/post-1\n\n\nslug\nSlug\nSlug de la page.\npost-1\n\n\npublished\nPublié ou non\ntrue.\nfalse\n\n\ndraft\nBrouillon ou non\nfalse.\ntrue\n\n\n\nToutes les variables prédéfinies peuvent être surchargées, sauf section.\nupdated\nLa variable updated sert à définir la date de dernière modification d’une page.\nExemple :\n---\nupdated: 2026-02-02\n---\nAvant la version 8.80.1, la variable updated était une variable prédéfinie. Elle est désormais optionnelle (et doit être définie dans le front matter pour être utilisée).\nmenu\nUne page peut être ajoutée à un menu.\nLe nom de l’entrée est le title de la page et l’URL est le path de la page.\nLa même page peut être ajoutée à plusieurs menus, et la position de chaque entrée peut être définie avec la clé weight (la plus faible en premier). La clé name peut être utilisée pour personnaliser le nom de l’entrée par menu.\nExemples :\n---\nmenu: main\n---\n---\nmenu: [main, navigation] # same page in multiple menus\n---\n---\nmenu:\n  main:\n    weight: 10\n  navigation:\n    weight: 20\n---\n---\ntitle: 'Notre expertise'\nmenu:\n  main:\n    weight: 15\n  footer:\n    weight: 15\n    name: \"Expertise\" # personnalise le nom de l'entrée dans ce menu\n---\nTaxonomie\nLa taxonomie permet de connecter, relier et classer le contenu de votre site Web.\nDans Cecil, ces termes sont regroupés dans des vocabulaires.\nLes vocabulaires sont déclarés dans la Configuration.\n\nVocabulaire\nUne catégorisation du contenu (ex. : tags, categories, etc.).\nTerme\nUn terme est un élément d’un vocabulaire (ex. : Développement, PHP, etc.).\n\nExemple :\n---\ntags: [\"Développement\", \"PHP\"]\n---\nCecil génère ensuite, pour chaque vocabulaire :\n\nune page listant ses termes, ex. : \/tags\/\nune page par terme listant ses pages, ex. : \/tags\/developpement\/ et \/tags\/php\/\n\nVoir les règles de recherche des templates et les variables de taxonomie pour personnaliser ces pages.\nPlanification\nPlanifie la publication des pages.\nExemple :\nLa page sera publiée si la date courante est &gt;= 2023-02-07 :\nschedule:\n  publish: 2023-02-07\nCette page est publiée si la date courante est &lt;= 2022-04-28 :\nschedule:\n  expiry: 2022-04-28\nredirect\nComme son nom l’indique, la variable redirect sert à rediriger une page vers une URL dédiée.\nExemple :\n---\nredirect: \"https:\/\/arnaudligny.fr\"\n---\nLa redirection fonctionne avec le template redirect.html.twig.\nalias\nUn alias est une redirection vers la page courante.\nExemple :\n---\ntitle: \"About\"\nalias:\n  - contact\n---\nDans l’exemple précédent, contact\/ redirige vers about\/.\noutput\nDéfinit le format de sortie de la page.\nLes formats disponibles sont : html, atom, rss, json, xml, etc.\nVous pouvez définir un ou plusieurs formats dans un tableau.\nIl n’est pas obligatoire de définir un format de sortie, mais si vous le faites, il doit correspondre à l’un des formats disponibles définis dans la Configuration.\nExemple :\n---\noutput: [html, atom]\n---\nexternal\nUne page avec une variable external tente de récupérer le contenu de la ressource ciblée.\nExemple :\n---\nexternal: \"https:\/\/raw.githubusercontent.com\/Cecilapp\/Cecil\/main\/README.md\"\n---\nexcluded\nDéfinissez excluded à true pour masquer une page des pages de liste (c.-à-d. : Home page, Section, Sitemap, etc.).\nExemple :\n---\nexcluded: true\n---\nexcluded est différent de published : une page exclue est publiée, mais masquée des pages de liste.\nDepuis la version 8.49.0, l’ancienne variable exclude a été remplacée par excluded.",
      "content_html": "<h1>Front matter</h1>\n<p>Le <em>front matter</em> peut contenir des variables personnalisées appliquées à la page courante.</p>\n<p>Il doit se trouver au tout début du fichier et être un <a href=\"https://en.wikipedia.org/wiki/YAML\" target=\"_blank\" rel=\"noopener noreferrer\">YAML</a> valide.</p>\n<h2 id=\"variables-predefinies\">Variables prédéfinies</h2>\n<table>\n<thead>\n<tr>\n<th>Variable</th>\n<th>Description</th>\n<th>Valeur par défaut</th>\n<th>Exemple</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">title</code></td>\n<td>Titre</td>\n<td>Nom de fichier sans extension.</td>\n<td><code translate=\"no\">Post 1</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">layout</code></td>\n<td>Template</td>\n<td>Voir <a href=\"../templates/1-lookup-rules.fr.md#regles-de-recherche\"><em>Lookup rules</em></a>.</td>\n<td><code translate=\"no\">404</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">date</code></td>\n<td>Date de création</td>\n<td>Date de création du fichier (objet PHP <em>DateTime</em>).</td>\n<td><code translate=\"no\">2019/04/15</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">section</code></td>\n<td>Section</td>\n<td><em>Section</em> de la page.</td>\n<td><code translate=\"no\">blog</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">path</code></td>\n<td>Chemin</td>\n<td><em>Path</em> de la page.</td>\n<td><code translate=\"no\">blog/post-1</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">slug</code></td>\n<td>Slug</td>\n<td><em>Slug</em> de la page.</td>\n<td><code translate=\"no\">post-1</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">published</code></td>\n<td>Publié ou non</td>\n<td><code translate=\"no\">true</code>.</td>\n<td><code translate=\"no\">false</code></td>\n</tr>\n<tr>\n<td><code translate=\"no\">draft</code></td>\n<td>Brouillon ou non</td>\n<td><code translate=\"no\">false</code>.</td>\n<td><code translate=\"no\">true</code></td>\n</tr>\n</tbody>\n</table>\n<aside class=\"note note-info\"><p>Toutes les variables prédéfinies peuvent être surchargées, sauf <code translate=\"no\">section</code>.</p></aside>\n<h2 id=\"updated\">updated</h2>\n<p>La variable <code translate=\"no\">updated</code> sert à définir la date de dernière modification d’une page.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">updated:</span> <span class=\"hljs-number\">2026</span><span class=\"hljs-number\">-02</span><span class=\"hljs-number\">-02</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<aside class=\"note note-warning\"><p>Avant la version 8.80.1, la variable <code translate=\"no\">updated</code> était une variable prédéfinie. Elle est désormais optionnelle (et doit être définie dans le front matter pour être utilisée).</p></aside>\n<h2 id=\"menu\">menu</h2>\n<p>Une page peut être ajoutée à un <a href=\"../configuration/1-site.fr.md#menus\">menu</a>.</p>\n<p>Le nom de l’entrée est le <code translate=\"no\">title</code> de la page et l’URL est le <code translate=\"no\">path</code> de la page.</p>\n<p>La même page peut être ajoutée à plusieurs menus, et la position de chaque entrée peut être définie avec la clé <code translate=\"no\">weight</code> (la plus faible en premier). La clé <code translate=\"no\">name</code> peut être utilisée pour personnaliser le nom de l’entrée par menu.</p>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">menu:</span> <span class=\"hljs-string\">main</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">menu:</span> <span class=\"hljs-string\">[main,</span> <span class=\"hljs-string\">navigation]</span> <span class=\"hljs-comment\"># same page in multiple menus</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">menu:</span>\n  <span class=\"hljs-attr\">main:</span>\n    <span class=\"hljs-attr\">weight:</span> <span class=\"hljs-number\">10</span>\n  <span class=\"hljs-attr\">navigation:</span>\n    <span class=\"hljs-attr\">weight:</span> <span class=\"hljs-number\">20</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">'Notre expertise'</span>\n<span class=\"hljs-attr\">menu:</span>\n  <span class=\"hljs-attr\">main:</span>\n    <span class=\"hljs-attr\">weight:</span> <span class=\"hljs-number\">15</span>\n  <span class=\"hljs-attr\">footer:</span>\n    <span class=\"hljs-attr\">weight:</span> <span class=\"hljs-number\">15</span>\n    <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">\"Expertise\"</span> <span class=\"hljs-comment\"># personnalise le nom de l'entrée dans ce menu</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<h2 id=\"taxonomie\">Taxonomie</h2>\n<p>La taxonomie permet de connecter, relier et classer le contenu de votre site Web.<br>\nDans Cecil, ces termes sont regroupés dans des vocabulaires.</p>\n<p>Les vocabulaires sont déclarés dans la <a href=\"../configuration/1-site.fr.md#taxonomies\"><em>Configuration</em></a>.</p>\n<dl>\n<dt>Vocabulaire</dt>\n<dd>Une catégorisation du contenu (ex. : <code translate=\"no\">tags</code>, <code translate=\"no\">categories</code>, etc.).</dd>\n<dt>Terme</dt>\n<dd>Un terme est un élément d’un vocabulaire (ex. : <code translate=\"no\">Développement</code>, <code translate=\"no\">PHP</code>, etc.).</dd>\n</dl>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">tags:</span> <span class=\"hljs-string\">[\"Développement\",</span> <span class=\"hljs-string\">\"PHP\"</span><span class=\"hljs-string\">]</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<p>Cecil génère ensuite, pour chaque vocabulaire :</p>\n<ul>\n<li>une page listant ses termes, ex. : <code translate=\"no\">/tags/</code></li>\n<li>une page par terme listant ses pages, ex. : <code translate=\"no\">/tags/developpement/</code> et <code translate=\"no\">/tags/php/</code></li>\n</ul>\n<p>Voir les <a href=\"../templates/1-lookup-rules.fr.md#type-vocabulary\">règles de recherche des templates</a> et les <a href=\"../templates/2-variables.fr.md#taxonomie\">variables de taxonomie</a> pour personnaliser ces pages.</p>\n<h2 id=\"planification\">Planification</h2>\n<p>Planifie la publication des pages.</p>\n<p><em>Exemple :</em></p>\n<p>La page sera publiée si la date courante est &gt;= 2023-02-07 :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">schedule:</span>\n  <span class=\"hljs-attr\">publish:</span> <span class=\"hljs-number\">2023</span><span class=\"hljs-number\">-02</span><span class=\"hljs-number\">-07</span></code></pre>\n<p>Cette page est publiée si la date courante est &lt;= 2022-04-28 :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">schedule:</span>\n  <span class=\"hljs-attr\">expiry:</span> <span class=\"hljs-number\">2022</span><span class=\"hljs-number\">-04</span><span class=\"hljs-number\">-28</span></code></pre>\n<h2 id=\"redirect\">redirect</h2>\n<p>Comme son nom l’indique, la variable <code translate=\"no\">redirect</code> sert à rediriger une page vers une URL dédiée.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">redirect:</span> <span class=\"hljs-string\">\"https://arnaudligny.fr\"</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<aside class=\"note note-info\"><p>La redirection fonctionne avec le template <a href=\"https://github.com/Cecilapp/Cecil/blob/main/resources/layouts/_default/redirect.html.twig\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">redirect.html.twig</code></a>.</p></aside>\n<h2 id=\"alias\">alias</h2>\n<p>Un alias est une redirection vers la page courante.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">\"About\"</span>\n<span class=\"hljs-attr\">alias:</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">contact</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<p>Dans l’exemple précédent, <code translate=\"no\">contact/</code> redirige vers <code translate=\"no\">about/</code>.</p>\n<h2 id=\"output\">output</h2>\n<p>Définit le format de sortie de la page.</p>\n<p>Les formats disponibles sont : <code translate=\"no\">html</code>, <code translate=\"no\">atom</code>, <code translate=\"no\">rss</code>, <code translate=\"no\">json</code>, <code translate=\"no\">xml</code>, etc.<br>\nVous pouvez définir un ou plusieurs formats dans un tableau.</p>\n<p>Il n’est pas obligatoire de définir un format de sortie, mais si vous le faites, il doit correspondre à l’un des formats disponibles définis dans la <a href=\"../configuration/8-output.fr.md#output-formats\"><em>Configuration</em></a>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">output:</span> <span class=\"hljs-string\">[html,</span> <span class=\"hljs-string\">atom]</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<h2 id=\"external\">external</h2>\n<p>Une page avec une variable <code translate=\"no\">external</code> tente de récupérer le contenu de la ressource ciblée.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">external:</span> <span class=\"hljs-string\">\"https://raw.githubusercontent.com/Cecilapp/Cecil/main/README.md\"</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<h2 id=\"excluded\">excluded</h2>\n<p>Définissez <code translate=\"no\">excluded</code> à <code translate=\"no\">true</code> pour masquer une page des pages de liste (c.-à-d. : <em>Home page</em>, <em>Section</em>, <em>Sitemap</em>, etc.).</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">excluded:</span> <span class=\"hljs-literal\">true</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<aside class=\"note note-info\"><p><code translate=\"no\">excluded</code> est différent de <a href=\"#variables-predefinies\"><code translate=\"no\">published</code></a> : une page exclue est publiée, mais masquée des pages de liste.</p></aside>\n<aside class=\"note note-warning\"><p>Depuis la version 8.49.0, l’ancienne variable <code translate=\"no\">exclude</code> a été remplacée par <code translate=\"no\">excluded</code>.</p></aside>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/deployer/deploiement-continu/",
      "url": "https://cecil-945.pages.dev/fr/documentation/deployer/deploiement-continu/",
      "title": "Build et déploiement continus",
      "summary": "GitHub Pages et GitLab CI.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Build et déploiement continus\nLes services d’intégration continue peuvent construire votre site avec Cecil et le déployer à chaque modification de votre dépôt.\nGitHub Pages\n\nDes sites web pour vous et vos projets, hébergés directement depuis votre dépôt GitHub. Il suffit de modifier, pousser, et vos changements sont en ligne.\n\n➡️ https:\/\/pages.github.com\n.github\/workflows\/build-and-deploy.yml:\nname: Build and deploy to GitHub Pages\non:\n  push:\n    branches: [master, main]\n  workflow_dispatch:\nconcurrency:\n  group: pages\n  cancel-in-progress: true\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout source\n        uses: actions\/checkout@v6\n      - name: Restore Cecil cache\n        uses: actions\/cache\/restore@v5\n        with:\n          path: .\/.cache\n          key: cecil-cache-\n          restore-keys: |\n            cecil-cache-\n      - name: Build site\n        uses: Cecilapp\/Cecil-Action@v4\n      - name: Save Cecil cache\n        uses: actions\/cache\/save@v5\n        with:\n          path: .\/.cache\n          key: cecil-cache-${{ hashFiles('.\/.cache\/**\/*') }}\n  deploy:\n    needs: build\n    permissions:\n      pages: write\n      id-token: write\n    environment:\n      name: github-pages\n      url: ${{ steps.deployment.outputs.page_url }}\n    runs-on: ubuntu-latest\n    steps:\n      - name: Deploy to GitHub Pages\n        id: deployment\n        uses: actions\/deploy-pages@v5\nDocumentation officielle\nGitLab CI\n\nAvec GitLab Pages, vous pouvez publier des sites web statiques directement depuis un dépôt GitLab.\n\n➡️ https:\/\/about.gitlab.com\/solutions\/continuous-integration\/\n.gitlab-ci.yml:\nimage: wordpress:cli-php8.4\ntest:\n  stage: test\n  variables:\n    CECIL_OUTPUT_DIR: test\n  script:\n    - curl -sSOL https:\/\/cecil.app\/build.sh &amp;&amp; bash .\/build.sh\n  artifacts:\n    paths:\n     - test\n  except:\n   - master\npages:\n  stage: deploy\n  variables:\n    CECIL_ENV: production\n    CECIL_OUTPUT_DIR: public\n  script:\n    - curl -sSOL https:\/\/cecil.app\/build.sh &amp;&amp; bash .\/build.sh\n  artifacts:\n    paths:\n      - public\n  only:\n    - master\ncache:\n  paths:\n    - composer-cache\/\n    - vendor\/\n    - .cache\/\nDocumentation officielle",
      "content_html": "<h1>Build et déploiement continus</h1>\n<p>Les services d’intégration continue peuvent construire votre site avec Cecil et le déployer à chaque modification de votre dépôt.</p>\n<h2 id=\"github-pages\">GitHub Pages</h2>\n<blockquote>\n<p>Des sites web pour vous et vos projets, hébergés directement depuis votre dépôt GitHub. Il suffit de modifier, pousser, et vos changements sont en ligne.</p>\n</blockquote>\n<p>➡️ <a href=\"https://pages.github.com\" target=\"_blank\" rel=\"noopener noreferrer\">https://pages.github.com</a></p>\n<p><em>.github/workflows/build-and-deploy.yml</em>:</p>\n<pre><code class=\"language-yml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Build</span> <span class=\"hljs-string\">and</span> <span class=\"hljs-string\">deploy</span> <span class=\"hljs-string\">to</span> <span class=\"hljs-string\">GitHub</span> <span class=\"hljs-string\">Pages</span>\n<span class=\"hljs-attr\">on:</span>\n  <span class=\"hljs-attr\">push:</span>\n    <span class=\"hljs-attr\">branches:</span> <span class=\"hljs-string\">[master,</span> <span class=\"hljs-string\">main]</span>\n  <span class=\"hljs-attr\">workflow_dispatch:</span>\n<span class=\"hljs-attr\">concurrency:</span>\n  <span class=\"hljs-attr\">group:</span> <span class=\"hljs-string\">pages</span>\n  <span class=\"hljs-attr\">cancel-in-progress:</span> <span class=\"hljs-literal\">true</span>\n<span class=\"hljs-attr\">jobs:</span>\n  <span class=\"hljs-attr\">build:</span>\n    <span class=\"hljs-attr\">runs-on:</span> <span class=\"hljs-string\">ubuntu-latest</span>\n    <span class=\"hljs-attr\">steps:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Checkout</span> <span class=\"hljs-string\">source</span>\n        <span class=\"hljs-attr\">uses:</span> <span class=\"hljs-string\">actions/checkout@v6</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Restore</span> <span class=\"hljs-string\">Cecil</span> <span class=\"hljs-string\">cache</span>\n        <span class=\"hljs-attr\">uses:</span> <span class=\"hljs-string\">actions/cache/restore@v5</span>\n        <span class=\"hljs-attr\">with:</span>\n          <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">./.cache</span>\n          <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">cecil-cache-</span>\n          <span class=\"hljs-attr\">restore-keys:</span> <span class=\"hljs-string\">|\n            cecil-cache-\n</span>      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Build</span> <span class=\"hljs-string\">site</span>\n        <span class=\"hljs-attr\">uses:</span> <span class=\"hljs-string\">Cecilapp/Cecil-Action@v4</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Save</span> <span class=\"hljs-string\">Cecil</span> <span class=\"hljs-string\">cache</span>\n        <span class=\"hljs-attr\">uses:</span> <span class=\"hljs-string\">actions/cache/save@v5</span>\n        <span class=\"hljs-attr\">with:</span>\n          <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">./.cache</span>\n          <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">cecil-cache-${{</span> <span class=\"hljs-string\">hashFiles('./.cache/**/*')</span> <span class=\"hljs-string\">}}</span>\n  <span class=\"hljs-attr\">deploy:</span>\n    <span class=\"hljs-attr\">needs:</span> <span class=\"hljs-string\">build</span>\n    <span class=\"hljs-attr\">permissions:</span>\n      <span class=\"hljs-attr\">pages:</span> <span class=\"hljs-string\">write</span>\n      <span class=\"hljs-attr\">id-token:</span> <span class=\"hljs-string\">write</span>\n    <span class=\"hljs-attr\">environment:</span>\n      <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">github-pages</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">${{</span> <span class=\"hljs-string\">steps.deployment.outputs.page_url</span> <span class=\"hljs-string\">}}</span>\n    <span class=\"hljs-attr\">runs-on:</span> <span class=\"hljs-string\">ubuntu-latest</span>\n    <span class=\"hljs-attr\">steps:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Deploy</span> <span class=\"hljs-string\">to</span> <span class=\"hljs-string\">GitHub</span> <span class=\"hljs-string\">Pages</span>\n        <span class=\"hljs-attr\">id:</span> <span class=\"hljs-string\">deployment</span>\n        <span class=\"hljs-attr\">uses:</span> <span class=\"hljs-string\">actions/deploy-pages@v5</span></code></pre>\n<p><a href=\"https://docs.github.com/en/pages\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation officielle</a></p>\n<h2 id=\"gitlab-ci\">GitLab CI</h2>\n<blockquote>\n<p>Avec GitLab Pages, vous pouvez publier des sites web statiques directement depuis un dépôt GitLab.</p>\n</blockquote>\n<p>➡️ <a href=\"https://about.gitlab.com/solutions/continuous-integration/\" target=\"_blank\" rel=\"noopener noreferrer\">https://about.gitlab.com/solutions/continuous-integration/</a></p>\n<p><em>.gitlab-ci.yml</em>:</p>\n<pre><code class=\"language-yml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">image:</span> <span class=\"hljs-string\">wordpress:cli-php8.4</span>\n<span class=\"hljs-attr\">test:</span>\n  <span class=\"hljs-attr\">stage:</span> <span class=\"hljs-string\">test</span>\n  <span class=\"hljs-attr\">variables:</span>\n    <span class=\"hljs-attr\">CECIL_OUTPUT_DIR:</span> <span class=\"hljs-string\">test</span>\n  <span class=\"hljs-attr\">script:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">curl</span> <span class=\"hljs-string\">-sSOL</span> <span class=\"hljs-string\">https://cecil.app/build.sh</span> <span class=\"hljs-string\">&amp;&amp;</span> <span class=\"hljs-string\">bash</span> <span class=\"hljs-string\">./build.sh</span>\n  <span class=\"hljs-attr\">artifacts:</span>\n    <span class=\"hljs-attr\">paths:</span>\n     <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">test</span>\n  <span class=\"hljs-attr\">except:</span>\n   <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">master</span>\n<span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">stage:</span> <span class=\"hljs-string\">deploy</span>\n  <span class=\"hljs-attr\">variables:</span>\n    <span class=\"hljs-attr\">CECIL_ENV:</span> <span class=\"hljs-string\">production</span>\n    <span class=\"hljs-attr\">CECIL_OUTPUT_DIR:</span> <span class=\"hljs-string\">public</span>\n  <span class=\"hljs-attr\">script:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">curl</span> <span class=\"hljs-string\">-sSOL</span> <span class=\"hljs-string\">https://cecil.app/build.sh</span> <span class=\"hljs-string\">&amp;&amp;</span> <span class=\"hljs-string\">bash</span> <span class=\"hljs-string\">./build.sh</span>\n  <span class=\"hljs-attr\">artifacts:</span>\n    <span class=\"hljs-attr\">paths:</span>\n      <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">public</span>\n  <span class=\"hljs-attr\">only:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">master</span>\n<span class=\"hljs-attr\">cache:</span>\n  <span class=\"hljs-attr\">paths:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">composer-cache/</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">vendor/</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-string\">.cache/</span></code></pre>\n<p><a href=\"https://about.gitlab.com/stages-devops-lifecycle/continuous-integration/\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation officielle</a></p>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/developpeurs/bibliotheque/",
      "url": "https://cecil-945.pages.dev/fr/documentation/developpeurs/bibliotheque/",
      "title": "Bibliothèque",
      "summary": "Utilisez Cecil comme bibliothèque PHP : installez-le avec Composer, puis générez et diagnostiquez par programmation.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-03T00:00:00+00:00","content_text": "Bibliothèque\nCecil propose une API PHP simple pour générer votre site web.\nVous pouvez consulter la documentation de l'API pour plus de détails.\nInstallation\ncomposer require cecil\/cecil\nSupport de libvips\nPour traiter les images avec libvips (optionnel), installez le driver libvips dans votre projet :\ncomposer require intervention\/image-driver-vips\nCe driver nécessite libvips installé sur le système et l’extension PHP FFI activée.\nSans lui, Cecil utilise Imagick ou GD à la place.\nUtilisation\nConstruction\nConstruisez un nouveau site web avec une configuration personnalisée :\nrequire_once 'vendor\/autoload.php';\n\nuse Cecil\\Builder;\n\n$config = [\n    'title'   =&gt; \"My website\",\n    'baseurl' =&gt; 'https:\/\/domain.tld\/',\n];\n\nBuilder::create($config)-&gt;build();\n\nexec('php -S localhost:8000 -t _site'); \/\/ prévisualisation locale\nLe paramètre principal de la méthode create doit être un array PHP ou une instance de Cecil\\Config.\nDiagnostic\nVous pouvez aussi exécuter les vérifications doctor via des services de domaine dédiés, sans utiliser les commandes CLI.\n&lt;?php\n\nrequire_once 'vendor\/autoload.php';\n\nuse Cecil\\Builder;\nuse Cecil\\Doctor\\SeoDoctor;\nuse Cecil\\Doctor\\SiteDoctor;\n\n$builder = Builder::create(require 'config.php')\n    -&gt;setSourceDir(__DIR__)\n    -&gt;setDestinationDir(__DIR__);\n\n$siteDoctor = new SiteDoctor();\n$diagnosis = $siteDoctor-&gt;diagnose($builder, __DIR__, ['cecil.yml']);\n\n$seoDoctor = new SeoDoctor();\n$seoAudit = $seoDoctor-&gt;audit($builder, [\n    'page' =&gt; '',\n    'include_virtual' =&gt; false,\n]);\n\nvar_dump($diagnosis['errors'], $seoAudit['summary']);",
      "content_html": "<h1>Bibliothèque</h1>\n<p>Cecil propose une API PHP simple pour générer votre site web.</p>\n<p>Vous pouvez consulter la <a href=\"https://cecil.app/documentation/library/api/namespaces/cecil.html\" target=\"_blank\" rel=\"noopener noreferrer\">documentation de l'API</a> pour plus de détails.</p>\n<h2 id=\"installation\">Installation</h2>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">composer require cecil/cecil</code></pre>\n<h3 id=\"support-de-libvips\">Support de libvips</h3>\n<p>Pour traiter les images avec <a href=\"https://www.libvips.org/\" target=\"_blank\" rel=\"noopener noreferrer\">libvips</a> (optionnel), installez le driver libvips dans votre projet :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">composer require intervention/image-driver-vips</code></pre>\n<aside class=\"note note-important\"><p>Ce driver nécessite <a href=\"https://www.libvips.org/install.html\" target=\"_blank\" rel=\"noopener noreferrer\">libvips</a> installé sur le système et l’extension PHP <a href=\"https://www.php.net/manual/book.ffi.php\" target=\"_blank\" rel=\"noopener noreferrer\">FFI</a> activée.<br>\nSans lui, Cecil utilise <a href=\"https://www.php.net/manual/book.imagick.php\" target=\"_blank\" rel=\"noopener noreferrer\">Imagick</a> ou <a href=\"https://www.php.net/manual/book.image.php\" target=\"_blank\" rel=\"noopener noreferrer\">GD</a> à la place.</p></aside>\n<h2 id=\"utilisation\">Utilisation</h2>\n<h3 id=\"construction\">Construction</h3>\n<p>Construisez un nouveau site web avec une configuration personnalisée :</p>\n<pre><code class=\"language-php hljs php\" translate=\"no\"><span class=\"hljs-keyword\">require_once</span> <span class=\"hljs-string\">'vendor/autoload.php'</span>;\n\n<span class=\"hljs-keyword\">use</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Builder</span>;\n\n$config = [\n    <span class=\"hljs-string\">'title'</span>   =&gt; <span class=\"hljs-string\">\"My website\"</span>,\n    <span class=\"hljs-string\">'baseurl'</span> =&gt; <span class=\"hljs-string\">'https://domain.tld/'</span>,\n];\n\nBuilder::create($config)-&gt;build();\n\nexec(<span class=\"hljs-string\">'php -S localhost:8000 -t _site'</span>); <span class=\"hljs-comment\">// prévisualisation locale</span></code></pre>\n<aside class=\"note note-info\"><p>Le paramètre principal de la méthode <code translate=\"no\">create</code> doit être un <code translate=\"no\">array</code> PHP ou une instance de <a href=\"https://github.com/Cecilapp/Cecil/blob/main/src/Config.php\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">Cecil\\Config</code></a>.</p></aside>\n<h3 id=\"diagnostic\">Diagnostic</h3>\n<p>Vous pouvez aussi exécuter les vérifications doctor via des services de domaine dédiés, sans utiliser les commandes CLI.</p>\n<pre><code class=\"language-php hljs php\" translate=\"no\"><span class=\"hljs-meta\">&lt;?php</span>\n\n<span class=\"hljs-keyword\">require_once</span> <span class=\"hljs-string\">'vendor/autoload.php'</span>;\n\n<span class=\"hljs-keyword\">use</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Builder</span>;\n<span class=\"hljs-keyword\">use</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Doctor</span>\\<span class=\"hljs-title\">SeoDoctor</span>;\n<span class=\"hljs-keyword\">use</span> <span class=\"hljs-title\">Cecil</span>\\<span class=\"hljs-title\">Doctor</span>\\<span class=\"hljs-title\">SiteDoctor</span>;\n\n$builder = Builder::create(<span class=\"hljs-keyword\">require</span> <span class=\"hljs-string\">'config.php'</span>)\n    -&gt;setSourceDir(<span class=\"hljs-keyword\">__DIR__</span>)\n    -&gt;setDestinationDir(<span class=\"hljs-keyword\">__DIR__</span>);\n\n$siteDoctor = <span class=\"hljs-keyword\">new</span> SiteDoctor();\n$diagnosis = $siteDoctor-&gt;diagnose($builder, <span class=\"hljs-keyword\">__DIR__</span>, [<span class=\"hljs-string\">'cecil.yml'</span>]);\n\n$seoDoctor = <span class=\"hljs-keyword\">new</span> SeoDoctor();\n$seoAudit = $seoDoctor-&gt;audit($builder, [\n    <span class=\"hljs-string\">'page'</span> =&gt; <span class=\"hljs-string\">''</span>,\n    <span class=\"hljs-string\">'include_virtual'</span> =&gt; <span class=\"hljs-keyword\">false</span>,\n]);\n\nvar_dump($diagnosis[<span class=\"hljs-string\">'errors'</span>], $seoAudit[<span class=\"hljs-string\">'summary'</span>]);</code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/commandes/serve/",
      "url": "https://cecil-945.pages.dev/fr/documentation/commandes/serve/",
      "title": "serve",
      "summary": "Prévisualiser le site avec le serveur intégré.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "serve\nConstruit et sert le site en local.\nLe serveur web est conçu pour faciliter les tests d’un site. Il n’a pas vocation à être un serveur web complet et ne doit pas être utilisé sur un réseau public.\nUtilisation\nDescription:\n  Starts the built-in server\n\nUsage:\n  serve [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                             Use the given path as working directory\n\nOptions:\n  -o, --open                       Open web browser automatically\n      --host=HOST                  Server host [default: \"localhost\"]\n      --port=PORT                  Server port [default: \"8000\"]\n  -w, --watch|--no-watch           Enable (or disable --no-watch) changes watcher (enabled by default)\n  -i, --incremental                Enable incremental builds (rebuild only changed pages)\n  -d, --drafts                     Include drafts\n      --optimize|--no-optimize     Enable (or disable --no-optimize) optimization of generated files\n  -c, --config=CONFIG              Set the path to extra config files (comma-separated)\n      --clear-cache[=CLEAR-CACHE]  Clear cache before build (optional cache key as regular expression) [default: false]\n  -p, --page=PAGE                  Build a specific page\n      --no-ignore-vcs              Changes watcher must not ignore VCS directories\n  -m, --metrics                    Show build metrics (duration and memory) of each step\n      --timeout=TIMEOUT            Sets the process timeout (max. runtime) in seconds [default: 7200]\n      --notify                     Send desktop notification on server start\n  -b, --background                 Run the server in the background\n  -h, --help                       Display help for the given command. When no command is given display help for the list command\n  -q, --quiet                      Do not output any message\n  -V, --version                    Display this application version\n      --ansi|--no-ansi             Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction             Do not ask any interactive question\n  -v|vv|vvv, --verbose             Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The serve command starts the live-reloading-built-in web server.\n\n    cecil.phar serve\n    cecil.phar serve path\/to\/the\/working\/directory\n    cecil.phar serve --open\n    cecil.phar serve --drafts\n    cecil.phar serve --no-watch\n\n  To speed up local development you can enable incremental builds with the --incremental option.\n  When content pages change, Cecil rebuilds just those pages.\n  When templates change, Cecil rebuilds only pages using those templates (including Twig dependencies such as extends\/include).\n  Any other change (data, config, static or asset file, or file deletion) triggers a full rebuild:\n\n    cecil.phar serve --incremental\n\n  You can use a custom host and port by using the --host and --port options:\n\n    cecil.phar serve --host=127.0.0.1 --port=8080\n\n  To build the website with an extra configuration file, you can use the --config option.\n  This is useful during local development to override some settings without modifying the main configuration:\n\n    cecil.phar serve --config=config\/dev.yml\n\n  To start the server with changes watcher not ignoring VCS directories, run:\n\n    cecil.phar serve --no-ignore-vcs\n\n  To define the process timeout (in seconds), run:\n\n    cecil.phar serve --timeout=7200\n\n  To run the server in the background, run:\n\n    cecil.phar serve --background\n    cecil.phar serve -b\n\n  Then stop it with:\n\n    cecil.phar serve:stop\n\n  In background mode, file changes are not watched automatically.\nserve:background\nAlias de serve --background : démarre le serveur intégré en arrière-plan sans occuper le terminal.\nDescription:\n  Starts the built-in server in the background (alias of `serve --background`)\n\nUsage:\n  serve:background [options] [--] [&lt;path&gt;]\n\nHelp:\n  The serve:background command starts the built-in web server in the background.\n\n    cecil.phar serve:background\n    cecil.phar serve:background path\/to\/the\/working\/directory\n\n  This command is an alias of serve --background.\n\n  Stop the server with:\n\n    cecil.phar serve:stop\nserve:log\nAffiche les logs combinés du serveur et des erreurs, triés par date.\nDescription:\n  Shows combined server and error logs\n\nUsage:\n  serve:log [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                  Use the given path as working directory\n\nOptions:\n  -l, --lines=LINES     Number of entries to display (default: 25)\n\nHelp:\n  The serve:log command displays entries from combined server and error logs, sorted by date.\n\n    cecil.phar serve:log\n    cecil.phar serve:log path\/to\/the\/working\/directory\n    cecil.phar serve:log --lines=100\n    cecil.phar serve:log -l 100\n\n  This command shows logs from `.cecil\/errors.log` and `.cecil\/server.log`.\n  It is useful for debugging issues with your local development server.",
      "content_html": "<h1>serve</h1>\n<p>Construit et sert le site en local.</p>\n<aside class=\"note note-warning\"><p>Le serveur web est conçu pour faciliter les tests d’un site. Il n’a pas vocation à être un serveur web complet et ne doit pas être utilisé sur un réseau public.</p></aside>\n<h2 id=\"utilisation\">Utilisation</h2>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Starts the built-in server\n\nUsage:\n  serve [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                             Use the given path as working directory\n\nOptions:\n  -o, --open                       Open web browser automatically\n      --host=HOST                  Server host [default: \"localhost\"]\n      --port=PORT                  Server port [default: \"8000\"]\n  -w, --watch|--no-watch           Enable (or disable --no-watch) changes watcher (enabled by default)\n  -i, --incremental                Enable incremental builds (rebuild only changed pages)\n  -d, --drafts                     Include drafts\n      --optimize|--no-optimize     Enable (or disable --no-optimize) optimization of generated files\n  -c, --config=CONFIG              Set the path to extra config files (comma-separated)\n      --clear-cache[=CLEAR-CACHE]  Clear cache before build (optional cache key as regular expression) [default: false]\n  -p, --page=PAGE                  Build a specific page\n      --no-ignore-vcs              Changes watcher must not ignore VCS directories\n  -m, --metrics                    Show build metrics (duration and memory) of each step\n      --timeout=TIMEOUT            Sets the process timeout (max. runtime) in seconds [default: 7200]\n      --notify                     Send desktop notification on server start\n  -b, --background                 Run the server in the background\n  -h, --help                       Display help for the given command. When no command is given display help for the list command\n  -q, --quiet                      Do not output any message\n  -V, --version                    Display this application version\n      --ansi|--no-ansi             Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction             Do not ask any interactive question\n  -v|vv|vvv, --verbose             Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The serve command starts the live-reloading-built-in web server.\n\n    cecil.phar serve\n    cecil.phar serve path/to/the/working/directory\n    cecil.phar serve --open\n    cecil.phar serve --drafts\n    cecil.phar serve --no-watch\n\n  To speed up local development you can enable incremental builds with the --incremental option.\n  When content pages change, Cecil rebuilds just those pages.\n  When templates change, Cecil rebuilds only pages using those templates (including Twig dependencies such as extends/include).\n  Any other change (data, config, static or asset file, or file deletion) triggers a full rebuild:\n\n    cecil.phar serve --incremental\n\n  You can use a custom host and port by using the --host and --port options:\n\n    cecil.phar serve --host=127.0.0.1 --port=8080\n\n  To build the website with an extra configuration file, you can use the --config option.\n  This is useful during local development to override some settings without modifying the main configuration:\n\n    cecil.phar serve --config=config/dev.yml\n\n  To start the server with changes watcher not ignoring VCS directories, run:\n\n    cecil.phar serve --no-ignore-vcs\n\n  To define the process timeout (in seconds), run:\n\n    cecil.phar serve --timeout=7200\n\n  To run the server in the background, run:\n\n    cecil.phar serve --background\n    cecil.phar serve -b\n\n  Then stop it with:\n\n    cecil.phar serve:stop\n\n  In background mode, file changes are not watched automatically.</code></pre>\n<h2 id=\"serve-background\">serve:background</h2>\n<p>Alias de <code translate=\"no\">serve --background</code> : démarre le serveur intégré en arrière-plan sans occuper le terminal.</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Starts the built-in server in the background (alias of `serve --background`)\n\nUsage:\n  serve:background [options] [--] [&lt;path&gt;]\n\nHelp:\n  The serve:background command starts the built-in web server in the background.\n\n    cecil.phar serve:background\n    cecil.phar serve:background path/to/the/working/directory\n\n  This command is an alias of serve --background.\n\n  Stop the server with:\n\n    cecil.phar serve:stop</code></pre>\n<h2 id=\"serve-log\">serve:log</h2>\n<p>Affiche les logs combinés du serveur et des erreurs, triés par date.</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Shows combined server and error logs\n\nUsage:\n  serve:log [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                  Use the given path as working directory\n\nOptions:\n  -l, --lines=LINES     Number of entries to display (default: 25)\n\nHelp:\n  The serve:log command displays entries from combined server and error logs, sorted by date.\n\n    cecil.phar serve:log\n    cecil.phar serve:log path/to/the/working/directory\n    cecil.phar serve:log --lines=100\n    cecil.phar serve:log -l 100\n\n  This command shows logs from `.cecil/errors.log` and `.cecil/server.log`.\n  It is useful for debugging issues with your local development server.</code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/contenu/markdown/",
      "url": "https://cecil-945.pages.dev/fr/documentation/contenu/markdown/",
      "title": "Markdown",
      "summary": "Syntaxe et extensions Markdown : attributs, liens, images, table des matières, notes, coloration syntaxique, etc.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-12T00:00:00+00:00","content_text": "Markdown\nCecil prend en charge le format Markdown, ainsi que Markdown Extra.\nCecil fournit aussi des fonctionnalités supplémentaires pour enrichir votre contenu, voir ci-dessous.\nAttributs\nAvec Markdown Extra, vous pouvez définir un id, une classe et des attributs personnalisés sur certains éléments à l’aide d’un bloc d’attributs.\nPar exemple, placez le(s) attribut(s) souhaité(s) après un en-tête, un bloc de code délimité, un lien ou une image en fin de ligne, entre accolades, comme ceci :\n## En-tête {#id .class attribute=value}\nPour un élément en ligne, comme un lien, vous devez utiliser un retour à la ligne après l’accolade fermante :\nLorem ipsum [dolor](url){attribute=value} \nsit amet.\nLiens\nVous pouvez créer un lien avec la syntaxe [Texte](url) ; url peut être un chemin, un chemin relatif vers un fichier Markdown, une URL externe, etc.\nExemple :\n[Link to a path](\/about\/)\n[Link to a Markdown file](\/fr\/a-propos\/)\n[Link to Cecil website](https:\/\/cecil.app)\nUn lien relatif vers un fichier Markdown est résolu depuis le dossier du fichier courant (comme sur GitHub), puis remplacé par l’URL de la page ciblée.\nLien vers une page\nVous pouvez facilement créer un lien vers une page avec la syntaxe [Titre de page](page:page-id).\nExemple :\n[Link to a blog post](page:blog\/post-1)\nExterne\nPar défaut, les liens externes ont la valeur suivante pour l’attribut rel : noopener noreferrer.\nExemple :\n&lt;a href=\"&lt;url&gt;\" rel=\"noopener noreferrer\"&gt;Link to another website&lt;\/a&gt;\nVous pouvez modifier ce comportement avec les options pages.body.links.external.\nLiens intégrés\nVous pouvez laisser Cecil essayer de transformer un lien en contenu embarqué en utilisant l’attribut {embed} ou en activant l’option de configuration globale pages.body.links.embed.enabled à true.\nSeuls les liens YouTube, Vimeo, Dailymotion et GitHub Gists sont pris en charge.\nExemple :\n[CECIL : LE générateur de SITES STATIQUES en PHP](https:\/\/www.youtube.com\/watch?v=ur8koU0iYvc){embed}\n\n\n\nLocal video\/audio files\nCecil peut aussi créer des éléments HTML vidéo et audio, selon l’extension du fichier.\nExemple :\n[Video file](video.mp4){embed controls poster=\/images\/video-test.png}\n[Audio file](song.mp3){embed controls}\nEst converti en :\n&lt;video src=\"\/video.mp4\" controls poster=\"\/images\/video-test.png\" style=\"max-width:100%;height:auto;\"&gt;&lt;\/video&gt;\n&lt;audio src=\"\/song.mp3\" controls&gt;&lt;\/audio&gt;\nAvec {embed=false} (ou lorsque l’intégration est désactivée), un fichier vidéo\/audio local reste un lien, mais son URL pointe vers le fichier publié (avec empreinte si assets.fingerprint est activé).\nImages\nPour ajouter une image, utilisez un point d’exclamation (!) suivi d’une description alternative entre crochets ([]), puis du chemin ou de l’URL de l’image entre parenthèses (()).\nVous pouvez facultativement ajouter un titre entre guillemets.\n![Alternative description](\/image.jpg \"Image title\")\nLe chemin doit être relatif à la racine de votre site Web (ex. : \/image.jpg), mais Cecil est capable de normaliser un chemin relatif aux répertoires assets et static (ex. : ..\/..\/assets\/image.jpg).\nLazy loading\nCecil ajoute l’attribut loading=\"lazy\" à chaque image.\nExemple :\n![](\/image.jpg)\nEst converti en :\n&lt;img src=\"\/image.jpg\" loading=\"lazy\"&gt;\nVous pouvez désactiver ce comportement avec l’attribut {loading=eager} ou avec l’option lazy.\nDecoding\nCecil ajoute l’attribut decoding=\"async\" à chaque image.\nExemple :\n![](\/image.jpg)\nEst converti en :\n&lt;img src=\"\/image.jpg\" decoding=\"async\"&gt;\nVous pouvez désactiver ce comportement avec l’attribut {decoding=auto} ou avec l’option decoding.\nRedimensionnement\nChaque image du body peut être redimensionnée automatiquement en définissant une largeur inférieure à celle d’origine, avec l’attribut additionnel {width=X}.\nExemple :\n![](\/image.jpg){width=800}\nEst converti en :\n&lt;img src=\"\/thumbnails\/800\/image.jpg\" width=\"800\" height=\"600\"&gt;\nLe ratio est conservé (l’attribut height est calculé automatiquement), le fichier original n’est pas modifié et la version redimensionnée est stockée dans \/thumbnails\/&lt;width&gt;\/.\nCette fonctionnalité nécessite une bibliothèque de traitement d’images : Imagick est utilisé en priorité s’il est disponible (et capable de lire le JPEG et le PNG), puis libvips (via l’extension PHP FFI), et enfin GD en dernier recours ; sinon, elle ajoute seulement un attribut HTML width à la balise img.\nLe support de libvips est optionnel et n’est pas inclus dans cecil.phar. Pour l’utiliser, Cecil doit être installé avec Composer et il faut :\n\nlibvips installé sur le système\nl’extension PHP FFI activée\nle paquet intervention\/image-driver-vips installé avec Cecil\n\nSi Cecil est une dépendance de votre projet (voir Bibliothèque) :\ncomposer require intervention\/image-driver-vips\nSi Cecil est installé globalement :\ncomposer global require cecil\/cecil intervention\/image-driver-vips\nFormats\nSi l’option formats est définie, des images alternatives sont créées et ajoutées.\nExemple :\n![](\/image.jpg)\nPeut être converti en :\n&lt;picture&gt;\n  &lt;source srcset=\"\/image.avif\" type=\"image\/avif\"&gt;\n  &lt;source srcset=\"\/image.webp\" type=\"image\/webp\"&gt;\n  &lt;img src=\"\/image.jpg\"&gt;\n&lt;\/picture&gt;\nVeuillez noter que tous les formats d’image ne sont pas toujours inclus dans les extensions d’image PHP.\nResponsive\nSi l’option responsive est activée, alors toutes les images du body seront automatiquement rendues « responsive ».\nExemple :\n![](\/image.jpg){width=800}\nsera converti en :\n&lt;img src=\"\/thumbnails\/800\/image.jpg\" width=\"800\" height=\"600\"\n  srcset=\"\/thumbnails\/320\/image.jpg 320w,\n          \/thumbnails\/640\/image.jpg 640w,\n          \/thumbnails\/800\/image.jpg 800w\"\n  sizes=\"100vw\"\n&gt;\nComme une image du body est convertie en Asset, les différentes largeurs doivent être définies dans la configuration des assets.\nL’attribut sizes prend la valeur de l’option de configuration assets.images.responsive.sizes.default, mais peut être modifié en créant une nouvelle entrée nommée d’après une class ajoutée à l’image.\nExemple :\nassets:\n  images:\n    responsive:\n      sizes:\n        default: 100vw\n        my_class: \"(max-width: 800px) 768px, 1024px\"\n![](\/image.jpg){.my_class}\nVous pouvez combiner les options formats et responsive.\nCSS class\nVous pouvez définir une valeur par défaut pour l’attribut class de chaque image avec l’option class.\nCaption\nLe titre optionnel peut être utilisé pour créer automatiquement une légende (figcaption) en activant l’option caption.\nExemple :\n![](\/images\/img.jpg \"Title\")\nEst converti en :\n&lt;figure&gt;\n  &lt;img src=\"\/image.jpg\" title=\"Title\"&gt;\n  &lt;figcaption&gt;Title&lt;\/figcaption&gt;\n&lt;\/figure&gt;\nLa légende prend en charge le contenu Markdown.\nImage localisée\nPour les pages traduites, Cecil recherche d’abord un fichier suffixé par la langue lors de la résolution des chemins d’image Markdown.\nExemple :\n![](\/images\/cecil-logo.png)\nAvec une page française (fr), Cecil essaie d’abord \/images\/cecil-logo.fr.png, puis revient à \/images\/cecil-logo.png.\nPlaceholder\nComme les images sont généralement des ressources plus lourdes et plus lentes, et qu’elles ne bloquent pas le rendu, il est préférable de donner aux utilisateurs quelque chose à voir pendant qu’ils attendent leur chargement.\nL’attribut placeholder accepte 2 options :\n\ncolor: affiche un fond coloré (basé sur la couleur dominante de l’image)\nlqip: Low-Quality Image Placeholder\n\nExemples :\n![](\/images\/img.jpg){placeholder=color}\n![](\/images\/img.jpg){placeholder=lqip}\nVous pouvez définir une valeur pour l’attribut placeholder de chaque image avec l’option placeholder.\nL’option lqip n’est pas compatible avec les GIF animés.\nTable des matières\nVous pouvez ajouter une table des matières avec la syntaxe Markdown suivante :\n[toc]\nPar défaut, la ToC extrait les en-têtes H2 et H3. Vous pouvez modifier ce comportement avec les options de body.\nExtrait\nUn extrait peut être défini dans le body avec l’une des balises suivantes : excerpt ou break.\nExemple :\nIntroduction.\n&lt;!-- excerpt --&gt;\nMain content.\nUtilisez ensuite le filtre excerpt_html dans votre template.\nNotes\nCréez un bloc de Note (info, astuce, important, etc.).\nExemple :\n:::tip\n**Tip:** This is advice.\n:::\nEst converti en :\n&lt;aside class=\"note note-tip\"&gt;\n  &lt;p&gt;\n    &lt;strong&gt;Tip:&lt;\/strong&gt; This is advice.\n  &lt;\/p&gt;\n&lt;\/aside&gt;\nTip: This is advice.\nAutres exemples :\nempty\ninfo\ntip\nimportant\nwarning\ncaution\nColoration syntaxique\nLa coloration syntaxique des blocs de code est activée par défaut avec l’option pages.body.highlight.\nSi besoin, vous pouvez la désactiver avec :\npages:\n  body:\n    highlight: false\nExemple :\n\n```php\necho \"Hello world\";\n```\n\nEst rendu en :\necho \"Hello world\";\nVous pouvez personnaliser le style de coloration syntaxique en créant votre propre thème. Consultez le guide des thèmes de Highlight.js.\nTexte inséré\nReprésente une plage de texte qui a été ajoutée.\n++text++\nEst converti en :\n&lt;ins&gt;text&lt;\/ins&gt;",
      "content_html": "<h1>Markdown</h1>\n<p>Cecil prend en charge le format <a href=\"http://daringfireball.net/projects/markdown/syntax\" target=\"_blank\" rel=\"noopener noreferrer\">Markdown</a>, ainsi que <a href=\"https://michelf.ca/projects/php-markdown/extra/\" target=\"_blank\" rel=\"noopener noreferrer\">Markdown Extra</a>.</p>\n<p>Cecil fournit aussi des <strong>fonctionnalités supplémentaires</strong> pour enrichir votre contenu, voir ci-dessous.</p>\n<h2 id=\"attributs\">Attributs</h2>\n<p>Avec <a href=\"https://michelf.ca/projects/php-markdown/extra/\" target=\"_blank\" rel=\"noopener noreferrer\">Markdown Extra</a>, vous pouvez définir un id, une classe et des attributs personnalisés sur certains éléments à l’aide d’un bloc d’attributs.<br>\nPar exemple, placez le(s) attribut(s) souhaité(s) après un en-tête, un bloc de code délimité, un lien ou une image en fin de ligne, entre accolades, comme ceci :</p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\"><span class=\"hljs-section\">## En-tête {#id .class attribute=value}</span></code></pre>\n<aside class=\"note note-warning\"><p>Pour un élément en ligne, comme un lien, vous devez utiliser un retour à la ligne après l’accolade fermante :</p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">Lorem ipsum [<span class=\"hljs-string\">dolor</span>](<span class=\"hljs-link\">url</span>){attribute=value} \nsit amet.</code></pre></aside>\n<h2 id=\"liens\">Liens</h2>\n<p>Vous pouvez créer un lien avec la syntaxe <code translate=\"no\">[Texte](url)</code> ; <code translate=\"no\">url</code> peut être un chemin, un chemin relatif vers un fichier Markdown, une URL externe, etc.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">[<span class=\"hljs-string\">Link to a path</span>](<span class=\"hljs-link\">/about/</span>)\n[<span class=\"hljs-string\">Link to a Markdown file</span>](<span class=\"hljs-link\">/fr/a-propos/</span>)\n[<span class=\"hljs-string\">Link to Cecil website</span>](<span class=\"hljs-link\">https://cecil.app</span>)</code></pre>\n<aside class=\"note note-info\"><p>Un lien relatif vers un fichier Markdown est résolu depuis le dossier du fichier courant (comme sur GitHub), puis remplacé par l’URL de la page ciblée.</p></aside>\n<h3 id=\"lien-vers-une-page\">Lien vers une page</h3>\n<p>Vous pouvez facilement créer un lien vers une page avec la syntaxe <code translate=\"no\">[Titre de page](page:page-id)</code>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">[<span class=\"hljs-string\">Link to a blog post</span>](<span class=\"hljs-link\">page:blog/post-1</span>)</code></pre>\n<h3 id=\"externe\">Externe</h3>\n<p>Par défaut, les liens externes ont la valeur suivante pour l’attribut <code translate=\"no\">rel</code> : <code translate=\"no\">noopener noreferrer</code>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"&lt;url&gt;\"</span> <span class=\"hljs-attr\">rel</span>=<span class=\"hljs-string\">\"noopener noreferrer\"</span>&gt;</span>Link to another website<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span></code></pre>\n<p>Vous pouvez modifier ce comportement avec les <a href=\"../configuration/4-pages.fr.md#pages-body-links\">options <code translate=\"no\">pages.body.links.external</code></a>.</p>\n<h3 id=\"liens-integres\">Liens intégrés</h3>\n<p>Vous pouvez laisser Cecil essayer de transformer un lien en contenu embarqué en utilisant l’attribut <code translate=\"no\">{embed}</code> ou en activant l’option de configuration globale <code translate=\"no\">pages.body.links.embed.enabled</code> à <code translate=\"no\">true</code>.</p>\n<aside class=\"note note-important\"><p>Seuls les liens <strong>YouTube</strong>, <strong>Vimeo</strong>, <strong>Dailymotion</strong> et <strong>GitHub Gists</strong> sont pris en charge.</p></aside>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">[<span class=\"hljs-string\">CECIL : LE générateur de SITES STATIQUES en PHP</span>](<span class=\"hljs-link\">https://www.youtube.com/watch?v=ur8koU0iYvc</span>){embed}</code></pre>\n<p><div style=\"position:relative;padding-bottom:56.25%;height:0;overflow:hidden;\">\n<iframe src=\"https://www.youtube-nocookie.com/embed/ur8koU0iYvc\" loading=\"lazy\" width=\"640\" height=\"360\" frameborder=\"0\" allow=\"accelerometer;autoplay;encrypted-media;gyroscope;picture-in-picture;fullscreen;web-share;\" allowfullscreen=\"\" style=\"position:absolute;top:0;left:0;width:100%;height:100%;border:0;background-color:#d8d8d8;\"></iframe>\n</div></p>\n<h4>Local video/audio files</h4>\n<p>Cecil peut aussi créer des éléments HTML vidéo et audio, selon l’extension du fichier.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">[<span class=\"hljs-string\">Video file</span>](<span class=\"hljs-link\">video.mp4</span>){embed controls poster=/images/video-test.png}\n[<span class=\"hljs-string\">Audio file</span>](<span class=\"hljs-link\">song.mp3</span>){embed controls}</code></pre>\n<p>Est converti en :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"/video.mp4\"</span> <span class=\"hljs-attr\">controls</span> <span class=\"hljs-attr\">poster</span>=<span class=\"hljs-string\">\"/images/video-test.png\"</span> <span class=\"hljs-attr\">style</span>=<span class=\"hljs-string\">\"max-width:100%;height:auto;\"</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">video</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">audio</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"/song.mp3\"</span> <span class=\"hljs-attr\">controls</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">audio</span>&gt;</span></code></pre>\n<p>Avec <code translate=\"no\">{embed=false}</code> (ou lorsque l’intégration est désactivée), un fichier vidéo/audio local reste un lien, mais son URL pointe vers le fichier publié (avec empreinte si <a href=\"../configuration/6-assets.fr.md\"><code translate=\"no\">assets.fingerprint</code></a> est activé).</p>\n<h2 id=\"images\">Images</h2>\n<p>Pour ajouter une image, utilisez un point d’exclamation (<code translate=\"no\">!</code>) suivi d’une description alternative entre crochets (<code translate=\"no\">[]</code>), puis du chemin ou de l’URL de l’image entre parenthèses (<code translate=\"no\">()</code>).<br>\nVous pouvez facultativement ajouter un titre entre guillemets.</p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![<span class=\"hljs-string\">Alternative description</span>](<span class=\"hljs-link\">/image.jpg \"Image title\"</span>)</code></pre>\n<aside class=\"note note-info\"><p>Le chemin doit être relatif à la racine de votre site Web (ex. : <code translate=\"no\">/image.jpg</code>), mais Cecil est capable de normaliser un chemin relatif aux répertoires <em>assets</em> et <em>static</em> (ex. : <code translate=\"no\">../../assets/image.jpg</code>).</p></aside>\n<h3 id=\"lazy-loading\">Lazy loading</h3>\n<p>Cecil ajoute l’attribut <code translate=\"no\">loading=\"lazy\"</code> à chaque image.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![](/image.jpg)</code></pre>\n<p>Est converti en :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"/image.jpg\"</span> <span class=\"hljs-attr\">loading</span>=<span class=\"hljs-string\">\"lazy\"</span>&gt;</span></code></pre>\n<aside class=\"note note-info\"><p>Vous pouvez désactiver ce comportement avec l’attribut <code translate=\"no\">{loading=eager}</code> ou avec l’<a href=\"../configuration/4-pages.fr.md#pages-body-images\">option <code translate=\"no\">lazy</code></a>.</p></aside>\n<h3 id=\"decoding\">Decoding</h3>\n<p>Cecil ajoute l’attribut <code translate=\"no\">decoding=\"async\"</code> à chaque image.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![](/image.jpg)</code></pre>\n<p>Est converti en :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"/image.jpg\"</span> <span class=\"hljs-attr\">decoding</span>=<span class=\"hljs-string\">\"async\"</span>&gt;</span></code></pre>\n<aside class=\"note note-info\"><p>Vous pouvez désactiver ce comportement avec l’attribut <code translate=\"no\">{decoding=auto}</code> ou avec l’<a href=\"../configuration/4-pages.fr.md#pages-body-images\">option <code translate=\"no\">decoding</code></a>.</p></aside>\n<h3 id=\"redimensionnement\">Redimensionnement</h3>\n<p>Chaque image du <em>body</em> peut être redimensionnée automatiquement en définissant une largeur inférieure à celle d’origine, avec l’attribut additionnel <code translate=\"no\">{width=X}</code>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![](/image.jpg){width=800}</code></pre>\n<p>Est converti en :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"/thumbnails/800/image.jpg\"</span> <span class=\"hljs-attr\">width</span>=<span class=\"hljs-string\">\"800\"</span> <span class=\"hljs-attr\">height</span>=<span class=\"hljs-string\">\"600\"</span>&gt;</span></code></pre>\n<aside class=\"note note-info\"><p>Le ratio est conservé (l’attribut <code translate=\"no\">height</code> est calculé automatiquement), le fichier original n’est pas modifié et la version redimensionnée est stockée dans <code translate=\"no\">/thumbnails/&lt;width&gt;/</code>.</p></aside>\n<aside class=\"note note-important\"><p>Cette fonctionnalité nécessite une bibliothèque de traitement d’images : <a href=\"https://www.php.net/manual/book.imagick.php\" target=\"_blank\" rel=\"noopener noreferrer\">Imagick</a> est utilisé en priorité s’il est disponible (et capable de lire le JPEG et le PNG), puis <a href=\"https://www.libvips.org/\" target=\"_blank\" rel=\"noopener noreferrer\">libvips</a> (via l’extension PHP <a href=\"https://www.php.net/manual/book.ffi.php\" target=\"_blank\" rel=\"noopener noreferrer\">FFI</a>), et enfin <a href=\"https://www.php.net/manual/book.image.php\" target=\"_blank\" rel=\"noopener noreferrer\">GD</a> en dernier recours ; sinon, elle ajoute seulement un attribut HTML <code translate=\"no\">width</code> à la balise <code translate=\"no\">img</code>.</p></aside>\n<aside class=\"note note-info\"><p>Le support de libvips est optionnel et n’est pas inclus dans <code translate=\"no\">cecil.phar</code>. Pour l’utiliser, Cecil doit être installé avec <a href=\"https://getcomposer.org\" target=\"_blank\" rel=\"noopener noreferrer\">Composer</a> et il faut :</p>\n<ol>\n<li><a href=\"https://www.libvips.org/install.html\" target=\"_blank\" rel=\"noopener noreferrer\">libvips</a> installé sur le système</li>\n<li>l’extension PHP <a href=\"https://www.php.net/manual/book.ffi.php\" target=\"_blank\" rel=\"noopener noreferrer\">FFI</a> activée</li>\n<li>le paquet <code translate=\"no\">intervention/image-driver-vips</code> installé avec Cecil</li>\n</ol>\n<p>Si Cecil est une dépendance de votre projet (voir <a href=\"../developers/2-library.fr.md#support-de-libvips\">Bibliothèque</a>) :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">composer require intervention/image-driver-vips</code></pre>\n<p>Si Cecil est installé globalement :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">composer global require cecil/cecil intervention/image-driver-vips</code></pre></aside>\n<h3 id=\"formats\">Formats</h3>\n<p>Si l’<a href=\"../configuration/4-pages.fr.md#pages-body-images\">option <code translate=\"no\">formats</code></a> est définie, des images alternatives sont créées et ajoutées.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![](/image.jpg)</code></pre>\n<p>Peut être converti en :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">picture</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">source</span> <span class=\"hljs-attr\">srcset</span>=<span class=\"hljs-string\">\"/image.avif\"</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"image/avif\"</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">source</span> <span class=\"hljs-attr\">srcset</span>=<span class=\"hljs-string\">\"/image.webp\"</span> <span class=\"hljs-attr\">type</span>=<span class=\"hljs-string\">\"image/webp\"</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"/image.jpg\"</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">picture</span>&gt;</span></code></pre>\n<aside class=\"note note-important\"><p>Veuillez noter que <strong>tous les formats d’image</strong> ne sont pas toujours inclus dans les extensions d’image PHP.</p></aside>\n<h3 id=\"responsive\">Responsive</h3>\n<p>Si l’<a href=\"../configuration/4-pages.fr.md#pages-body-images\">option <code translate=\"no\">responsive</code></a> est activée, alors toutes les images du <em>body</em> seront automatiquement rendues « responsive ».</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![](/image.jpg){width=800}</code></pre>\n<p>sera converti en :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"/thumbnails/800/image.jpg\"</span> <span class=\"hljs-attr\">width</span>=<span class=\"hljs-string\">\"800\"</span> <span class=\"hljs-attr\">height</span>=<span class=\"hljs-string\">\"600\"</span>\n  <span class=\"hljs-attr\">srcset</span>=<span class=\"hljs-string\">\"/thumbnails/320/image.jpg 320w,\n          /thumbnails/640/image.jpg 640w,\n          /thumbnails/800/image.jpg 800w\"</span>\n  <span class=\"hljs-attr\">sizes</span>=<span class=\"hljs-string\">\"100vw\"</span>\n&gt;</span></code></pre>\n<aside class=\"note note-info\"><p>Comme une image du body est convertie en <a href=\"../assets/index.fr.md#asset\">Asset</a>, les différentes largeurs doivent être définies dans la <a href=\"../configuration/6-assets.fr.md\">configuration des assets</a>.</p></aside>\n<p>L’attribut <code translate=\"no\">sizes</code> prend la valeur de l’option de configuration <code translate=\"no\">assets.images.responsive.sizes.default</code>, mais peut être modifié en créant une nouvelle entrée nommée d’après une <em>class</em> ajoutée à l’image.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">responsive:</span>\n      <span class=\"hljs-attr\">sizes:</span>\n        <span class=\"hljs-attr\">default:</span> <span class=\"hljs-string\">100vw</span>\n        <span class=\"hljs-attr\">my_class:</span> <span class=\"hljs-string\">\"(max-width: 800px) 768px, 1024px\"</span></code></pre>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![](/image.jpg){.my_class}</code></pre>\n<aside class=\"note note-info\"><p>Vous pouvez combiner les options <code translate=\"no\">formats</code> et <code translate=\"no\">responsive</code>.</p></aside>\n<h3 id=\"css-class\">CSS class</h3>\n<p>Vous pouvez définir une valeur par défaut pour l’attribut <code translate=\"no\">class</code> de chaque image avec l’<a href=\"../configuration/4-pages.fr.md#pages-body-images\">option <code translate=\"no\">class</code></a>.</p>\n<h3 id=\"caption\">Caption</h3>\n<p>Le titre optionnel peut être utilisé pour créer automatiquement une légende (<code translate=\"no\">figcaption</code>) en activant l’<a href=\"../configuration/4-pages.fr.md#pages-body-images\">option <code translate=\"no\">caption</code></a>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![](/images/img.jpg \"Title\")</code></pre>\n<p>Est converti en :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">figure</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">img</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"/image.jpg\"</span> <span class=\"hljs-attr\">title</span>=<span class=\"hljs-string\">\"Title\"</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">figcaption</span>&gt;</span>Title<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">figcaption</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">figure</span>&gt;</span></code></pre>\n<aside class=\"note note-info\"><p>La légende prend en charge le contenu Markdown.</p></aside>\n<h3 id=\"image-localisee\">Image localisée</h3>\n<p>Pour les pages traduites, Cecil recherche d’abord un fichier suffixé par la langue lors de la résolution des chemins d’image Markdown.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![](/images/cecil-logo.png)</code></pre>\n<p>Avec une page française (<code translate=\"no\">fr</code>), Cecil essaie d’abord <code translate=\"no\">/images/cecil-logo.fr.png</code>, puis revient à <code translate=\"no\">/images/cecil-logo.png</code>.</p>\n<h3 id=\"placeholder\">Placeholder</h3>\n<p>Comme les images sont généralement des ressources plus lourdes et plus lentes, et qu’elles ne bloquent pas le rendu, il est préférable de donner aux utilisateurs quelque chose à voir pendant qu’ils attendent leur chargement.</p>\n<p>L’attribut <code translate=\"no\">placeholder</code> accepte 2 options :</p>\n<ol>\n<li><code translate=\"no\">color</code>: affiche un fond coloré (basé sur la couleur dominante de l’image)</li>\n<li><code translate=\"no\">lqip</code>: <a href=\"https://www.guypo.com/introducing-lqip-low-quality-image-placeholders\" target=\"_blank\" rel=\"noopener noreferrer\">Low-Quality Image Placeholder</a></li>\n</ol>\n<p><em>Exemples :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">![](/images/img.jpg){placeholder=color}\n![](/images/img.jpg){placeholder=lqip}</code></pre>\n<aside class=\"note note-tip\"><p>Vous pouvez définir une valeur pour l’attribut <code translate=\"no\">placeholder</code> de chaque image avec l’<a href=\"../configuration/4-pages.fr.md#pages-body-images\">option <code translate=\"no\">placeholder</code></a>.</p></aside>\n<aside class=\"note note-warning\"><p>L’option <code translate=\"no\">lqip</code> n’est pas compatible avec les GIF animés.</p></aside>\n<h2 id=\"table-des-matieres\">Table des matières</h2>\n<p>Vous pouvez ajouter une table des matières avec la syntaxe Markdown suivante :</p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">[toc]</code></pre>\n<aside class=\"note note-info\"><p>Par défaut, la ToC extrait les en-têtes H2 et H3. Vous pouvez modifier ce comportement avec les <a href=\"../configuration/4-pages.fr.md#pages-body\">options de body</a>.</p></aside>\n<h2 id=\"extrait\">Extrait</h2>\n<p>Un extrait peut être défini dans le <em>body</em> avec l’une des balises suivantes : <code translate=\"no\">excerpt</code> ou <code translate=\"no\">break</code>.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\">Introduction.\n<span class=\"hljs-comment\">&lt;!-- excerpt --&gt;</span>\nMain content.</code></pre>\n<p>Utilisez ensuite le filtre <a href=\"../templates/reference/3-filters.fr.md#excerpt-html\"><code translate=\"no\">excerpt_html</code></a> dans votre template.</p>\n<h2 id=\"notes\">Notes</h2>\n<p>Créez un bloc de <em>Note</em> (info, astuce, important, etc.).</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">:::tip\n<span class=\"hljs-strong\">**Tip:**</span> This is advice.\n:::</code></pre>\n<p>Est converti en :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">aside</span> <span class=\"hljs-attr\">class</span>=<span class=\"hljs-string\">\"note note-tip\"</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p</span>&gt;</span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong</span>&gt;</span>Tip:<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">strong</span>&gt;</span> This is advice.\n  <span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">p</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">aside</span>&gt;</span></code></pre>\n<aside class=\"note note-tip\"><p><strong>Tip:</strong> This is advice.</p></aside>\n<p><em>Autres exemples :</em></p>\n<aside class=\"note\"><p>empty</p></aside>\n<aside class=\"note note-info\"><p>info</p></aside>\n<aside class=\"note note-tip\"><p>tip</p></aside>\n<aside class=\"note note-important\"><p>important</p></aside>\n<aside class=\"note note-warning\"><p>warning</p></aside>\n<aside class=\"note note-caution\"><p>caution</p></aside>\n<h2 id=\"coloration-syntaxique\">Coloration syntaxique</h2>\n<p>La coloration syntaxique des blocs de code est activée par défaut avec l’option <a href=\"../configuration/4-pages.fr.md#pages-body-highlight\">pages.body.highlight</a>.</p>\n<p>Si besoin, vous pouvez la désactiver avec :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">body:</span>\n    <span class=\"hljs-attr\">highlight:</span> <span class=\"hljs-literal\">false</span></code></pre>\n<p><em>Exemple :</em></p>\n<pre>\n```php\necho \"Hello world\";\n```\n</pre>\n<p>Est rendu en :</p>\n<pre><code class=\"language-php hljs php\" translate=\"no\"><span class=\"hljs-keyword\">echo</span> <span class=\"hljs-string\">\"Hello world\"</span>;</code></pre>\n<aside class=\"note note-info\"><p>Vous pouvez personnaliser le style de coloration syntaxique en créant votre propre thème. Consultez le <a href=\"https://highlightjs.readthedocs.io/en/latest/theme-guide.html\" target=\"_blank\" rel=\"noopener noreferrer\">guide des thèmes de Highlight.js</a>.</p></aside>\n<h2 id=\"texte-insere\">Texte inséré</h2>\n<p>Représente une plage de texte qui a été ajoutée.</p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">++text++</code></pre>\n<p>Est converti en :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ins</span>&gt;</span>text<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">ins</span>&gt;</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/deployer/hebergement-statique/",
      "url": "https://cecil-945.pages.dev/fr/documentation/deployer/hebergement-statique/",
      "title": "Hébergement statique",
      "summary": "Déployer sur un hébergement statique (Surge).",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Hébergement statique\nLe site construit peut être envoyé tel quel vers n’importe quel service d’hébergement statique.\nSurge\n\nPublier des projets web doit être rapide, simple et peu risqué. Surge est un service de publication de sites statiques pour les développeurs frontend, directement depuis la CLI.\n\n➡️ https:\/\/surge.sh\nTerminal:\nnpm install -g surge\nsurge _site\/\nDocumentation officielle",
      "content_html": "<h1>Hébergement statique</h1>\n<p>Le site construit peut être envoyé tel quel vers n’importe quel service d’hébergement statique.</p>\n<h2 id=\"surge\">Surge</h2>\n<blockquote>\n<p>Publier des projets web doit être rapide, simple et peu risqué. Surge est un service de publication de sites statiques pour les développeurs frontend, directement depuis la CLI.</p>\n</blockquote>\n<p>➡️ <a href=\"https://surge.sh\" target=\"_blank\" rel=\"noopener noreferrer\">https://surge.sh</a></p>\n<p>Terminal:</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">npm install -g surge\nsurge _site/</code></pre>\n<p><a href=\"https://surge.sh/help/\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation officielle</a></p>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/bien-demarrer/structure-des-dossiers/",
      "url": "https://cecil-945.pages.dev/fr/documentation/bien-demarrer/structure-des-dossiers/",
      "title": "Structure des dossiers",
      "summary": "Organisation des fichiers sources, arborescence du site généré et routage des fichiers vers les URL.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Structure des dossiers\nCette page décrit l’organisation d’un projet Cecil, la structure du site construit et la façon dont les fichiers sont associés aux URL.\nArborescence du système de fichiers\nOrganisation des fichiers du projet.\n&lt;monsiteweb&gt;\n├─ pages\n|  ├─ blog            &lt;- Section\n|  |  ├─ billet-1.md  &lt;- Page dans Section\n|  |  └─ billet-2.md\n|  ├─ projets\n|  |  └─ projet-a.md\n|  └─ about.md        &lt;- Page racine\n├─ assets\n|  ├─ styles.scss     &lt;- Fichier d'asset\n|  └─ logo.png\n├─ static\n|  └─ fichier.pdf     &lt;- Fichier statique\n└─ data\n   └─ auteurs.yml     &lt;- Collection de données\nArborescence du site généré\nRésultat de la génération.\n&lt;monsiteweb&gt;\n└─ _site\n   ├─ index.html               &lt;- Page d'accueil générée\n   ├─ blog\/\n   |  ├─ index.html            &lt;- Liste des articles générée\n   |  ├─ billet-1\/index.html   &lt;- Article de blog\n   |  └─ billet-2\/index.html\n   ├─ projets\/\n   |  ├─ index.html            &lt;- Liste des projets générée\n   |  └─ projet-a\/index.html   &lt;- Projet individuel\n   ├─ about\/index.html         &lt;- Page \"À propos\"\n   ├─ styles.css\n   ├─ logo.png\n   └─ fichier.pdf\nPar défaut, chaque page est générée sous la forme nomdufichier-sluglifié\/index.html pour obtenir une « belle » URL comme https:\/\/monsiteweb.tld\/section\/nomdufichier-sluglifié\/.\nPour obtenir une URL « ugly » (comme 404.html au lieu de 404\/), définissez uglyurl: true dans le front matter de la page.\nRoutage basé sur les fichiers\nLes fichiers Markdown du répertoire pages activent un routage basé sur les fichiers. Cela signifie que l’ajout, par exemple, de pages\/mon-projet\/projet-a.md le rendra accessible à l’URL \/projet-a dans votre navigateur.\nFichier :\n                   pages\/mon-projet\/projet-a.md\n                        └───── filepath ──────┘\nURL :\n    ┌───── baseurl ─────┬─────── path ────────┐\n     https:\/\/exemple.com\/mon-projet\/projet-a\/index.html\n                        └─ section ─┴─ slug ──┘\nDeux types de préfixes peuvent modifier l’URL, voir la section Préfixe de fichier ci-dessous.",
      "content_html": "<h1>Structure des dossiers</h1>\n<p>Cette page décrit l’organisation d’un projet Cecil, la structure du site construit et la façon dont les fichiers sont associés aux URL.</p>\n<h2 id=\"arborescence-du-systeme-de-fichiers\">Arborescence du système de fichiers</h2>\n<p>Organisation des fichiers du projet.</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">&lt;monsiteweb&gt;\n├─ pages\n|  ├─ blog            &lt;- Section\n|  |  ├─ billet-1.md  &lt;- Page dans Section\n|  |  └─ billet-2.md\n|  ├─ projets\n|  |  └─ projet-a.md\n|  └─ about.md        &lt;- Page racine\n├─ assets\n|  ├─ styles.scss     &lt;- Fichier d'asset\n|  └─ logo.png\n├─ static\n|  └─ fichier.pdf     &lt;- Fichier statique\n└─ data\n   └─ auteurs.yml     &lt;- Collection de données</code></pre>\n<h2 id=\"arborescence-du-site-genere\">Arborescence du site généré</h2>\n<p>Résultat de la génération.</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">&lt;monsiteweb&gt;\n└─ _site\n   ├─ index.html               &lt;- Page d'accueil générée\n   ├─ blog/\n   |  ├─ index.html            &lt;- Liste des articles générée\n   |  ├─ billet-1/index.html   &lt;- Article de blog\n   |  └─ billet-2/index.html\n   ├─ projets/\n   |  ├─ index.html            &lt;- Liste des projets générée\n   |  └─ projet-a/index.html   &lt;- Projet individuel\n   ├─ about/index.html         &lt;- Page \"À propos\"\n   ├─ styles.css\n   ├─ logo.png\n   └─ fichier.pdf</code></pre>\n<aside class=\"note note-info\"><p>Par défaut, chaque page est générée sous la forme <code translate=\"no\">nomdufichier-sluglifié/index.html</code> pour obtenir une « belle » URL comme <code translate=\"no\">https://monsiteweb.tld/section/nomdufichier-sluglifié/</code>.</p>\n<p>Pour obtenir une URL « ugly » (comme <code translate=\"no\">404.html</code> au lieu de <code translate=\"no\">404/</code>), définissez <code translate=\"no\">uglyurl: true</code> dans le <a href=\"../content/1-pages.fr.md#front-matter\">front matter</a> de la page.</p></aside>\n<h2 id=\"routage-base-sur-les-fichiers\">Routage basé sur les fichiers</h2>\n<p>Les fichiers Markdown du répertoire <code translate=\"no\">pages</code> activent un routage basé sur les fichiers. Cela signifie que l’ajout, par exemple, de <code translate=\"no\">pages/mon-projet/projet-a.md</code> le rendra accessible à l’URL <code translate=\"no\">/projet-a</code> dans votre navigateur.</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Fichier :\n                   pages/mon-projet/projet-a.md\n                        └───── filepath ──────┘\nURL :\n    ┌───── baseurl ─────┬─────── path ────────┐\n     https://exemple.com/mon-projet/projet-a/index.html\n                        └─ section ─┴─ slug ──┘</code></pre>\n<aside class=\"note note-important\"><p>Deux types de préfixes peuvent modifier l’URL, voir la section <a href=\"../content/1-pages.fr.md#prefixe-de-fichier\">Préfixe de fichier</a> ci-dessous.</p></aside>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/commandes/build/",
      "url": "https://cecil-945.pages.dev/fr/documentation/commandes/build/",
      "title": "build",
      "summary": "Générer le site.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "build\nConstruit le site.\nUtilisation\nDescription:\n  Builds the website\n\nUsage:\n  build [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                               Use the given path as working directory\n\nOptions:\n  -d, --drafts                       Include drafts\n  -u, --baseurl=BASEURL              Set the base URL\n  -o, --output=OUTPUT                Set the output directory\n      --optimize|--no-optimize       Enable (or disable --no-optimize) optimization of generated files\n      --dry-run                      Build without saving\n  -c, --config=CONFIG                Set the path to extra config files (comma-separated)\n      --clear-cache[=CLEAR-CACHE]    Clear cache before build (optional cache key as regular expression) [default: false]\n  -p, --page=PAGE                    Build a specific page\n      --render-subset=RENDER-SUBSET  Render a subset of pages\n      --show-pages                   Show list of built pages in a table\n  -m, --metrics                      Show build metrics (duration and memory) of each step\n      --notify                       Send desktop notification on build completion\n  -h, --help                         Display help for the given command. When no command is given display help for the list command\n  -q, --quiet                        Do not output any message\n  -V, --version                      Display this application version\n      --ansi|--no-ansi               Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction               Do not ask any interactive question\n  -v|vv|vvv, --verbose               Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The build command generates the website in the output directory.\n\n    cecil.phar build\n    cecil.phar build path\/to\/the\/working\/directory\n    cecil.phar build --baseurl=https:\/\/example.com\/\n    cecil.phar build --output=_site\n\n  To build the website with optimization of generated files, you can use the --optimize option.\n  This is useful to reduce the size of the generated files and improve performance:\n\n    cecil.phar build --optimize\n    cecil.phar build --no-optimize\n\n  To build the website without overwriting files in the output directory, you can use the --dry-run option.\n  This is useful to check what would be built without actually writing files:\n\n    cecil.phar build --dry-run\n\n  To build the website with a specific subset of rendered pages, you can use the --render-subset option.\n  This is useful to build only a part of the website, for example, only \"hot\" pages or a specific section:\n\n    cecil.phar build --render-subset=subset\n\n  To show build steps metrics, run:\n\n    cecil.phar build --metrics",
      "content_html": "<h1>build</h1>\n<p>Construit le site.</p>\n<h2 id=\"utilisation\">Utilisation</h2>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Builds the website\n\nUsage:\n  build [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                               Use the given path as working directory\n\nOptions:\n  -d, --drafts                       Include drafts\n  -u, --baseurl=BASEURL              Set the base URL\n  -o, --output=OUTPUT                Set the output directory\n      --optimize|--no-optimize       Enable (or disable --no-optimize) optimization of generated files\n      --dry-run                      Build without saving\n  -c, --config=CONFIG                Set the path to extra config files (comma-separated)\n      --clear-cache[=CLEAR-CACHE]    Clear cache before build (optional cache key as regular expression) [default: false]\n  -p, --page=PAGE                    Build a specific page\n      --render-subset=RENDER-SUBSET  Render a subset of pages\n      --show-pages                   Show list of built pages in a table\n  -m, --metrics                      Show build metrics (duration and memory) of each step\n      --notify                       Send desktop notification on build completion\n  -h, --help                         Display help for the given command. When no command is given display help for the list command\n  -q, --quiet                        Do not output any message\n  -V, --version                      Display this application version\n      --ansi|--no-ansi               Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction               Do not ask any interactive question\n  -v|vv|vvv, --verbose               Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The build command generates the website in the output directory.\n\n    cecil.phar build\n    cecil.phar build path/to/the/working/directory\n    cecil.phar build --baseurl=https://example.com/\n    cecil.phar build --output=_site\n\n  To build the website with optimization of generated files, you can use the --optimize option.\n  This is useful to reduce the size of the generated files and improve performance:\n\n    cecil.phar build --optimize\n    cecil.phar build --no-optimize\n\n  To build the website without overwriting files in the output directory, you can use the --dry-run option.\n  This is useful to check what would be built without actually writing files:\n\n    cecil.phar build --dry-run\n\n  To build the website with a specific subset of rendered pages, you can use the --render-subset option.\n  This is useful to build only a part of the website, for example, only \"hot\" pages or a specific section:\n\n    cecil.phar build --render-subset=subset\n\n  To show build steps metrics, run:\n\n    cecil.phar build --metrics</code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/pages/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/pages/",
      "title": "Pages",
      "summary": "Dossier des pages, tri, pagination, chemins, corps, pages virtuelles, générateurs, etc.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Pages\nCes options contrôlent la façon dont les pages sont chargées, triées, paginées, routées et générées.\npages.dir\nRépertoire source des pages (pages par défaut).\npages:\n  dir: pages\npages.ext\nExtensions des fichiers de pages.\npages:\n  ext: [md, markdown, mdown, mkdn, mkd, text, txt]\npages.exclude\nRépertoires, chemins et noms de fichiers à exclure (accepte les glob, les chaînes et les expressions régulières).\npages:\n  exclude: ['vendor', 'node_modules', '*.scss', '\/\\.bck$\/']\npages.prefix.separator\nListe des caractères utilisés comme séparateur entre un préfixe de nom de fichier (date ou weight) et le slug.\npages:\n  prefix:\n    separator: ['-', '_']\npages.sortby\nMéthode de tri par défaut des collections.\npages:\n  sortby: date # `date`, `updated`, `title` ou `weight`\n  # ou\n  sortby:\n    variable: date    # `date`, `updated`, `title` ou `weight`\n    desc_title: false # tri par titre décroissant\n    reverse: false    # inverse l’ordre de tri\npages.pagination\nLa pagination est disponible pour les pages de liste (type homepage, section ou term).\npages:\n  pagination:\n    max: 5     # nombre maximum d’entrées par page\n    path: page # chemin de la page paginée\nDésactiver la pagination\nLa pagination peut être désactivée :\npages:\n  pagination: false\npages.paths\nApplique un path personnalisé à toutes les pages d’une section.\npages:\n  paths:\n    - section: &lt;section’s ID&gt;\n      path: &lt;path of pages&gt;\nEmplacements des variables de chemin\n\n:year\n:month\n:day\n:section\n:slug\n\nExemple :\npages:\n  paths:\n    - section: Blog\n      path: :section\/:year\/:month\/:day\/:slug # ex. : \/blog\/2020\/12\/01\/my-post\/\n# localized\nlanguages:\n  - code: fr\n    name: Français\n    locale: fr_FR\n    config:\n      pages:\n        paths:\n          - section: Blog\n            path: blogue\/:year\/:month\/:day\/:slug # ex. : \/blogue\/2020\/12\/01\/mon-billet\/\npages.frontmatter\nFormat du front matter des pages (yaml par défaut, accepte aussi ini, toml et json).\npages:\n  frontmatter: yaml\npages.body\nOptions du corps des pages.\nPour savoir comment ces options influencent votre contenu, voir la documentation Contenu &gt; Markdown.\npages.body.toc\nEn-têtes utilisés pour construire la table des matières ([h2, h3] par défaut).\npages:\n  body:\n    toc: [h2, h3]\npages.body.highlight\nActive la coloration syntaxique du code (true par défaut).\npages:\n  body:\n    highlight: false # définissez à false pour désactiver la coloration syntaxique\npages.body.images\nOptions de gestion des images.\npages:\n  body:\n    images:\n      formats: []       # ajoute des formats d’image alternatifs comme `source` (ex. `[avif, webp]`, tableau vide par défaut)\n      resize: 0         # redimensionne toutes les images à &lt;width&gt; (en pixels, `0` pour désactiver)\n      responsive: false # ajoute des variantes responsives à l’attribut `srcset` (`false` par défaut)\n      lazy: true        # ajoute l’attribut `loading=\"lazy\"` (`true` par défaut)\n      decoding: true    # ajoute l’attribut `decoding=\"async\"` (`true` par défaut)\n      caption: false    # place l’image dans un élément &lt;figure&gt; et ajoute une &lt;figcaption&gt; contenant le titre (`false` par défaut)\n      placeholder: ''   # remplit l’arrière-plan de &lt;img&gt; avant le chargement ('color' ou 'lqip', vide par défaut)\n      class: ''         # définit une classe par défaut sur chaque image (vide par défaut)\n      dark_suffix: ''   # suffixe de l’image variante sombre (ex. `.dark`), désactivé par défaut\n      mobile_suffix: '' # suffixe de l’image variante mobile (ex. `.mobile`), désactivé par défaut\n      mobile_media_query: '(max-width: 767px)' # media query de la `&lt;source&gt;` de la variante mobile\n      remote:           # traitement des images distantes (mettre à `false` pour désactiver)\n        fallback:         # chemin de l’image de secours, stockée dans le répertoire assets (vide par défaut)\nDepuis la version 8.41.0, l’option pages.body.images.resize sert à redimensionner les images à une largeur précise, et non plus à activer la fonctionnalité de redimensionnement (activée systématiquement).\nLes options globales, comme les largeurs et tailles des images responsives, sont configurables dans la section assets.images.\nLes images distantes sont téléchargées et converties en Assets pour être manipulées. Vous pouvez désactiver ce comportement en définissant l’option pages.body.images.remote.enabled à false.\nLorsque dark_suffix est défini (par ex. dark_suffix: .dark), Cecil cherche automatiquement une variante sombre de chaque image (par ex. photo.dark.jpg à côté de photo.jpg). Si elle est trouvée, l’image est entourée d’un élément &lt;picture&gt; avec une balise &lt;source media=\"(prefers-color-scheme: dark)\"&gt; pour un basculement automatique clair\/sombre. Cela fonctionne avec formats et responsive.\nDe la même manière, lorsque mobile_suffix est défini (par ex. mobile_suffix: .mobile), Cecil cherche une variante mobile de chaque image (par ex. photo.mobile.jpg à côté de photo.jpg) et ajoute une balise &lt;source&gt; avec la media query mobile_media_query ((max-width: 767px) par défaut). Si dark_suffix est également défini, la variante sombre de l’image mobile (par ex. photo.mobile.dark.jpg) est utilisée sur mobile en mode sombre. Les sources mobiles sont placées avant les sources sombres, afin que la variante mobile soit prioritaire.\npages.body.links\nOptions de gestion des liens.\npages:\n  body:\n    links:\n      embed:\n        enabled: false     # transforme les liens en contenu embarqué si possible (`false` par défaut)\n        video: [mp4, webm] # extensions des fichiers vidéo\n        audio: [mp3]       # extensions des fichiers audio\n      external:\n        blank: false     # si `true`, ouvre le lien externe dans un nouvel onglet\n        noopener: true   # si `true`, ajoute `noopener` à l’attribut `rel`\n        noreferrer: true # si `true`, ajoute `noreferrer` à l’attribut `rel`\n        nofollow: false  # si `true`, ajoute `nofollow` à l’attribut `rel`\npages.body.excerpt\nOptions de gestion des extraits.\npages:\n  body:\n    excerpt:\n      separator: excerpt|break # chaîne utilisée comme séparateur (`excerpt|break` par défaut)\n      capture: before          # partie à capturer, `before` ou `after` le séparateur (`before` par défaut)\npages.virtual\nLes pages virtuelles sont la meilleure façon de créer des pages sans contenu (front matter uniquement).\nElles consistent en une liste de pages avec un path et quelques variables de front matter.\nExemple :\npages:\n  virtual:\n    - path: code\n      redirect: https:\/\/github.com\/ArnaudLigny\npages.default\nLes pages par défaut sont des pages créées automatiquement par Cecil (à partir de modèles intégrés) :\npages:\n  default:\n    index:\n      path: ''\n      title: Accueil\n      published: true\n    404:\n      path: 404\n      title: Page introuvable\n      layout: 404\n      uglyurl: true\n      published: true\n      excluded: true\n    robots:\n      path: robots\n      title: Robots.txt\n      layout: robots\n      output: txt\n      published: true\n      excluded: true\n      multilingual: false\n    sitemap:\n      path: sitemap\n      title: Plan de site XML\n      layout: sitemap\n      output: xml\n      changefreq: monthly\n      priority: 0.5\n      published: true\n      excluded: true\n      multilingual: false\n    xsl\/atom:\n      path: xsl\/atom\n      layout: feed\n      output: xsl\n      uglyurl: true\n      published: true\n      excluded: true\n    xsl\/rss:\n      path: xsl\/rss\n      layout: feed\n      output: xsl\n      uglyurl: true\n      published: false\n      excluded: true\nLa structure est presque identique à celle de pages.virtual, à l’exception de la clé nommée.\nChaque page peut être :\n\ndésactivée : published: false\nexclue des pages de liste : excluded: true\nexclue de la localisation : multilingual: false\n\nDepuis la version 8.68.0, vous pouvez surcharger la page robots.txt par défaut en créant une page avec le même path :\npages\/robots.md\n---\nlayout: robots\noutput: txt\n---\nUser-agent: AI-bot\nDisallow: \/\npages.generators\nLes générateurs servent à Cecil pour créer des pages supplémentaires (par ex. sitemap, flux, pagination, etc.) à partir de pages existantes, ou à partir d’autres sources comme le fichier de configuration ou des sources externes.\nVoici la liste des générateurs fournis par Cecil, dans un ordre défini :\npages:\n  generators:\n    10: 'Cecil\\Generator\\DefaultPages'\n    20: 'Cecil\\Generator\\VirtualPages'\n    30: 'Cecil\\Generator\\ExternalBody'\n    40: 'Cecil\\Generator\\Section'\n    50: 'Cecil\\Generator\\Taxonomy'\n    60: 'Cecil\\Generator\\Homepage'\n    70: 'Cecil\\Generator\\Pagination'\n    80: 'Cecil\\Generator\\Alias'\n    90: 'Cecil\\Generator\\Redirect'\nVous pouvez étendre Cecil avec un générateur de pages.\npages.subsets\nLes sous-ensembles servent à rendre une partie de la collection de pages, selon un chemin, une langue ou un format de sortie spécifique, avec la commande :\ncecil build --render-subset=&lt;name&gt;\npages:\n  subsets:\n    &lt;name&gt;:\n      path: &lt;path&gt; # chemin glob ou chaîne (ex. `blog\/*`, `blog`)\n      language: &lt;language&gt; # code de langue (ex. `en`, `fr`)\n      output: &lt;output&gt; # format de sortie (ex. `html`, `atom`)\nExemple :\npages:\n  subsets:\n    blog_en:\n      path: blog\n      language: en\n      output: html\n    search_index:\n      path: '*'\n      output: json\n",
      "content_html": "<h1>Pages</h1>\n<p>Ces options contrôlent la façon dont les pages sont chargées, triées, paginées, routées et générées.</p>\n<h2 id=\"pages-dir\">pages.dir</h2>\n<p>Répertoire source des pages (<code translate=\"no\">pages</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">pages</span></code></pre>\n<h2 id=\"pages-ext\">pages.ext</h2>\n<p>Extensions des fichiers de pages.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">ext:</span> <span class=\"hljs-string\">[md,</span> <span class=\"hljs-string\">markdown,</span> <span class=\"hljs-string\">mdown,</span> <span class=\"hljs-string\">mkdn,</span> <span class=\"hljs-string\">mkd,</span> <span class=\"hljs-string\">text,</span> <span class=\"hljs-string\">txt]</span></code></pre>\n<h2 id=\"pages-exclude\">pages.exclude</h2>\n<p>Répertoires, chemins et noms de fichiers à exclure (accepte les glob, les chaînes et les expressions régulières).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">exclude:</span> <span class=\"hljs-string\">['vendor',</span> <span class=\"hljs-string\">'node_modules'</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">'*.scss'</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">'/\\.bck$/'</span><span class=\"hljs-string\">]</span></code></pre>\n<h2 id=\"pages-prefix-separator\">pages.prefix.separator</h2>\n<p>Liste des caractères utilisés comme séparateur entre un préfixe de nom de fichier (<code translate=\"no\">date</code> ou <code translate=\"no\">weight</code>) et le slug.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">prefix:</span>\n    <span class=\"hljs-attr\">separator:</span> <span class=\"hljs-string\">['-',</span> <span class=\"hljs-string\">'_'</span><span class=\"hljs-string\">]</span></code></pre>\n<h2 id=\"pages-sortby\">pages.sortby</h2>\n<p>Méthode de tri par défaut des collections.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">sortby:</span> <span class=\"hljs-string\">date</span> <span class=\"hljs-comment\"># `date`, `updated`, `title` ou `weight`</span>\n  <span class=\"hljs-comment\"># ou</span>\n  <span class=\"hljs-attr\">sortby:</span>\n    <span class=\"hljs-attr\">variable:</span> <span class=\"hljs-string\">date</span>    <span class=\"hljs-comment\"># `date`, `updated`, `title` ou `weight`</span>\n    <span class=\"hljs-attr\">desc_title:</span> <span class=\"hljs-literal\">false</span> <span class=\"hljs-comment\"># tri par titre décroissant</span>\n    <span class=\"hljs-attr\">reverse:</span> <span class=\"hljs-literal\">false</span>    <span class=\"hljs-comment\"># inverse l’ordre de tri</span></code></pre>\n<h2 id=\"pages-pagination\">pages.pagination</h2>\n<p>La pagination est disponible pour les pages de liste (<em>type</em> <code translate=\"no\">homepage</code>, <code translate=\"no\">section</code> ou <code translate=\"no\">term</code>).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">pagination:</span>\n    <span class=\"hljs-attr\">max:</span> <span class=\"hljs-number\">5</span>     <span class=\"hljs-comment\"># nombre maximum d’entrées par page</span>\n    <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">page</span> <span class=\"hljs-comment\"># chemin de la page paginée</span></code></pre>\n<h3 id=\"desactiver-la-pagination\">Désactiver la pagination</h3>\n<p>La pagination peut être désactivée :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">pagination:</span> <span class=\"hljs-literal\">false</span></code></pre>\n<h2 id=\"pages-paths\">pages.paths</h2>\n<p>Applique un <a href=\"../content/2-front-matter.fr.md#variables-predefinies\"><code translate=\"no\">path</code></a> personnalisé à toutes les pages d’une <strong><em>section</em></strong>.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">paths:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">section:</span> <span class=\"hljs-string\">&lt;section’s</span> <span class=\"hljs-string\">ID&gt;</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">&lt;path</span> <span class=\"hljs-string\">of</span> <span class=\"hljs-string\">pages&gt;</span></code></pre>\n<h3 id=\"emplacements-des-variables-de-chemin\">Emplacements des variables de chemin</h3>\n<ul>\n<li><code translate=\"no\">:year</code></li>\n<li><code translate=\"no\">:month</code></li>\n<li><code translate=\"no\">:day</code></li>\n<li><code translate=\"no\">:section</code></li>\n<li><code translate=\"no\">:slug</code></li>\n</ul>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">paths:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">section:</span> <span class=\"hljs-string\">Blog</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">:section/:year/:month/:day/:slug</span> <span class=\"hljs-comment\"># ex. : /blog/2020/12/01/my-post/</span>\n<span class=\"hljs-comment\"># localized</span>\n<span class=\"hljs-attr\">languages:</span>\n  <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">code:</span> <span class=\"hljs-string\">fr</span>\n    <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Français</span>\n    <span class=\"hljs-attr\">locale:</span> <span class=\"hljs-string\">fr_FR</span>\n    <span class=\"hljs-attr\">config:</span>\n      <span class=\"hljs-attr\">pages:</span>\n        <span class=\"hljs-attr\">paths:</span>\n          <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">section:</span> <span class=\"hljs-string\">Blog</span>\n            <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">blogue/:year/:month/:day/:slug</span> <span class=\"hljs-comment\"># ex. : /blogue/2020/12/01/mon-billet/</span></code></pre>\n<h2 id=\"pages-frontmatter\">pages.frontmatter</h2>\n<p>Format du front matter des pages (<code translate=\"no\">yaml</code> par défaut, accepte aussi <code translate=\"no\">ini</code>, <code translate=\"no\">toml</code> et <code translate=\"no\">json</code>).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">frontmatter:</span> <span class=\"hljs-string\">yaml</span></code></pre>\n<h2 id=\"pages-body\">pages.body</h2>\n<p>Options du corps des pages.</p>\n<aside class=\"note note-info\"><p>Pour savoir comment ces options influencent votre contenu, voir la documentation <em><a href=\"../content/3-markdown.fr.md\">Contenu &gt; Markdown</a></em>.</p></aside>\n<h3 id=\"pages-body-toc\">pages.body.toc</h3>\n<p>En-têtes utilisés pour construire la table des matières (<code translate=\"no\">[h2, h3]</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">body:</span>\n    <span class=\"hljs-attr\">toc:</span> <span class=\"hljs-string\">[h2,</span> <span class=\"hljs-string\">h3]</span></code></pre>\n<h3 id=\"pages-body-highlight\">pages.body.highlight</h3>\n<p>Active la coloration syntaxique du code (<code translate=\"no\">true</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">body:</span>\n    <span class=\"hljs-attr\">highlight:</span> <span class=\"hljs-literal\">false</span> <span class=\"hljs-comment\"># définissez à false pour désactiver la coloration syntaxique</span></code></pre>\n<h3 id=\"pages-body-images\">pages.body.images</h3>\n<p>Options de gestion des images.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">body:</span>\n    <span class=\"hljs-attr\">images:</span>\n      <span class=\"hljs-attr\">formats:</span> <span class=\"hljs-string\">[]</span>       <span class=\"hljs-comment\"># ajoute des formats d’image alternatifs comme `source` (ex. `[avif, webp]`, tableau vide par défaut)</span>\n      <span class=\"hljs-attr\">resize:</span> <span class=\"hljs-number\">0</span>         <span class=\"hljs-comment\"># redimensionne toutes les images à &lt;width&gt; (en pixels, `0` pour désactiver)</span>\n      <span class=\"hljs-attr\">responsive:</span> <span class=\"hljs-literal\">false</span> <span class=\"hljs-comment\"># ajoute des variantes responsives à l’attribut `srcset` (`false` par défaut)</span>\n      <span class=\"hljs-attr\">lazy:</span> <span class=\"hljs-literal\">true</span>        <span class=\"hljs-comment\"># ajoute l’attribut `loading=\"lazy\"` (`true` par défaut)</span>\n      <span class=\"hljs-attr\">decoding:</span> <span class=\"hljs-literal\">true</span>    <span class=\"hljs-comment\"># ajoute l’attribut `decoding=\"async\"` (`true` par défaut)</span>\n      <span class=\"hljs-attr\">caption:</span> <span class=\"hljs-literal\">false</span>    <span class=\"hljs-comment\"># place l’image dans un élément &lt;figure&gt; et ajoute une &lt;figcaption&gt; contenant le titre (`false` par défaut)</span>\n      <span class=\"hljs-attr\">placeholder:</span> <span class=\"hljs-string\">''</span>   <span class=\"hljs-comment\"># remplit l’arrière-plan de &lt;img&gt; avant le chargement ('color' ou 'lqip', vide par défaut)</span>\n      <span class=\"hljs-attr\">class:</span> <span class=\"hljs-string\">''</span>         <span class=\"hljs-comment\"># définit une classe par défaut sur chaque image (vide par défaut)</span>\n      <span class=\"hljs-attr\">dark_suffix:</span> <span class=\"hljs-string\">''</span>   <span class=\"hljs-comment\"># suffixe de l’image variante sombre (ex. `.dark`), désactivé par défaut</span>\n      <span class=\"hljs-attr\">mobile_suffix:</span> <span class=\"hljs-string\">''</span> <span class=\"hljs-comment\"># suffixe de l’image variante mobile (ex. `.mobile`), désactivé par défaut</span>\n      <span class=\"hljs-attr\">mobile_media_query:</span> <span class=\"hljs-string\">'(max-width: 767px)'</span> <span class=\"hljs-comment\"># media query de la `&lt;source&gt;` de la variante mobile</span>\n      <span class=\"hljs-attr\">remote:</span>           <span class=\"hljs-comment\"># traitement des images distantes (mettre à `false` pour désactiver)</span>\n        <span class=\"hljs-attr\">fallback:</span>         <span class=\"hljs-comment\"># chemin de l’image de secours, stockée dans le répertoire assets (vide par défaut)</span></code></pre>\n<aside class=\"note note-warning\"><p>Depuis la version <ins>8.41.0</ins>, l’option <code translate=\"no\">pages.body.images.resize</code> sert à redimensionner les images à une largeur précise, et non plus à activer la fonctionnalité de redimensionnement (activée systématiquement).</p></aside>\n<aside class=\"note note-important\"><p>Les options globales, comme les largeurs et tailles des images responsives, sont configurables dans la section <a href=\"6-assets.fr.md#assets-images\"><code translate=\"no\">assets.images</code></a>.</p></aside>\n<aside class=\"note note-info\"><p>Les images distantes sont téléchargées et converties en <em>Assets</em> pour être manipulées. Vous pouvez désactiver ce comportement en définissant l’option <code translate=\"no\">pages.body.images.remote.enabled</code> à <code translate=\"no\">false</code>.</p></aside>\n<aside class=\"note note-tip\"><p>Lorsque <code translate=\"no\">dark_suffix</code> est défini (par ex. <code translate=\"no\">dark_suffix: .dark</code>), Cecil cherche automatiquement une variante sombre de chaque image (par ex. <code translate=\"no\">photo.dark.jpg</code> à côté de <code translate=\"no\">photo.jpg</code>). Si elle est trouvée, l’image est entourée d’un élément <code translate=\"no\">&lt;picture&gt;</code> avec une balise <code translate=\"no\">&lt;source media=\"(prefers-color-scheme: dark)\"&gt;</code> pour un basculement automatique clair/sombre. Cela fonctionne avec <code translate=\"no\">formats</code> et <code translate=\"no\">responsive</code>.</p>\n<p>De la même manière, lorsque <code translate=\"no\">mobile_suffix</code> est défini (par ex. <code translate=\"no\">mobile_suffix: .mobile</code>), Cecil cherche une variante mobile de chaque image (par ex. <code translate=\"no\">photo.mobile.jpg</code> à côté de <code translate=\"no\">photo.jpg</code>) et ajoute une balise <code translate=\"no\">&lt;source&gt;</code> avec la media query <code translate=\"no\">mobile_media_query</code> (<code translate=\"no\">(max-width: 767px)</code> par défaut). Si <code translate=\"no\">dark_suffix</code> est également défini, la variante sombre de l’image mobile (par ex. <code translate=\"no\">photo.mobile.dark.jpg</code>) est utilisée sur mobile en mode sombre. Les sources mobiles sont placées avant les sources sombres, afin que la variante mobile soit prioritaire.</p></aside>\n<h3 id=\"pages-body-links\">pages.body.links</h3>\n<p>Options de gestion des liens.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">body:</span>\n    <span class=\"hljs-attr\">links:</span>\n      <span class=\"hljs-attr\">embed:</span>\n        <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">false</span>     <span class=\"hljs-comment\"># transforme les liens en contenu embarqué si possible (`false` par défaut)</span>\n        <span class=\"hljs-attr\">video:</span> <span class=\"hljs-string\">[mp4,</span> <span class=\"hljs-string\">webm]</span> <span class=\"hljs-comment\"># extensions des fichiers vidéo</span>\n        <span class=\"hljs-attr\">audio:</span> <span class=\"hljs-string\">[mp3]</span>       <span class=\"hljs-comment\"># extensions des fichiers audio</span>\n      <span class=\"hljs-attr\">external:</span>\n        <span class=\"hljs-attr\">blank:</span> <span class=\"hljs-literal\">false</span>     <span class=\"hljs-comment\"># si `true`, ouvre le lien externe dans un nouvel onglet</span>\n        <span class=\"hljs-attr\">noopener:</span> <span class=\"hljs-literal\">true</span>   <span class=\"hljs-comment\"># si `true`, ajoute `noopener` à l’attribut `rel`</span>\n        <span class=\"hljs-attr\">noreferrer:</span> <span class=\"hljs-literal\">true</span> <span class=\"hljs-comment\"># si `true`, ajoute `noreferrer` à l’attribut `rel`</span>\n        <span class=\"hljs-attr\">nofollow:</span> <span class=\"hljs-literal\">false</span>  <span class=\"hljs-comment\"># si `true`, ajoute `nofollow` à l’attribut `rel`</span></code></pre>\n<h3 id=\"pages-body-excerpt\">pages.body.excerpt</h3>\n<p>Options de gestion des extraits.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">body:</span>\n    <span class=\"hljs-attr\">excerpt:</span>\n      <span class=\"hljs-attr\">separator:</span> <span class=\"hljs-string\">excerpt|break</span> <span class=\"hljs-comment\"># chaîne utilisée comme séparateur (`excerpt|break` par défaut)</span>\n      <span class=\"hljs-attr\">capture:</span> <span class=\"hljs-string\">before</span>          <span class=\"hljs-comment\"># partie à capturer, `before` ou `after` le séparateur (`before` par défaut)</span></code></pre>\n<h2 id=\"pages-virtual\">pages.virtual</h2>\n<p>Les pages virtuelles sont la meilleure façon de créer des pages sans contenu (<strong>front matter uniquement</strong>).</p>\n<p>Elles consistent en une liste de pages avec un <code translate=\"no\">path</code> et quelques variables de front matter.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">virtual:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">code</span>\n      <span class=\"hljs-attr\">redirect:</span> <span class=\"hljs-string\">https://github.com/ArnaudLigny</span></code></pre>\n<h2 id=\"pages-default\">pages.default</h2>\n<p>Les pages par défaut sont des pages créées automatiquement par Cecil (à partir de modèles intégrés) :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">default:</span>\n    <span class=\"hljs-attr\">index:</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">''</span>\n      <span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">Accueil</span>\n      <span class=\"hljs-attr\">published:</span> <span class=\"hljs-literal\">true</span>\n    <span class=\"hljs-attr\">404:</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-number\">404</span>\n      <span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">Page</span> <span class=\"hljs-string\">introuvable</span>\n      <span class=\"hljs-attr\">layout:</span> <span class=\"hljs-number\">404</span>\n      <span class=\"hljs-attr\">uglyurl:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">published:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">excluded:</span> <span class=\"hljs-literal\">true</span>\n    <span class=\"hljs-attr\">robots:</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">robots</span>\n      <span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">Robots.txt</span>\n      <span class=\"hljs-attr\">layout:</span> <span class=\"hljs-string\">robots</span>\n      <span class=\"hljs-attr\">output:</span> <span class=\"hljs-string\">txt</span>\n      <span class=\"hljs-attr\">published:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">excluded:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">multilingual:</span> <span class=\"hljs-literal\">false</span>\n    <span class=\"hljs-attr\">sitemap:</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">sitemap</span>\n      <span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">Plan</span> <span class=\"hljs-string\">de</span> <span class=\"hljs-string\">site</span> <span class=\"hljs-string\">XML</span>\n      <span class=\"hljs-attr\">layout:</span> <span class=\"hljs-string\">sitemap</span>\n      <span class=\"hljs-attr\">output:</span> <span class=\"hljs-string\">xml</span>\n      <span class=\"hljs-attr\">changefreq:</span> <span class=\"hljs-string\">monthly</span>\n      <span class=\"hljs-attr\">priority:</span> <span class=\"hljs-number\">0.5</span>\n      <span class=\"hljs-attr\">published:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">excluded:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">multilingual:</span> <span class=\"hljs-literal\">false</span>\n    <span class=\"hljs-attr\">xsl/atom:</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">xsl/atom</span>\n      <span class=\"hljs-attr\">layout:</span> <span class=\"hljs-string\">feed</span>\n      <span class=\"hljs-attr\">output:</span> <span class=\"hljs-string\">xsl</span>\n      <span class=\"hljs-attr\">uglyurl:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">published:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">excluded:</span> <span class=\"hljs-literal\">true</span>\n    <span class=\"hljs-attr\">xsl/rss:</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">xsl/rss</span>\n      <span class=\"hljs-attr\">layout:</span> <span class=\"hljs-string\">feed</span>\n      <span class=\"hljs-attr\">output:</span> <span class=\"hljs-string\">xsl</span>\n      <span class=\"hljs-attr\">uglyurl:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">published:</span> <span class=\"hljs-literal\">false</span>\n      <span class=\"hljs-attr\">excluded:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<aside class=\"note note-info\"><p>La structure est presque identique à celle de <a href=\"#pages-virtual\"><code translate=\"no\">pages.virtual</code></a>, à l’exception de la clé nommée.</p></aside>\n<p>Chaque page peut être :</p>\n<ol>\n<li>désactivée : <code translate=\"no\">published: false</code></li>\n<li>exclue des pages de liste : <code translate=\"no\">excluded: true</code></li>\n<li>exclue de la localisation : <code translate=\"no\">multilingual: false</code></li>\n</ol>\n<aside class=\"note note-tip\"><p>Depuis la version 8.68.0, vous pouvez surcharger la page <code translate=\"no\">robots.txt</code> par défaut en créant une page avec le même <code translate=\"no\">path</code> :</p>\n<p><em>pages/robots.md</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">layout:</span> <span class=\"hljs-string\">robots</span>\n<span class=\"hljs-attr\">output:</span> <span class=\"hljs-string\">txt</span>\n<span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">User-agent:</span> <span class=\"hljs-string\">AI-bot</span>\n<span class=\"hljs-attr\">Disallow:</span> <span class=\"hljs-string\">/</span></code></pre></aside>\n<h2 id=\"pages-generators\">pages.generators</h2>\n<p>Les générateurs servent à Cecil pour créer des pages supplémentaires (par ex. sitemap, flux, pagination, etc.) à partir de pages existantes, ou à partir d’autres sources comme le fichier de configuration ou des sources externes.</p>\n<p>Voici la liste des générateurs fournis par Cecil, dans un ordre défini :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">generators:</span>\n    <span class=\"hljs-attr\">10:</span> <span class=\"hljs-string\">'Cecil\\Generator\\DefaultPages'</span>\n    <span class=\"hljs-attr\">20:</span> <span class=\"hljs-string\">'Cecil\\Generator\\VirtualPages'</span>\n    <span class=\"hljs-attr\">30:</span> <span class=\"hljs-string\">'Cecil\\Generator\\ExternalBody'</span>\n    <span class=\"hljs-attr\">40:</span> <span class=\"hljs-string\">'Cecil\\Generator\\Section'</span>\n    <span class=\"hljs-attr\">50:</span> <span class=\"hljs-string\">'Cecil\\Generator\\Taxonomy'</span>\n    <span class=\"hljs-attr\">60:</span> <span class=\"hljs-string\">'Cecil\\Generator\\Homepage'</span>\n    <span class=\"hljs-attr\">70:</span> <span class=\"hljs-string\">'Cecil\\Generator\\Pagination'</span>\n    <span class=\"hljs-attr\">80:</span> <span class=\"hljs-string\">'Cecil\\Generator\\Alias'</span>\n    <span class=\"hljs-attr\">90:</span> <span class=\"hljs-string\">'Cecil\\Generator\\Redirect'</span></code></pre>\n<aside class=\"note note-tip\"><p>Vous pouvez étendre Cecil avec un <a href=\"../developers/1-extend.fr.md#generateur-de-pages\">générateur de pages</a>.</p></aside>\n<h2 id=\"pages-subsets\">pages.subsets</h2>\n<p>Les sous-ensembles servent à rendre une partie de la collection de pages, selon un chemin, une langue ou un format de sortie spécifique, avec la commande :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">cecil build --render-subset=&lt;name&gt;</code></pre>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">subsets:</span>\n    <span class=\"hljs-string\">&lt;name&gt;:</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">&lt;path&gt;</span> <span class=\"hljs-comment\"># chemin glob ou chaîne (ex. `blog/*`, `blog`)</span>\n      <span class=\"hljs-attr\">language:</span> <span class=\"hljs-string\">&lt;language&gt;</span> <span class=\"hljs-comment\"># code de langue (ex. `en`, `fr`)</span>\n      <span class=\"hljs-attr\">output:</span> <span class=\"hljs-string\">&lt;output&gt;</span> <span class=\"hljs-comment\"># format de sortie (ex. `html`, `atom`)</span></code></pre>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">pages:</span>\n  <span class=\"hljs-attr\">subsets:</span>\n    <span class=\"hljs-attr\">blog_en:</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">blog</span>\n      <span class=\"hljs-attr\">language:</span> <span class=\"hljs-string\">en</span>\n      <span class=\"hljs-attr\">output:</span> <span class=\"hljs-string\">html</span>\n    <span class=\"hljs-attr\">search_index:</span>\n      <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">'*'</span>\n      <span class=\"hljs-attr\">output:</span> <span class=\"hljs-string\">json</span></code></pre>\n<hr>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/contenu/multilingue/",
      "url": "https://cecil-945.pages.dev/fr/documentation/contenu/multilingue/",
      "title": "Multilingue",
      "summary": "Traduisez les pages via le nom de fichier ou le front matter et liez les pages traduites.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-03T00:00:00+00:00","content_text": "Multilingue\nSi vos pages sont disponibles en plusieurs langues, il existe 2 façons différentes de le définir :\nVia le nom de fichier\nC’est la méthode la plus courante pour traduire une page depuis la langue principale vers une autre langue.\nIl suffit de dupliquer la page de référence et de lui ajouter en suffixe le code de la langue cible (ex. : fr).\nExemple :\n├─ about.md    # the reference page\n└─ about.fr.md # the french version (`fr`)\nVous pouvez changer l’URL de la page traduite avec la variable slug dans le front matter. Par exemple :\n---\nslug: a-propos\n---\n# about.md    -&gt; \/about\/\n# about.fr.md -&gt; \/fr\/a-propos\/\nVia le front matter\nSi vous souhaitez créer une page dans une langue autre que la langue principale, sans qu’elle soit la traduction d’une page existante, vous pouvez utiliser la variable language dans son front matter.\nExemple :\n---\nlanguage: fr\n---\nLier les pages traduites\nChaque page traduite référence les pages dans les autres langues.\nCette collection de pages est disponible dans les templates via la variable suivante :\n{{ page.translations }}\nLa variable langref est fournie par défaut, mais vous pouvez la modifier dans le front matter :\n---\nlangref: my-page-ref\n---",
      "content_html": "<h1>Multilingue</h1>\n<p>Si vos pages sont disponibles en plusieurs <a href=\"../configuration/2-languages.fr.md#languages\">langues</a>, il existe 2 façons différentes de le définir :</p>\n<h2 id=\"via-le-nom-de-fichier\">Via le nom de fichier</h2>\n<p>C’est la méthode la plus courante pour traduire une page depuis la <a href=\"../configuration/2-languages.fr.md#language\">langue</a> principale vers une autre langue.</p>\n<p>Il suffit de dupliquer la page de référence et de lui ajouter en suffixe le <code translate=\"no\">code</code> de la langue cible (ex. : <code translate=\"no\">fr</code>).</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">├─ about.md    # the reference page\n└─ about.fr.md # the french version (`fr`)</code></pre>\n<aside class=\"note note-tip\"><p>Vous pouvez changer l’URL de la page traduite avec la variable <code translate=\"no\">slug</code> dans le front matter. Par exemple :</p>\n<pre><code class=\"language-yml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">slug:</span> <span class=\"hljs-string\">a-propos</span>\n<span class=\"hljs-meta\">---</span>\n<span class=\"hljs-comment\"># about.md    -&gt; /about/</span>\n<span class=\"hljs-comment\"># about.fr.md -&gt; /fr/a-propos/</span></code></pre></aside>\n<h2 id=\"via-le-front-matter\">Via le front matter</h2>\n<p>Si vous souhaitez créer une page dans une langue autre que la langue principale, sans qu’elle soit la traduction d’une page existante, vous pouvez utiliser la variable <code translate=\"no\">language</code> dans son front matter.</p>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">language:</span> <span class=\"hljs-string\">fr</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<h2 id=\"lier-les-pages-traduites\">Lier les pages traduites</h2>\n<p>Chaque page traduite référence les pages dans les autres langues.</p>\n<p>Cette collection de pages est disponible dans les <a href=\"../templates/2-variables.fr.md#page\">templates</a> via la variable suivante :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ page.translations }}</span></code></pre>\n<aside class=\"note note-info\"><p>La variable <code translate=\"no\">langref</code> est fournie par défaut, mais vous pouvez la modifier dans le front matter :</p>\n<pre><code class=\"language-yml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">langref:</span> <span class=\"hljs-string\">my-page-ref</span>\n<span class=\"hljs-meta\">---</span></code></pre></aside>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/commandes/doctor/",
      "url": "https://cecil-945.pages.dev/fr/documentation/commandes/doctor/",
      "title": "doctor",
      "summary": "Diagnostiquer la configuration, le front matter, le SEO et les liens.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-11T00:00:00+00:00","content_text": "doctor\nDiagnostique le site courant et l'environnement Cecil.\nUtilisation\nDescription:\n  Diagnoses the site configuration\n\nUsage:\n  doctor [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                       Use the given path as working directory\n\nOptions:\n  -c, --config=CONFIG        Set the path to an extra configuration file\n  -h, --help                 Display help for the given command. When no command is given display help for the list command\n  -q, --quiet                Do not output any message\n  -V, --version              Display this application version\n      --ansi|--no-ansi       Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction       Do not ask any interactive question\n  -v|vv|vvv, --verbose       Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The doctor command diagnoses the current site and Cecil environment.\n\n    cecil.phar doctor\n    cecil.phar doctor path\/to\/the\/working\/directory\n\n  To inspect a site with an extra configuration file, run:\n\n    cecil.phar doctor --config=config.yml\ndoctor:frontmatter\nValide la syntaxe du front matter des pages.\nDescription:\n  Validates pages front matter syntax\n\nUsage:\n  doctor:frontmatter|doctor:fm [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                  Use the given path as working directory\n\nOptions:\n  -c, --config=CONFIG   Set the path to an extra configuration file\n  -p, --page=PAGE       Validate a single page relative to the pages directory\n      --ansi|--no-ansi  Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction  Do not ask any interactive question\n  -h, --help            Display help for the given command. When no command is given display help for the list command\n  -q, --quiet           Do not output any message\n  -V, --version         Display this application version\n  -v|vv|vvv             Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\ndoctor:seo\nAudite les pages HTML rendues pour détecter les problèmes SEO courants.\nDescription:\n  Audits rendered HTML pages for common SEO issues\n\nUsage:\n  doctor:seo [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                  Use the given path as working directory\n\nOptions:\n  -c, --config=CONFIG   Set the path to an extra configuration file\n  -p, --page=PAGE       Audit a single page relative to the pages directory\n      --format=FORMAT   Output format: text (default) or json\n      --feedback        Include findings with feedback level\n      --include-virtual Include virtual pages (paginated, taxonomies) in audit\n      --fail-on=FAIL-ON Return a failure exit code when findings of this level or higher are found: bad (default), ok, feedback or never\nLa commande construit le site en mode dry-run, puis audite le HTML rendu avec un jeu de contrôles ciblés : balise title, meta description, URL canonique, structure des titres, balises Open Graph, attributs alt des images et longueur estimée du contenu.\nPar défaut, les pages virtuelles (paginées, pages de taxonomie) sont exclues de l'audit. Utilisez --include-virtual pour les inclure.\nPar défaut, les findings de niveau feedback ne sont pas listés.\nUtilisez --feedback pour inclure les findings de niveau feedback en plus des autres findings.\nExportez les résultats en JSON pour l'intégration CI en utilisant --format=json.\nPar défaut, la commande retourne un code de sortie en échec (1) lorsque des findings de niveau bad sont trouvés. Utilisez --fail-on=ok pour échouer également sur les findings ok, --fail-on=feedback pour échouer sur n'importe quel finding, ou --fail-on=never pour toujours réussir.\nConfiguration\nPersonnalisez les seuils d'audit et les contrôles activés dans votre fichier de configuration :\ndoctor:\n  seo:\n    title: { min: 30, max: 60 }\n    description: { min: 120, max: 160 }\n    content: { min_words: 300 }\n    checks:\n      title: true\n      description: true\n      canonical: true\n      h1: true\n      og_tags: true\n      img_alt: true\n      content_length: true\n      lang_attribute: true\ndoctor:links\nContrôle les liens internes et externes des pages rendues.\nDescription:\n  Checks internal and external links of the rendered pages\n\nUsage:\n  doctor:links [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                           Use the given path as working directory\n\nOptions:\n  -c, --config=CONFIG            Set the path to an extra configuration file\n  -p, --page=PAGE                Check links of a single page relative to the pages directory\n      --internal                 Check internal links\n      --external                 Check external links\n      --exclude=EXCLUDE          Exclude links matching this regular expression (multiple values allowed)\n      --timeout=TIMEOUT          External links request timeout, in seconds\n      --concurrency=CONCURRENCY  Number of concurrent external links requests\n      --no-cache                 Do not use cached external links results\n      --format=FORMAT            Output format: text (default) or json\n      --include-virtual          Include virtual pages (paginated, taxonomies) in audit\n      --feedback                 Include findings with feedback level\n      --fail-on=FAIL-ON          Return a failure exit code when findings of this level or higher are found: bad (default), ok, feedback or never\nLa commande construit le site en mode dry-run, puis contrôle les liens trouvés dans les pages HTML rendues : liens (&lt;a&gt;, &lt;area&gt;, &lt;link&gt;), images (src et srcset), scripts, iframes, médias et styles en ligne. Les fichiers CSS liés depuis les pages sont également analysés (url() et @import).\n\nLiens internes : ils doivent cibler une page générée, un fichier statique ou un asset. Les fragments (#ancre) doivent correspondre à l'ID d'un élément de la page cible. Les URL absolues commençant par baseurl sont considérées comme des liens internes.\nLiens externes : ils sont requêtés en HTTP (HEAD, puis GET si le serveur refuse HEAD), en parallèle. Les résultats en succès sont mis en cache (24 heures par défaut) : utilisez --no-cache pour les contrôler à nouveau.\n\nPar défaut, seuls les liens internes sont contrôlés :\nphp cecil.phar doctor:links                       # liens internes (par défaut)\nphp cecil.phar doctor:links --external            # liens externes uniquement\nphp cecil.phar doctor:links --internal --external # les deux\nNiveaux des findings :\n\n\n\nNiveau\nSignification\n\n\n\n\nbad\nLien cassé : cible introuvable, ancre manquante, erreur HTTP (4xx, 5xx), hôte introuvable, etc.\n\n\nok\nLien fonctionnel mais améliorable : redirection, slash final manquant\n\n\nfeedback\nLien invérifiable : accès refusé (401, 403, 429), probablement par une protection anti-bot, ou timeout\n\n\n\nLes liens utilisant d'autres schémas que HTTP (ex. : mailto:, tel:, data:) sont ignorés. Utilisez --exclude (expression régulière, insensible à la casse) pour ignorer d'autres liens.\nLes options --page, --include-virtual, --feedback, --format et --fail-on se comportent comme avec doctor:seo (voir ci-dessus).\nLe contrôle des liens externes nécessite l'extension PHP cURL.\nConfiguration\nPersonnalisez les réglages par défaut dans votre fichier de configuration :\ndoctor:\n  links:\n    internal: true    # contrôle des liens internes\n    external: false   # contrôle des liens externes\n    timeout: 10       # timeout des requêtes des liens externes, en secondes\n    concurrency: 10   # nombre de requêtes simultanées des liens externes\n    cache_ttl: 86400  # durée de mise en cache des résultats en succès des liens externes, en secondes\n    exclude: []       # liens à ignorer (liste d'expressions régulières), ex. : ['linkedin\\.com', '^https:\/\/localhost']\n    useragent: ~      # en-tête User-Agent des requêtes des liens externes (`assets.remote.useragent.default` par défaut)",
      "content_html": "<h1>doctor</h1>\n<p>Diagnostique le site courant et l'environnement Cecil.</p>\n<h2 id=\"utilisation\">Utilisation</h2>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Diagnoses the site configuration\n\nUsage:\n  doctor [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                       Use the given path as working directory\n\nOptions:\n  -c, --config=CONFIG        Set the path to an extra configuration file\n  -h, --help                 Display help for the given command. When no command is given display help for the list command\n  -q, --quiet                Do not output any message\n  -V, --version              Display this application version\n      --ansi|--no-ansi       Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction       Do not ask any interactive question\n  -v|vv|vvv, --verbose       Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug\n\nHelp:\n  The doctor command diagnoses the current site and Cecil environment.\n\n    cecil.phar doctor\n    cecil.phar doctor path/to/the/working/directory\n\n  To inspect a site with an extra configuration file, run:\n\n    cecil.phar doctor --config=config.yml</code></pre>\n<h2 id=\"doctor-frontmatter\">doctor:frontmatter</h2>\n<p>Valide la syntaxe du front matter des pages.</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Validates pages front matter syntax\n\nUsage:\n  doctor:frontmatter|doctor:fm [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                  Use the given path as working directory\n\nOptions:\n  -c, --config=CONFIG   Set the path to an extra configuration file\n  -p, --page=PAGE       Validate a single page relative to the pages directory\n      --ansi|--no-ansi  Force (or disable --no-ansi) ANSI output\n  -n, --no-interaction  Do not ask any interactive question\n  -h, --help            Display help for the given command. When no command is given display help for the list command\n  -q, --quiet           Do not output any message\n  -V, --version         Display this application version\n  -v|vv|vvv             Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug</code></pre>\n<h2 id=\"doctor-seo\">doctor:seo</h2>\n<p>Audite les pages HTML rendues pour détecter les problèmes SEO courants.</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Audits rendered HTML pages for common SEO issues\n\nUsage:\n  doctor:seo [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                  Use the given path as working directory\n\nOptions:\n  -c, --config=CONFIG   Set the path to an extra configuration file\n  -p, --page=PAGE       Audit a single page relative to the pages directory\n      --format=FORMAT   Output format: text (default) or json\n      --feedback        Include findings with feedback level\n      --include-virtual Include virtual pages (paginated, taxonomies) in audit\n      --fail-on=FAIL-ON Return a failure exit code when findings of this level or higher are found: bad (default), ok, feedback or never</code></pre>\n<p>La commande construit le site en mode dry-run, puis audite le HTML rendu avec un jeu de contrôles ciblés : balise title, meta description, URL canonique, structure des titres, balises Open Graph, attributs alt des images et longueur estimée du contenu.</p>\n<p>Par défaut, les pages virtuelles (paginées, pages de taxonomie) sont exclues de l'audit. Utilisez <code translate=\"no\">--include-virtual</code> pour les inclure.</p>\n<p>Par défaut, les findings de niveau <code translate=\"no\">feedback</code> ne sont pas listés.</p>\n<p>Utilisez <code translate=\"no\">--feedback</code> pour inclure les findings de niveau <code translate=\"no\">feedback</code> en plus des autres findings.</p>\n<p>Exportez les résultats en JSON pour l'intégration CI en utilisant <code translate=\"no\">--format=json</code>.</p>\n<p>Par défaut, la commande retourne un code de sortie en échec (<code translate=\"no\">1</code>) lorsque des findings de niveau <code translate=\"no\">bad</code> sont trouvés. Utilisez <code translate=\"no\">--fail-on=ok</code> pour échouer également sur les findings <code translate=\"no\">ok</code>, <code translate=\"no\">--fail-on=feedback</code> pour échouer sur n'importe quel finding, ou <code translate=\"no\">--fail-on=never</code> pour toujours réussir.</p>\n<h3 id=\"configuration\">Configuration</h3>\n<p>Personnalisez les seuils d'audit et les contrôles activés dans votre fichier de configuration :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">doctor:</span>\n  <span class=\"hljs-attr\">seo:</span>\n    <span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">{</span> <span class=\"hljs-attr\">min:</span> <span class=\"hljs-number\">30</span><span class=\"hljs-string\">,</span> <span class=\"hljs-attr\">max:</span> <span class=\"hljs-number\">60</span> <span class=\"hljs-string\">}</span>\n    <span class=\"hljs-attr\">description:</span> <span class=\"hljs-string\">{</span> <span class=\"hljs-attr\">min:</span> <span class=\"hljs-number\">120</span><span class=\"hljs-string\">,</span> <span class=\"hljs-attr\">max:</span> <span class=\"hljs-number\">160</span> <span class=\"hljs-string\">}</span>\n    <span class=\"hljs-attr\">content:</span> <span class=\"hljs-string\">{</span> <span class=\"hljs-attr\">min_words:</span> <span class=\"hljs-number\">300</span> <span class=\"hljs-string\">}</span>\n    <span class=\"hljs-attr\">checks:</span>\n      <span class=\"hljs-attr\">title:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">description:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">canonical:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">h1:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">og_tags:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">img_alt:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">content_length:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">lang_attribute:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<h2 id=\"doctor-links\">doctor:links</h2>\n<p>Contrôle les liens internes et externes des pages rendues.</p>\n<pre><code class=\"language-plaintext hljs plaintext\" translate=\"no\">Description:\n  Checks internal and external links of the rendered pages\n\nUsage:\n  doctor:links [options] [--] [&lt;path&gt;]\n\nArguments:\n  path                           Use the given path as working directory\n\nOptions:\n  -c, --config=CONFIG            Set the path to an extra configuration file\n  -p, --page=PAGE                Check links of a single page relative to the pages directory\n      --internal                 Check internal links\n      --external                 Check external links\n      --exclude=EXCLUDE          Exclude links matching this regular expression (multiple values allowed)\n      --timeout=TIMEOUT          External links request timeout, in seconds\n      --concurrency=CONCURRENCY  Number of concurrent external links requests\n      --no-cache                 Do not use cached external links results\n      --format=FORMAT            Output format: text (default) or json\n      --include-virtual          Include virtual pages (paginated, taxonomies) in audit\n      --feedback                 Include findings with feedback level\n      --fail-on=FAIL-ON          Return a failure exit code when findings of this level or higher are found: bad (default), ok, feedback or never</code></pre>\n<p>La commande construit le site en mode dry-run, puis contrôle les liens trouvés dans les pages HTML rendues : liens (<code translate=\"no\">&lt;a&gt;</code>, <code translate=\"no\">&lt;area&gt;</code>, <code translate=\"no\">&lt;link&gt;</code>), images (<code translate=\"no\">src</code> et <code translate=\"no\">srcset</code>), scripts, iframes, médias et styles en ligne. Les fichiers CSS liés depuis les pages sont également analysés (<code translate=\"no\">url()</code> et <code translate=\"no\">@import</code>).</p>\n<ul>\n<li><strong>Liens internes</strong> : ils doivent cibler une page générée, un fichier statique ou un asset. Les fragments (<code translate=\"no\">#ancre</code>) doivent correspondre à l'ID d'un élément de la page cible. Les URL absolues commençant par <code translate=\"no\">baseurl</code> sont considérées comme des liens internes.</li>\n<li><strong>Liens externes</strong> : ils sont requêtés en HTTP (<code translate=\"no\">HEAD</code>, puis <code translate=\"no\">GET</code> si le serveur refuse <code translate=\"no\">HEAD</code>), en parallèle. Les résultats en succès sont mis en cache (24 heures par défaut) : utilisez <code translate=\"no\">--no-cache</code> pour les contrôler à nouveau.</li>\n</ul>\n<p>Par défaut, seuls les liens internes sont contrôlés :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar doctor:links                       <span class=\"hljs-comment\"># liens internes (par défaut)</span>\nphp cecil.phar doctor:links --external            <span class=\"hljs-comment\"># liens externes uniquement</span>\nphp cecil.phar doctor:links --internal --external <span class=\"hljs-comment\"># les deux</span></code></pre>\n<p>Niveaux des findings :</p>\n<table>\n<thead>\n<tr>\n<th>Niveau</th>\n<th>Signification</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code translate=\"no\">bad</code></td>\n<td>Lien cassé : cible introuvable, ancre manquante, erreur HTTP (4xx, 5xx), hôte introuvable, etc.</td>\n</tr>\n<tr>\n<td><code translate=\"no\">ok</code></td>\n<td>Lien fonctionnel mais améliorable : redirection, slash final manquant</td>\n</tr>\n<tr>\n<td><code translate=\"no\">feedback</code></td>\n<td>Lien invérifiable : accès refusé (401, 403, 429), probablement par une protection anti-bot, ou timeout</td>\n</tr>\n</tbody>\n</table>\n<p>Les liens utilisant d'autres schémas que HTTP (ex. : <code translate=\"no\">mailto:</code>, <code translate=\"no\">tel:</code>, <code translate=\"no\">data:</code>) sont ignorés. Utilisez <code translate=\"no\">--exclude</code> (expression régulière, insensible à la casse) pour ignorer d'autres liens.</p>\n<p>Les options <code translate=\"no\">--page</code>, <code translate=\"no\">--include-virtual</code>, <code translate=\"no\">--feedback</code>, <code translate=\"no\">--format</code> et <code translate=\"no\">--fail-on</code> se comportent comme avec <code translate=\"no\">doctor:seo</code> (voir ci-dessus).</p>\n<aside class=\"note note-info\"><p>Le contrôle des liens externes nécessite l'extension PHP cURL.</p></aside>\n<h3 id=\"configuration-1\">Configuration</h3>\n<p>Personnalisez les réglages par défaut dans votre fichier de configuration :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">doctor:</span>\n  <span class=\"hljs-attr\">links:</span>\n    <span class=\"hljs-attr\">internal:</span> <span class=\"hljs-literal\">true</span>    <span class=\"hljs-comment\"># contrôle des liens internes</span>\n    <span class=\"hljs-attr\">external:</span> <span class=\"hljs-literal\">false</span>   <span class=\"hljs-comment\"># contrôle des liens externes</span>\n    <span class=\"hljs-attr\">timeout:</span> <span class=\"hljs-number\">10</span>       <span class=\"hljs-comment\"># timeout des requêtes des liens externes, en secondes</span>\n    <span class=\"hljs-attr\">concurrency:</span> <span class=\"hljs-number\">10</span>   <span class=\"hljs-comment\"># nombre de requêtes simultanées des liens externes</span>\n    <span class=\"hljs-attr\">cache_ttl:</span> <span class=\"hljs-number\">86400</span>  <span class=\"hljs-comment\"># durée de mise en cache des résultats en succès des liens externes, en secondes</span>\n    <span class=\"hljs-attr\">exclude:</span> <span class=\"hljs-string\">[]</span>       <span class=\"hljs-comment\"># liens à ignorer (liste d'expressions régulières), ex. : ['linkedin\\.com', '^https://localhost']</span>\n    <span class=\"hljs-attr\">useragent:</span> <span class=\"hljs-string\">~</span>      <span class=\"hljs-comment\"># en-tête User-Agent des requêtes des liens externes (`assets.remote.useragent.default` par défaut)</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/donnees-et-statiques/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/donnees-et-statiques/",
      "title": "Données et fichiers statiques",
      "summary": "Options des fichiers de données et des fichiers statiques.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Données et fichiers statiques\nCes options définissent où sont stockés les fichiers de données et les fichiers statiques, et comment ils sont traités.\nDonnées\nEmplacement des fichiers de données et types d’extensions pris en charge.\nFormats pris en charge : YAML, JSON, XML et CSV.\ndata.dir\nRépertoire source des données (data par défaut).\ndata:\n  dir: data\ndata.ext\nTableau des extensions de fichiers.\ndata:\n  ext: [yaml, yml, json, xml, csv]\ndata.load\nActive la collection site.data (true par défaut).\ndata:\n  load: true\n\nFichiers statiques\nGestion des fichiers statiques copiés (PDF, polices, etc.).\nVous devez placer les fichiers d’assets, utilisés par asset(), dans le répertoire assets afin d’éviter des copies de fichiers inutiles.\nstatic.dir\nRépertoire source des fichiers statiques (static par défaut).\nstatic:\n  dir: static\nstatic.target\nRépertoire vers lequel les fichiers statiques sont copiés (root par défaut).\nstatic:\n  target: ''\nstatic.exclude\nListe des fichiers exclus. Accepte les glob, les chaînes et les expressions régulières.\nstatic:\n  exclude: ['sass', 'scss', '*.scss', 'package*.json', 'node_modules']\nSi vous utilisez Bootstrap Icons, vous pouvez exclure node_modules sauf node_modules\/bootstrap-icons avec une expression régulière :\nexclude: ['sass', 'scss', '*.scss', 'package*.json', '#node_modules\/(?!bootstrap-icons)#']\nstatic.load\nActive la collection site.static (false par défaut).\nstatic:\n  load: false\nstatic.mounts\nPermet de copier des fichiers ou répertoires spécifiques vers une destination spécifique.\nstatic:\n  mounts: []\nexemple de static\nstatic:\n  dir: docs\n  target: docs\n  exclude: ['sass', '*.scss', '\/\\.bck$\/']\n  load: true\n  mounts:\n    - source\/path\/file.ext: dest\/path\/file.ext\n    - node_modules\/bootstrap-icons\/font\/fonts: fonts",
      "content_html": "<h1>Données et fichiers statiques</h1>\n<p>Ces options définissent où sont stockés les fichiers de données et les fichiers statiques, et comment ils sont traités.</p>\n<h2 id=\"donnees\">Données</h2>\n<p>Emplacement des fichiers de données et types d’extensions pris en charge.</p>\n<p>Formats pris en charge : YAML, JSON, XML et CSV.</p>\n<h3 id=\"data-dir\">data.dir</h3>\n<p>Répertoire source des données (<code translate=\"no\">data</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">data:</span>\n  <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">data</span></code></pre>\n<h3 id=\"data-ext\">data.ext</h3>\n<p>Tableau des extensions de fichiers.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">data:</span>\n  <span class=\"hljs-attr\">ext:</span> <span class=\"hljs-string\">[yaml,</span> <span class=\"hljs-string\">yml,</span> <span class=\"hljs-string\">json,</span> <span class=\"hljs-string\">xml,</span> <span class=\"hljs-string\">csv]</span></code></pre>\n<h3 id=\"data-load\">data.load</h3>\n<p>Active la collection <code translate=\"no\">site.data</code> (<code translate=\"no\">true</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">data:</span>\n  <span class=\"hljs-attr\">load:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<hr>\n<h2 id=\"fichiers-statiques\">Fichiers statiques</h2>\n<p>Gestion des fichiers statiques copiés (PDF, polices, etc.).</p>\n<aside class=\"note note-important\"><p>Vous devez placer les fichiers d’assets, utilisés par <a href=\"../assets/index.fr.md#asset\"><code translate=\"no\">asset()</code></a>, dans le <a href=\"6-assets.fr.md#assets-dir\"><code translate=\"no\">répertoire assets</code></a> afin d’éviter des copies de fichiers inutiles.</p></aside>\n<h3 id=\"static-dir\">static.dir</h3>\n<p>Répertoire source des fichiers statiques (<code translate=\"no\">static</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">static:</span>\n  <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">static</span></code></pre>\n<h3 id=\"static-target\">static.target</h3>\n<p>Répertoire vers lequel les fichiers statiques sont copiés (<code translate=\"no\">root</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">static:</span>\n  <span class=\"hljs-attr\">target:</span> <span class=\"hljs-string\">''</span></code></pre>\n<h3 id=\"static-exclude\">static.exclude</h3>\n<p>Liste des fichiers exclus. Accepte les glob, les chaînes et les expressions régulières.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">static:</span>\n  <span class=\"hljs-attr\">exclude:</span> <span class=\"hljs-string\">['sass',</span> <span class=\"hljs-string\">'scss'</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">'*.scss'</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">'package*.json'</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">'node_modules'</span><span class=\"hljs-string\">]</span></code></pre>\n<aside class=\"note note-tip\"><p>Si vous utilisez <a href=\"https://icons.getbootstrap.com\" target=\"_blank\" rel=\"noopener noreferrer\">Bootstrap Icons</a>, vous pouvez exclure <code translate=\"no\">node_modules</code> sauf <code translate=\"no\">node_modules/bootstrap-icons</code> avec une expression régulière :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">exclude:</span> <span class=\"hljs-string\">['sass',</span> <span class=\"hljs-string\">'scss'</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">'*.scss'</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">'package*.json'</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">'#node_modules/(?!bootstrap-icons)#'</span><span class=\"hljs-string\">]</span></code></pre></aside>\n<h3 id=\"static-load\">static.load</h3>\n<p>Active la collection <code translate=\"no\">site.static</code> (<code translate=\"no\">false</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">static:</span>\n  <span class=\"hljs-attr\">load:</span> <span class=\"hljs-literal\">false</span></code></pre>\n<h3 id=\"static-mounts\">static.mounts</h3>\n<p>Permet de copier des fichiers ou répertoires spécifiques vers une destination spécifique.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">static:</span>\n  <span class=\"hljs-attr\">mounts:</span> <span class=\"hljs-string\">[]</span></code></pre>\n<h3 id=\"exemple-de-static\">exemple de static</h3>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">static:</span>\n  <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">docs</span>\n  <span class=\"hljs-attr\">target:</span> <span class=\"hljs-string\">docs</span>\n  <span class=\"hljs-attr\">exclude:</span> <span class=\"hljs-string\">['sass',</span> <span class=\"hljs-string\">'*.scss'</span><span class=\"hljs-string\">,</span> <span class=\"hljs-string\">'/\\.bck$/'</span><span class=\"hljs-string\">]</span>\n  <span class=\"hljs-attr\">load:</span> <span class=\"hljs-literal\">true</span>\n  <span class=\"hljs-attr\">mounts:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">source/path/file.ext:</span> <span class=\"hljs-string\">dest/path/file.ext</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">node_modules/bootstrap-icons/font/fonts:</span> <span class=\"hljs-string\">fonts</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/contenu/contenu-dynamique/",
      "url": "https://cecil-945.pages.dev/fr/documentation/contenu/contenu-dynamique/",
      "title": "Contenu dynamique",
      "summary": "Utilisez des variables et expressions Twig dans le contenu des pages.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-09T00:00:00+00:00","content_text": "Contenu dynamique\nPar défaut, le corps d’une page est statique : la syntaxe Twig écrite dans un fichier Markdown est affichée telle quelle.\nVous pouvez créer du contenu dynamique dans une page en utilisant la fonction Twig template_from_string, qui interprète le contenu de la page comme un template Twig.\n{{ include(template_from_string(page.content, \"contenu dynamique pour la page \" ~ page.id)) }}\nAvec cette approche, vous pouvez utiliser n’importe quelle variable de page dans le body de la page.\n---\nvar: 'value'\n---\nLa valeur de `var` est {{ page.var }}.\nActiver le contenu dynamique\nLa méthode recommandée consiste à créer un layout dédié qui surcharge le bloc content, et à ne l’utiliser que pour les pages qui en ont besoin.\n{# layouts\/dynamic.html.twig #}\n{% extends '_default\/page.html.twig' %}\n\n{% block content %}\n{{ include(template_from_string(page.content, \"contenu dynamique pour la page \" ~ page.id)) }}\n{% endblock content %}\nPuis définissez la variable layout dans le front matter de la page :\n---\ntitle: \"Ma page dynamique\"\nlayout: dynamic\n---\nLe second argument de template_from_string est le nom du template : il est affiché dans les messages d’erreur, inclure page.id permet donc de retrouver la page en erreur.\nVariables disponibles\nLe contenu de la page est rendu avec le même contexte que le layout, vous pouvez donc utiliser :\n\nles variables de page : page.title, page.date, page.&lt;variable personnalisée&gt;, etc.\nles variables du site : site.title, site.pages, site.data, etc.\ntoutes les fonctions, filtres et tris disponibles dans les templates ;\nles tags Twig : {% set %}, {% if %}, {% for %}, {% include %}, etc.\n\nFonctionnement\nLe corps Markdown est d’abord converti en HTML, puis le résultat (page.content) est rendu par Twig. Cet ordre a quelques conséquences :\n\nMarkdown échappe les caractères &lt; et &gt;, les opérateurs de comparaison (&gt;, &lt;=) et les fonctions fléchées (=&gt;) ne peuvent donc pas être utilisés dans le corps : le build échoue avec une erreur Unexpected character \"&amp;\".\nUne expression Twig utilisée dans un attribut HTML (ex. : href=\"{{ url(post) }}\") est encodée (URL) par le convertisseur Markdown et ne sera pas évaluée.\nUne expression Twig seule sur sa ligne est encapsulée dans un élément &lt;p&gt;.\nLa syntaxe Twig écrite dans un bloc ou une portion de code est également évaluée.\n\nGardez le corps simple (variables, filtres, conditions courtes) et déplacez le balisage et la logique complexes dans un template partiel ou une macro.\nPour afficher la syntaxe Twig telle quelle, encadrez-la avec le tag verbatim :\n{% verbatim %}`{{ page.title }}`{% endverbatim %}\nPour éviter un élément &lt;p&gt; superflu autour d’un bloc HTML, encadrez l’expression dans un élément HTML, séparé par des retours à la ligne :\n&lt;div&gt;\n{{ include('partials\/latest-posts.html.twig') }}\n&lt;\/div&gt;\nExemple : variables, données et template partiel\nCet exemple montre une page affichant des variables du site et de la page, des données issues d’un fichier de données, ainsi que les derniers articles du blog via un template partiel réutilisable.\nFichier de données :\n# data\/team.yml\n- name: Alice\n  role: Développeuse\n- name: Bob\n  role: Designer\nTemplate partiel, qui reçoit section et limit en paramètres :\n{# layouts\/partials\/latest-posts.html.twig #}\n{% set posts = site.pages.showable|filter_by('section', section|default('blog'))|sort_by_date|slice(0, limit|default(5)) %}\n{% if posts|length &gt; 0 %}\n&lt;ul class=\"latest-posts\"&gt;\n  {% for post in posts %}\n  &lt;li&gt;&lt;a href=\"{{ url(post) }}\"&gt;{{ post.title }}&lt;\/a&gt; &lt;time datetime=\"{{ post.date|date('Y-m-d') }}\"&gt;{{ post.date|format_date('long') }}&lt;\/time&gt;&lt;\/li&gt;\n  {% endfor %}\n&lt;\/ul&gt;\n{% else %}\n&lt;p&gt;Aucun article pour le moment.&lt;\/p&gt;\n{% endif %}\nPage :\n---\ntitle: À propos\nlayout: dynamic\n---\nBienvenue sur **{{ site.title }}** ! Cette page a été publiée le {{ page.date|format_date('long') }}.\n\nNotre équipe compte {{ site.data.team|length }} membres : {{ site.data.team|column('name')|join(', ') }}.\n\n## Derniers articles\n\n&lt;div&gt;\n{{ include('partials\/latest-posts.html.twig', {section: 'blog', limit: 3}) }}\n&lt;\/div&gt;\nRésultat :\n&lt;p&gt;Bienvenue sur &lt;strong&gt;Mon site&lt;\/strong&gt; ! Cette page a été publiée le 9 octobre 2026.&lt;\/p&gt;\n&lt;p&gt;Notre équipe compte 2 membres : Alice, Bob.&lt;\/p&gt;\n&lt;h2 id=\"derniers-articles\"&gt;Derniers articles&lt;\/h2&gt;\n&lt;div&gt;\n&lt;ul class=\"latest-posts\"&gt;\n  &lt;li&gt;&lt;a href=\"\/blog\/post-3\/\"&gt;Post 3&lt;\/a&gt; &lt;time datetime=\"2026-03-01\"&gt;1 mars 2026&lt;\/time&gt;&lt;\/li&gt;\n  &lt;li&gt;&lt;a href=\"\/blog\/post-2\/\"&gt;Post 2&lt;\/a&gt; &lt;time datetime=\"2026-02-01\"&gt;1 février 2026&lt;\/time&gt;&lt;\/li&gt;\n  &lt;li&gt;&lt;a href=\"\/blog\/post-1\/\"&gt;Post 1&lt;\/a&gt; &lt;time datetime=\"2026-01-01\"&gt;1 janvier 2026&lt;\/time&gt;&lt;\/li&gt;\n&lt;\/ul&gt;\n&lt;\/div&gt;\nL’opérateur &gt; et l’attribut href=\"{{ … }}\" fonctionnent ici car ils sont écrits dans le template partiel, et non dans le corps Markdown.\nExemple : shortcodes avec des macros\nLes macros Twig peuvent être utilisées comme shortcodes pour insérer des fragments HTML riches dans le corps d’une page.\nCréez les macros :\n{# layouts\/macros\/shortcodes.html.twig #}\n{% macro youtube(id, title = 'Vidéo YouTube') %}\n&lt;iframe src=\"https:\/\/www.youtube-nocookie.com\/embed\/{{ id }}\" title=\"{{ title }}\" width=\"560\" height=\"315\" loading=\"lazy\" allowfullscreen&gt;&lt;\/iframe&gt;\n{% endmacro %}\n\n{% macro alert(message, type = 'info') %}\n&lt;div class=\"alert alert-{{ type }}\" role=\"alert\"&gt;{{ message }}&lt;\/div&gt;\n{% endmacro %}\nCréez un layout qui importe les macros avant de rendre le contenu :\n{# layouts\/shortcodes.html.twig #}\n{% extends '_default\/page.html.twig' %}\n\n{% block content %}\n{% set imports = \"{% import 'macros\/shortcodes.html.twig' as sc %}\" %}\n{{ include(template_from_string(imports ~ page.content, \"contenu dynamique pour la page \" ~ page.id)) }}\n{% endblock content %}\nUtilisez les shortcodes dans une page :\n---\ntitle: \"Vidéo de démo\"\nlayout: shortcodes\n---\n&lt;div&gt;\n  {{ sc.alert('Cette vidéo est en anglais.', 'warning') }}\n&lt;\/div&gt;\n\n## Démo\n\n&lt;div&gt;\n  {{ sc.youtube('NaB8JBfE7DY', 'Démo de Cecil') }}\n&lt;\/div&gt;\nRésultat :\n&lt;div&gt;\n  &lt;div class=\"alert alert-warning\" role=\"alert\"&gt;Cette vidéo est en anglais.&lt;\/div&gt;\n&lt;\/div&gt;\n&lt;h2 id=\"demo\"&gt;Démo&lt;\/h2&gt;\n&lt;div&gt;\n  &lt;iframe src=\"https:\/\/www.youtube-nocookie.com\/embed\/NaB8JBfE7DY\" title=\"Démo de Cecil\" width=\"560\" height=\"315\" loading=\"lazy\" allowfullscreen&gt;&lt;\/iframe&gt;\n&lt;\/div&gt;\nPour réutiliser des éléments d’interface entre templates et pages, voir aussi les composants.",
      "content_html": "<h1>Contenu dynamique</h1>\n<p>Par défaut, le corps d’une page est statique : la syntaxe Twig écrite dans un fichier Markdown est affichée telle quelle.</p>\n<p>Vous pouvez créer du contenu dynamique dans une page en utilisant la fonction Twig <a href=\"https://twig.symfony.com/doc/3.x/functions/template_from_string.html\" target=\"_blank\" rel=\"noopener noreferrer\"><code translate=\"no\">template_from_string</code></a>, qui interprète le contenu de la page comme un template Twig.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-variable\">{{ <span class=\"hljs-name\">include</span><span class=\"hljs-params\">(template_from_string(page.content, \"contenu dynamique pour la page \" ~ page.id)</span>) }}</span></code></pre>\n<p>Avec cette approche, vous pouvez utiliser n’importe quelle variable de page dans le <em>body</em> de la page.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\">---\nvar: 'value'\n---\nLa valeur de `var` est </span><span class=\"hljs-template-variable\">{{ page.var }}</span><span class=\"xml\">.</span></code></pre>\n<h2 id=\"activer-le-contenu-dynamique\">Activer le contenu dynamique</h2>\n<p>La méthode recommandée consiste à créer un layout dédié qui surcharge le bloc <code translate=\"no\">content</code>, et à ne l’utiliser que pour les pages qui en ont besoin.</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# layouts/dynamic.html.twig #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">extends</span></span> '_default/page.html.twig' %}</span><span class=\"xml\">\n\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">block</span></span> content %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-variable\">{{ <span class=\"hljs-name\">include</span><span class=\"hljs-params\">(template_from_string(page.content, \"contenu dynamique pour la page \" ~ page.id)</span>) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endblock</span></span> content %}</span></code></pre>\n<p>Puis définissez la variable <a href=\"2-front-matter.fr.md#variables-predefinies\"><code translate=\"no\">layout</code></a> dans le front matter de la page :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-meta\">---</span>\n<span class=\"hljs-attr\">title:</span> <span class=\"hljs-string\">\"Ma page dynamique\"</span>\n<span class=\"hljs-attr\">layout:</span> <span class=\"hljs-string\">dynamic</span>\n<span class=\"hljs-meta\">---</span></code></pre>\n<aside class=\"note note-tip\"><p>Le second argument de <code translate=\"no\">template_from_string</code> est le nom du template : il est affiché dans les messages d’erreur, inclure <code translate=\"no\">page.id</code> permet donc de retrouver la page en erreur.</p></aside>\n<h2 id=\"variables-disponibles\">Variables disponibles</h2>\n<p>Le contenu de la page est rendu avec le même contexte que le layout, vous pouvez donc utiliser :</p>\n<ul>\n<li>les variables de page : <code translate=\"no\">page.title</code>, <code translate=\"no\">page.date</code>, <code translate=\"no\">page.&lt;variable personnalisée&gt;</code>, etc.</li>\n<li>les variables du site : <code translate=\"no\">site.title</code>, <code translate=\"no\">site.pages</code>, <a href=\"../templates/2-variables.fr.md#site-data\"><code translate=\"no\">site.data</code></a>, etc.</li>\n<li>toutes les <a href=\"../templates/reference/1-functions.fr.md\">fonctions</a>, <a href=\"../templates/reference/3-filters.fr.md\">filtres</a> et <a href=\"../templates/reference/2-sorts.fr.md\">tris</a> disponibles dans les templates ;</li>\n<li>les tags Twig : <code translate=\"no\">{% set %}</code>, <code translate=\"no\">{% if %}</code>, <code translate=\"no\">{% for %}</code>, <code translate=\"no\">{% include %}</code>, etc.</li>\n</ul>\n<h2 id=\"fonctionnement\">Fonctionnement</h2>\n<p>Le corps Markdown est <strong>d’abord converti en HTML</strong>, puis le résultat (<code translate=\"no\">page.content</code>) est rendu par Twig. Cet ordre a quelques conséquences :</p>\n<ul>\n<li>Markdown échappe les caractères <code translate=\"no\">&lt;</code> et <code translate=\"no\">&gt;</code>, les opérateurs de comparaison (<code translate=\"no\">&gt;</code>, <code translate=\"no\">&lt;=</code>) et les fonctions fléchées (<code translate=\"no\">=&gt;</code>) ne peuvent donc pas être utilisés dans le corps : le build échoue avec une erreur <code translate=\"no\">Unexpected character \"&amp;\"</code>.</li>\n<li>Une expression Twig utilisée dans un attribut HTML (ex. : <code translate=\"no\">href=\"{{ url(post) }}\"</code>) est encodée (URL) par le convertisseur Markdown et ne sera pas évaluée.</li>\n<li>Une expression Twig seule sur sa ligne est encapsulée dans un élément <code translate=\"no\">&lt;p&gt;</code>.</li>\n<li>La syntaxe Twig écrite dans un bloc ou une portion de code <strong>est</strong> également évaluée.</li>\n</ul>\n<aside class=\"note note-tip\"><p>Gardez le corps simple (variables, filtres, conditions courtes) et déplacez le balisage et la logique complexes dans un <a href=\"#exemple-inclure-un-template-partiel\">template partiel</a> ou une <a href=\"#exemple-shortcodes-avec-des-macros\">macro</a>.</p></aside>\n<p>Pour afficher la syntaxe Twig telle quelle, encadrez-la avec le tag <code translate=\"no\">verbatim</code> :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">verbatim</span></span> %}</span><span class=\"xml\">`</span><span class=\"hljs-template-variable\">{{ page.title }}</span><span class=\"xml\">`</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endverbatim</span></span> %}</span></code></pre>\n<p>Pour éviter un élément <code translate=\"no\">&lt;p&gt;</code> superflu autour d’un bloc HTML, encadrez l’expression dans un élément HTML, séparé par des retours à la ligne :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span>&gt;</span>\n</span><span class=\"hljs-template-variable\">{{ <span class=\"hljs-name\">include</span><span class=\"hljs-params\">('partials/latest-posts.html.twig')</span> }}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span></span></code></pre>\n<h2 id=\"exemple-inclure-un-template-partiel\">Exemple : variables, données et template partiel</h2>\n<p>Cet exemple montre une page affichant des variables du site et de la page, des données issues d’un <a href=\"../templates/2-variables.fr.md#site-data\">fichier de données</a>, ainsi que les derniers articles du blog via un template partiel réutilisable.</p>\n<p>Fichier de données :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-comment\"># data/team.yml</span>\n<span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Alice</span>\n  <span class=\"hljs-attr\">role:</span> <span class=\"hljs-string\">Développeuse</span>\n<span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">Bob</span>\n  <span class=\"hljs-attr\">role:</span> <span class=\"hljs-string\">Designer</span></code></pre>\n<p>Template partiel, qui reçoit <code translate=\"no\">section</code> et <code translate=\"no\">limit</code> en paramètres :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# layouts/partials/latest-posts.html.twig #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> posts = site.pages.showable|filter_by('section', section|<span class=\"hljs-keyword\">default</span>('blog'))|sort_by_date|<span class=\"hljs-keyword\">slice</span>(0, limit|<span class=\"hljs-keyword\">default</span>(5)) %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">if</span></span> posts|<span class=\"hljs-keyword\">length</span> &gt; 0 %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul</span> <span class=\"hljs-attr\">class</span>=<span class=\"hljs-string\">\"latest-posts\"</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">for</span></span> post in posts %}</span><span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ url(post) }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ post.title }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span> <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">time</span> <span class=\"hljs-attr\">datetime</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ post.<span class=\"hljs-name\">date</span>|<span class=\"hljs-keyword\">date</span>('Y-m-d') }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ post.<span class=\"hljs-name\">date</span>|format_date('long') }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">time</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n  </span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endfor</span></span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">ul</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\">else</span> %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p</span>&gt;</span>Aucun article pour le moment.<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">p</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endif</span></span> %}</span></code></pre>\n<p>Page :</p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">---\ntitle: À propos\n<span class=\"hljs-section\">layout: dynamic\n---</span>\nBienvenue sur <span class=\"hljs-strong\">**{{ site.title }}**</span> ! Cette page a été publiée le {{ page.date|format_date('long') }}.\n\nNotre équipe compte {{ site.data.team|length }} membres : {{ site.data.team|column('name')|join(', ') }}.\n\n<span class=\"hljs-section\">## Derniers articles</span>\n\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span>&gt;</span></span>\n{{ include('partials/latest-posts.html.twig', {section: 'blog', limit: 3}) }}\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span></span></code></pre>\n<p>Résultat :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p</span>&gt;</span>Bienvenue sur <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">strong</span>&gt;</span>Mon site<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">strong</span>&gt;</span> ! Cette page a été publiée le 9 octobre 2026.<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">p</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p</span>&gt;</span>Notre équipe compte 2 membres : Alice, Bob.<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">p</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2</span> <span class=\"hljs-attr\">id</span>=<span class=\"hljs-string\">\"derniers-articles\"</span>&gt;</span>Derniers articles<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">h2</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">ul</span> <span class=\"hljs-attr\">class</span>=<span class=\"hljs-string\">\"latest-posts\"</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"/blog/post-3/\"</span>&gt;</span>Post 3<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span> <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">time</span> <span class=\"hljs-attr\">datetime</span>=<span class=\"hljs-string\">\"2026-03-01\"</span>&gt;</span>1 mars 2026<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">time</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"/blog/post-2/\"</span>&gt;</span>Post 2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span> <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">time</span> <span class=\"hljs-attr\">datetime</span>=<span class=\"hljs-string\">\"2026-02-01\"</span>&gt;</span>1 février 2026<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">time</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">li</span>&gt;</span><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a</span> <span class=\"hljs-attr\">href</span>=<span class=\"hljs-string\">\"/blog/post-1/\"</span>&gt;</span>Post 1<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">a</span>&gt;</span> <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">time</span> <span class=\"hljs-attr\">datetime</span>=<span class=\"hljs-string\">\"2026-01-01\"</span>&gt;</span>1 janvier 2026<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">time</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">li</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">ul</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span></code></pre>\n<aside class=\"note note-info\"><p>L’opérateur <code translate=\"no\">&gt;</code> et l’attribut <code translate=\"no\">href=\"{{ … }}\"</code> fonctionnent ici car ils sont écrits dans le template partiel, et non dans le corps Markdown.</p></aside>\n<h2 id=\"exemple-shortcodes-avec-des-macros\">Exemple : shortcodes avec des macros</h2>\n<p>Les <a href=\"https://twig.symfony.com/doc/3.x/tags/macro.html\" target=\"_blank\" rel=\"noopener noreferrer\">macros Twig</a> peuvent être utilisées comme <em>shortcodes</em> pour insérer des fragments HTML riches dans le corps d’une page.</p>\n<p>Créez les macros :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# layouts/macros/shortcodes.html.twig #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">macro</span></span> youtube(id, title = 'Vidéo YouTube') %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">iframe</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"https://www.youtube-nocookie.com/embed/</span></span></span><span class=\"hljs-template-variable\">{{ id }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">title</span>=<span class=\"hljs-string\">\"</span></span></span><span class=\"hljs-template-variable\">{{ title }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">width</span>=<span class=\"hljs-string\">\"560\"</span> <span class=\"hljs-attr\">height</span>=<span class=\"hljs-string\">\"315\"</span> <span class=\"hljs-attr\">loading</span>=<span class=\"hljs-string\">\"lazy\"</span> <span class=\"hljs-attr\">allowfullscreen</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">iframe</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endmacro</span></span> %}</span><span class=\"xml\">\n\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">macro</span></span> alert(message, type = 'info') %}</span><span class=\"xml\">\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span> <span class=\"hljs-attr\">class</span>=<span class=\"hljs-string\">\"alert alert-</span></span></span><span class=\"hljs-template-variable\">{{ type }}</span><span class=\"xml\"><span class=\"hljs-tag\"><span class=\"hljs-string\">\"</span> <span class=\"hljs-attr\">role</span>=<span class=\"hljs-string\">\"alert\"</span>&gt;</span></span><span class=\"hljs-template-variable\">{{ message }}</span><span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span>\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endmacro</span></span> %}</span></code></pre>\n<p>Créez un layout qui importe les macros avant de rendre le contenu :</p>\n<pre><code class=\"language-twig hljs twig\" translate=\"no\"><span class=\"hljs-comment\">{# layouts/shortcodes.html.twig #}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">extends</span></span> '_default/page.html.twig' %}</span><span class=\"xml\">\n\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">block</span></span> content %}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">set</span></span> imports = \"{% import 'macros/shortcodes.html.twig' as sc %}</span><span class=\"xml\">\" %}\n</span><span class=\"hljs-template-variable\">{{ <span class=\"hljs-name\">include</span><span class=\"hljs-params\">(template_from_string(imports ~ page.content, \"contenu dynamique pour la page \" ~ page.id)</span>) }}</span><span class=\"xml\">\n</span><span class=\"hljs-template-tag\">{% <span class=\"hljs-name\"><span class=\"hljs-keyword\">endblock</span></span> content %}</span></code></pre>\n<p>Utilisez les shortcodes dans une page :</p>\n<pre><code class=\"language-markdown hljs markdown\" translate=\"no\">---\ntitle: \"Vidéo de démo\"\n<span class=\"hljs-section\">layout: shortcodes\n---</span>\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span>&gt;</span></span>\n  {{ sc.alert('Cette vidéo est en anglais.', 'warning') }}\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span></span>\n\n<span class=\"hljs-section\">## Démo</span>\n\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span>&gt;</span></span>\n  {{ sc.youtube('NaB8JBfE7DY', 'Démo de Cecil') }}\n<span class=\"xml\"><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span></span></code></pre>\n<p>Résultat :</p>\n<pre><code class=\"language-html hljs xml\" translate=\"no\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span> <span class=\"hljs-attr\">class</span>=<span class=\"hljs-string\">\"alert alert-warning\"</span> <span class=\"hljs-attr\">role</span>=<span class=\"hljs-string\">\"alert\"</span>&gt;</span>Cette vidéo est en anglais.<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2</span> <span class=\"hljs-attr\">id</span>=<span class=\"hljs-string\">\"demo\"</span>&gt;</span>Démo<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">h2</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">iframe</span> <span class=\"hljs-attr\">src</span>=<span class=\"hljs-string\">\"https://www.youtube-nocookie.com/embed/NaB8JBfE7DY\"</span> <span class=\"hljs-attr\">title</span>=<span class=\"hljs-string\">\"Démo de Cecil\"</span> <span class=\"hljs-attr\">width</span>=<span class=\"hljs-string\">\"560\"</span> <span class=\"hljs-attr\">height</span>=<span class=\"hljs-string\">\"315\"</span> <span class=\"hljs-attr\">loading</span>=<span class=\"hljs-string\">\"lazy\"</span> <span class=\"hljs-attr\">allowfullscreen</span>&gt;</span><span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">iframe</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">div</span>&gt;</span></code></pre>\n<aside class=\"note note-tip\"><p>Pour réutiliser des éléments d’interface entre templates et pages, voir aussi les <a href=\"../templates/4-components.fr.md\">composants</a>.</p></aside>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/assets/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/assets/",
      "title": "Assets",
      "summary": "Dossier des assets, compilation, minification, images et CDN.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Assets\nGestion des ressources (images, fichiers CSS et JS).\nassets.dir\nRépertoire source des ressources (assets par défaut).\nassets:\n  dir: assets\nassets.target\nRépertoire où les fichiers de ressources distants et redimensionnés sont enregistrés (root par défaut).\nassets:\n  target: ''\nassets.fingerprint\nActive le fingerprinting (cache busting) pour les fichiers de ressources (true par défaut).\nassets:\n  fingerprint: true\nassets.compile\nActive la compilation des fichiers Sass (true par défaut). Voir la documentation de scssphp pour les détails des options.\nassets:\n  compile:\n    style: expanded      # style de compilation (`expanded` ou `compressed`, `expanded` par défaut)\n    import: [sass, scss] # liste des chemins importés (`[sass, scss, node_modules]` par défaut)\n    sourcemap: false     # active les sourcemaps en mode debug (`false` par défaut)\n    variables: []        # liste de variables préconfigurées (vide par défaut)\nsourcemap sert à déboguer la compilation SCSS (mode debug requis).\nassets.minify\nActive la minification CSS et JS (true par défaut).\nassets:\n  minify: true\nassets.images\nGestion des images.\nassets:\n  images:\n    optimize: false # active l’optimisation d’images avec JpegOptim, Optipng, Pngquant 2, SVGO 1, Gifsicle, cwebp, avifenc (`false` par défaut)\n    quality: 75     # qualité d’image pour `optimize` et `resize` (`75` par défaut)\n    responsive:\n      widths: [480, 640, 768, 1024, 1366, 1600, 1920] # largeurs d’image pour l’attribut `srcset`\n      sizes:\n        default: '100vw' # attribut `sizes` par défaut (`100vw` par défaut)\nassets.images.cdn\nL’URL des ressources image peut être facilement remplacée par une url de CDN fournie.\nassets:\n  images:\n    cdn:\n      enabled: false  # active Image CDN (`false` par défaut)\n      canonical: true # `image_url` est canonique (au lieu d’un chemin relatif) (`true` par défaut)\n      remote: true    # prend aussi en charge les images non locales (`true` par défaut)\n      account: 'xxxx' # compte du fournisseur\n      url: 'https:\/\/provider.tld\/%account%\/%image_url%?w=%width%&amp;q=%quality%&amp;format=%format%'\nurl est un modèle qui contient des variables :\n\n%account% remplacé par l’option assets.images.cdn.account\n%image_url% remplacé par l’URL canonique de l’image ou par path\n%width% remplacé par la largeur de l’image\n%quality% remplacé par l’option assets.images.quality\n%format% remplacé par le format de l’image\n\nVoir les fournisseurs CDN.\nassets.remote.useragent\nUser agent utilisé pour télécharger les ressources distantes.\nassets:\n  remote:\n    useragent:\n      default: &lt;string&gt; # user agent par défaut\n      useragent1: &lt;string&gt;\n      useragent2: &lt;string&gt;",
      "content_html": "<h1>Assets</h1>\n<p>Gestion des ressources (images, fichiers CSS et JS).</p>\n<h2 id=\"assets-dir\">assets.dir</h2>\n<p>Répertoire source des ressources (<code translate=\"no\">assets</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">assets</span></code></pre>\n<h2 id=\"assets-target\">assets.target</h2>\n<p>Répertoire où les fichiers de ressources distants et redimensionnés sont enregistrés (<code translate=\"no\">root</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">target:</span> <span class=\"hljs-string\">''</span></code></pre>\n<h2 id=\"assets-fingerprint\">assets.fingerprint</h2>\n<p>Active le fingerprinting (cache busting) pour les fichiers de ressources (<code translate=\"no\">true</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">fingerprint:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<h2 id=\"assets-compile\">assets.compile</h2>\n<p>Active la compilation des fichiers <a href=\"https://sass-lang.com\" target=\"_blank\" rel=\"noopener noreferrer\">Sass</a> (<code translate=\"no\">true</code> par défaut). Voir la <a href=\"https://scssphp.github.io/scssphp/docs/#output-formatting\" target=\"_blank\" rel=\"noopener noreferrer\">documentation de scssphp</a> pour les détails des options.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">compile:</span>\n    <span class=\"hljs-attr\">style:</span> <span class=\"hljs-string\">expanded</span>      <span class=\"hljs-comment\"># style de compilation (`expanded` ou `compressed`, `expanded` par défaut)</span>\n    <span class=\"hljs-attr\">import:</span> <span class=\"hljs-string\">[sass,</span> <span class=\"hljs-string\">scss]</span> <span class=\"hljs-comment\"># liste des chemins importés (`[sass, scss, node_modules]` par défaut)</span>\n    <span class=\"hljs-attr\">sourcemap:</span> <span class=\"hljs-literal\">false</span>     <span class=\"hljs-comment\"># active les sourcemaps en mode debug (`false` par défaut)</span>\n    <span class=\"hljs-attr\">variables:</span> <span class=\"hljs-string\">[]</span>        <span class=\"hljs-comment\"># liste de variables préconfigurées (vide par défaut)</span></code></pre>\n<aside class=\"note note-info\"><p><code translate=\"no\">sourcemap</code> sert à déboguer la compilation SCSS (<a href=\"1-site.fr.md#debug\">mode debug</a> requis).</p></aside>\n<h2 id=\"assets-minify\">assets.minify</h2>\n<p>Active la minification CSS et JS (<code translate=\"no\">true</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">minify:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<h2 id=\"assets-images\">assets.images</h2>\n<p>Gestion des images.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">optimize:</span> <span class=\"hljs-literal\">false</span> <span class=\"hljs-comment\"># active l’optimisation d’images avec JpegOptim, Optipng, Pngquant 2, SVGO 1, Gifsicle, cwebp, avifenc (`false` par défaut)</span>\n    <span class=\"hljs-attr\">quality:</span> <span class=\"hljs-number\">75</span>     <span class=\"hljs-comment\"># qualité d’image pour `optimize` et `resize` (`75` par défaut)</span>\n    <span class=\"hljs-attr\">responsive:</span>\n      <span class=\"hljs-attr\">widths:</span> <span class=\"hljs-string\">[480,</span> <span class=\"hljs-number\">640</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">768</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">1024</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">1366</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">1600</span><span class=\"hljs-string\">,</span> <span class=\"hljs-number\">1920</span><span class=\"hljs-string\">]</span> <span class=\"hljs-comment\"># largeurs d’image pour l’attribut `srcset`</span>\n      <span class=\"hljs-attr\">sizes:</span>\n        <span class=\"hljs-attr\">default:</span> <span class=\"hljs-string\">'100vw'</span> <span class=\"hljs-comment\"># attribut `sizes` par défaut (`100vw` par défaut)</span></code></pre>\n<h2 id=\"assets-images-cdn\">assets.images.cdn</h2>\n<p>L’URL des ressources image peut être facilement remplacée par une <code translate=\"no\">url</code> de CDN fournie.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">cdn:</span>\n      <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">false</span>  <span class=\"hljs-comment\"># active Image CDN (`false` par défaut)</span>\n      <span class=\"hljs-attr\">canonical:</span> <span class=\"hljs-literal\">true</span> <span class=\"hljs-comment\"># `image_url` est canonique (au lieu d’un chemin relatif) (`true` par défaut)</span>\n      <span class=\"hljs-attr\">remote:</span> <span class=\"hljs-literal\">true</span>    <span class=\"hljs-comment\"># prend aussi en charge les images non locales (`true` par défaut)</span>\n      <span class=\"hljs-attr\">account:</span> <span class=\"hljs-string\">'xxxx'</span> <span class=\"hljs-comment\"># compte du fournisseur</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">'https://provider.tld/%account%/%image_url%?w=%width%&amp;q=%quality%&amp;format=%format%'</span></code></pre>\n<p><code translate=\"no\">url</code> est un modèle qui contient des variables :</p>\n<ul>\n<li><code translate=\"no\">%account%</code> remplacé par l’option <code translate=\"no\">assets.images.cdn.account</code></li>\n<li><code translate=\"no\">%image_url%</code> remplacé par l’URL canonique de l’image ou par <code translate=\"no\">path</code></li>\n<li><code translate=\"no\">%width%</code> remplacé par la largeur de l’image</li>\n<li><code translate=\"no\">%quality%</code> remplacé par l’option <code translate=\"no\">assets.images.quality</code></li>\n<li><code translate=\"no\">%format%</code> remplacé par le format de l’image</li>\n</ul>\n<p>Voir les <a href=\"../assets/3-cdn-providers.fr.md\"><strong>fournisseurs CDN</strong></a>.</p>\n<h2 id=\"assets-remote-useragent\">assets.remote.useragent</h2>\n<p>User agent utilisé pour télécharger les ressources distantes.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">remote:</span>\n    <span class=\"hljs-attr\">useragent:</span>\n      <span class=\"hljs-attr\">default:</span> <span class=\"hljs-string\">&lt;string&gt;</span> <span class=\"hljs-comment\"># user agent par défaut</span>\n      <span class=\"hljs-attr\">useragent1:</span> <span class=\"hljs-string\">&lt;string&gt;</span>\n      <span class=\"hljs-attr\">useragent2:</span> <span class=\"hljs-string\">&lt;string&gt;</span></code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/layouts/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/layouts/",
      "title": "Layouts",
      "summary": "Dossier des templates, échappement, images, traductions et composants.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Layouts\nOptions des templates.\nlayouts.dir\nRépertoire source des templates (layouts par défaut).\nlayouts:\n  dir: layouts\nlayouts.autoescape\nSurcharge l’option Twig autoescape (false par défaut).\nSi la valeur est null, Cecil applique une stratégie basée sur l’extension du nom de template :\n\n*.js.twig -&gt; js\n*.css.twig -&gt; css\n*.html.twig et *.twig -&gt; html\ntoute autre extension -&gt; false\n\nlayouts:\n  autoescape: false  # désactive l’échappement automatique (par défaut)\n  #autoescape: null  # utilise la stratégie automatique Cecil selon l’extension du template\n  #autoescape: html\n  #autoescape: js\nlayouts.images\nOptions de gestion des images.\nlayouts:\n  images:\n    formats: []       # utilisé par la fonction `html` : ajoute des formats d’image alternatifs comme `source` (ex. `[avif, webp]`, tableau vide par défaut)\n    responsive: false # utilisé par la fonction `html` : ajoute des images responsives ('width' ou 'density', `false` par défaut)\n    placeholder: ''   # utilisé par la fonction `html` : remplit l’arrière-plan de l’image avant son chargement (`color` ou `lqip`, désactivé par défaut)\n    dark_suffix: ''   # suffixe de l’image variante sombre (ex. `.dark`), désactivé par défaut\n    mobile_suffix: '' # suffixe de l’image variante mobile (ex. `.mobile`), désactivé par défaut\n    mobile_media_query: '(max-width: 767px)' # media query de la `&lt;source&gt;` de la variante mobile\nlayouts.translations\nOptions de gestion des traductions.\nlayouts:\n  translations:\n    dir: translations # répertoire source des traductions (`translations` par défaut)\n    formats:          # formats de traduction pris en charge\n      yaml:\n        loader: Symfony\\Component\\Translation\\Loader\\YamlFileLoader\n        ext: [yml, yaml]\n      mo:\n        loader: Symfony\\Component\\Translation\\Loader\\MoFileLoader\n        ext: [mo]\nChaque format de traduction définit :\n\nloader : classe du chargeur de traduction Symfony\next : une ou plusieurs extensions de fichier associées à ce format\n\nlayouts.components\nOptions des composants de template.\nlayouts:\n  components:\n    dir: components # répertoire source des composants (`components` par défaut)\n    ext: twig       # extension des fichiers de composants (`twig` par défaut)\nlayouts.sections\nAssocie une section aux layouts d’une autre section : le nom associé est utilisé à la place de &lt;section&gt; par les règles de recherche de la section et de ses pages.\nlayouts:\n  sections:\n    news: blog # la section « news » est rendue avec `blog\/list.html.twig` et ses pages avec `blog\/page.html.twig`\nUne sous-section se replie déjà sur les layouts de ses sections parentes : aucune association n’est nécessaire pour cela.\n",
      "content_html": "<h1>Layouts</h1>\n<p>Options des templates.</p>\n<h2 id=\"layouts-dir\">layouts.dir</h2>\n<p>Répertoire source des templates (<code translate=\"no\">layouts</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">layouts:</span>\n  <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">layouts</span></code></pre>\n<h2 id=\"layouts-autoescape\">layouts.autoescape</h2>\n<p>Surcharge l’option Twig <code translate=\"no\">autoescape</code> (<code translate=\"no\">false</code> par défaut).</p>\n<p>Si la valeur est <code translate=\"no\">null</code>, Cecil applique une stratégie basée sur l’extension du nom de template :</p>\n<ul>\n<li><code translate=\"no\">*.js.twig</code> -&gt; <code translate=\"no\">js</code></li>\n<li><code translate=\"no\">*.css.twig</code> -&gt; <code translate=\"no\">css</code></li>\n<li><code translate=\"no\">*.html.twig</code> et <code translate=\"no\">*.twig</code> -&gt; <code translate=\"no\">html</code></li>\n<li>toute autre extension -&gt; <code translate=\"no\">false</code></li>\n</ul>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">layouts:</span>\n  <span class=\"hljs-attr\">autoescape:</span> <span class=\"hljs-literal\">false</span>  <span class=\"hljs-comment\"># désactive l’échappement automatique (par défaut)</span>\n  <span class=\"hljs-comment\">#autoescape: null  # utilise la stratégie automatique Cecil selon l’extension du template</span>\n  <span class=\"hljs-comment\">#autoescape: html</span>\n  <span class=\"hljs-comment\">#autoescape: js</span></code></pre>\n<h2 id=\"layouts-images\">layouts.images</h2>\n<p>Options de gestion des images.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">layouts:</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">formats:</span> <span class=\"hljs-string\">[]</span>       <span class=\"hljs-comment\"># utilisé par la fonction `html` : ajoute des formats d’image alternatifs comme `source` (ex. `[avif, webp]`, tableau vide par défaut)</span>\n    <span class=\"hljs-attr\">responsive:</span> <span class=\"hljs-literal\">false</span> <span class=\"hljs-comment\"># utilisé par la fonction `html` : ajoute des images responsives ('width' ou 'density', `false` par défaut)</span>\n    <span class=\"hljs-attr\">placeholder:</span> <span class=\"hljs-string\">''</span>   <span class=\"hljs-comment\"># utilisé par la fonction `html` : remplit l’arrière-plan de l’image avant son chargement (`color` ou `lqip`, désactivé par défaut)</span>\n    <span class=\"hljs-attr\">dark_suffix:</span> <span class=\"hljs-string\">''</span>   <span class=\"hljs-comment\"># suffixe de l’image variante sombre (ex. `.dark`), désactivé par défaut</span>\n    <span class=\"hljs-attr\">mobile_suffix:</span> <span class=\"hljs-string\">''</span> <span class=\"hljs-comment\"># suffixe de l’image variante mobile (ex. `.mobile`), désactivé par défaut</span>\n    <span class=\"hljs-attr\">mobile_media_query:</span> <span class=\"hljs-string\">'(max-width: 767px)'</span> <span class=\"hljs-comment\"># media query de la `&lt;source&gt;` de la variante mobile</span></code></pre>\n<h2 id=\"layouts-translations\">layouts.translations</h2>\n<p>Options de gestion des traductions.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">layouts:</span>\n  <span class=\"hljs-attr\">translations:</span>\n    <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">translations</span> <span class=\"hljs-comment\"># répertoire source des traductions (`translations` par défaut)</span>\n    <span class=\"hljs-attr\">formats:</span>          <span class=\"hljs-comment\"># formats de traduction pris en charge</span>\n      <span class=\"hljs-attr\">yaml:</span>\n        <span class=\"hljs-attr\">loader:</span> <span class=\"hljs-string\">Symfony\\Component\\Translation\\Loader\\YamlFileLoader</span>\n        <span class=\"hljs-attr\">ext:</span> <span class=\"hljs-string\">[yml,</span> <span class=\"hljs-string\">yaml]</span>\n      <span class=\"hljs-attr\">mo:</span>\n        <span class=\"hljs-attr\">loader:</span> <span class=\"hljs-string\">Symfony\\Component\\Translation\\Loader\\MoFileLoader</span>\n        <span class=\"hljs-attr\">ext:</span> <span class=\"hljs-string\">[mo]</span></code></pre>\n<p>Chaque format de traduction définit :</p>\n<ul>\n<li><code translate=\"no\">loader</code> : classe du chargeur de traduction Symfony</li>\n<li><code translate=\"no\">ext</code> : une ou plusieurs extensions de fichier associées à ce format</li>\n</ul>\n<h2 id=\"layouts-components\">layouts.components</h2>\n<p>Options des <a href=\"../templates/4-components.fr.md\">composants de template</a>.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">layouts:</span>\n  <span class=\"hljs-attr\">components:</span>\n    <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">components</span> <span class=\"hljs-comment\"># répertoire source des composants (`components` par défaut)</span>\n    <span class=\"hljs-attr\">ext:</span> <span class=\"hljs-string\">twig</span>       <span class=\"hljs-comment\"># extension des fichiers de composants (`twig` par défaut)</span></code></pre>\n<h2 id=\"layouts-sections\">layouts.sections</h2>\n<p>Associe une section aux layouts d’une autre section : le nom associé est utilisé à la place de <code translate=\"no\">&lt;section&gt;</code> par les <a href=\"../templates/1-lookup-rules.fr.md#regles-de-recherche\">règles de recherche</a> de la section et de ses pages.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">layouts:</span>\n  <span class=\"hljs-attr\">sections:</span>\n    <span class=\"hljs-attr\">news:</span> <span class=\"hljs-string\">blog</span> <span class=\"hljs-comment\"># la section « news » est rendue avec `blog/list.html.twig` et ses pages avec `blog/page.html.twig`</span></code></pre>\n<aside class=\"note note-tip\"><p>Une <a href=\"../content/1-pages.fr.md#sous-section\">sous-section</a> se replie déjà sur les layouts de ses sections parentes : aucune association n’est nécessaire pour cela.</p></aside>\n<hr>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/sortie/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/sortie/",
      "title": "Sortie",
      "summary": "Dossier de sortie, formats et post-traitement.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Sortie\nDéfinit où et dans quel format les pages sont rendues.\noutput.dir\nRépertoire où les fichiers de pages rendues sont enregistrés (_site par défaut).\noutput:\n  dir: _site\noutput.formats\nListe de définition des formats de sortie, utilisés pour rendre les pages (par ex. HTML, Atom, RSS, JSON, XML, etc.).\noutput:\n  formats:\n    - name: &lt;name&gt;            # nom du format, par ex. `html` (requis)\n      mediatype: &lt;media type&gt; # type MIME, ex. `text\/html` (facultatif)\n      subpath: &lt;sub path&gt;     # sous-chemin, ex. `amp` dans `path\/amp\/index.html` (facultatif)\n      filename: &lt;file name&gt;   # nom du fichier, ex. `index` dans `path\/index.html` (facultatif)\n      extension: &lt;extension&gt;  # extension du fichier, ex. `html` dans `path\/index.html` (requis)\n      exclude: [&lt;variable&gt;]   # n’applique pas ce format aux pages identifiées par les variables listées, ex. `[redirect, paginated]` (facultatif)\nCes formats sont utilisés dans la configuration output.pagetypeformats et dans la variable de page output.\nFormats par défaut\nCecil fournit quelques formats par défaut, qui peuvent être surchargés dans le fichier de configuration : html (par défaut), atom, rss, json, xml, txt, amp, js, webmanifest, xsl, jsonfeed, iframe, oembed.\noutput.pagetypeformats\nIl n’est pas nécessaire de définir la variable output pour chaque page, car Cecil applique automatiquement les formats définis pour chaque type de page (homepage, page, section, vocabulary et term).\noutput:\n  pagetypeformats:\n    page: [&lt;format&gt;]\n    homepage: [&lt;format&gt;]\n    section: [&lt;format&gt;]\n    vocabulary: [&lt;format&gt;]\n    term: [&lt;format&gt;]\nPlusieurs formats peuvent être définis pour un même type de page. Par exemple, le type de page section peut être rendu automatiquement en HTML et Atom :\noutput:\n  pagetypeformats:\n    section: [html, atom]\nPour rendre une page, Cecil recherche un template nommé &lt;layout&gt;.&lt;format&gt;.twig (ex. page.html.twig).\nexemple de output\noutput:\n  dir: _site\n  formats:\n    - name: html\n      mediatype: text\/html\n      filename: index\n      extension: html\n    - name: atom\n      mediatype: application\/xml\n      filename: atom\n      extension: xml\n      exclude: [redirect, paginated]\n  pagetypeformats:\n    page: [html]\n    homepage: [html, atom]\n    section: [html, atom]\n    vocabulary: [html]\n    term: [html, atom]\nPost-process\nVous pouvez étendre les capacités de Cecil avec un post-processeur de sortie pour modifier les fichiers de sortie après leur génération.\n",
      "content_html": "<h1>Sortie</h1>\n<p>Définit où et dans quel format les pages sont rendues.</p>\n<h2 id=\"output-dir\">output.dir</h2>\n<p>Répertoire où les fichiers de pages rendues sont enregistrés (<code translate=\"no\">_site</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">output:</span>\n  <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">_site</span></code></pre>\n<h2 id=\"output-formats\">output.formats</h2>\n<p>Liste de définition des formats de sortie, utilisés pour rendre les pages (par ex. HTML, Atom, RSS, JSON, XML, etc.).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">output:</span>\n  <span class=\"hljs-attr\">formats:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">&lt;name&gt;</span>            <span class=\"hljs-comment\"># nom du format, par ex. `html` (requis)</span>\n      <span class=\"hljs-attr\">mediatype:</span> <span class=\"hljs-string\">&lt;media</span> <span class=\"hljs-string\">type&gt;</span> <span class=\"hljs-comment\"># type MIME, ex. `text/html` (facultatif)</span>\n      <span class=\"hljs-attr\">subpath:</span> <span class=\"hljs-string\">&lt;sub</span> <span class=\"hljs-string\">path&gt;</span>     <span class=\"hljs-comment\"># sous-chemin, ex. `amp` dans `path/amp/index.html` (facultatif)</span>\n      <span class=\"hljs-attr\">filename:</span> <span class=\"hljs-string\">&lt;file</span> <span class=\"hljs-string\">name&gt;</span>   <span class=\"hljs-comment\"># nom du fichier, ex. `index` dans `path/index.html` (facultatif)</span>\n      <span class=\"hljs-attr\">extension:</span> <span class=\"hljs-string\">&lt;extension&gt;</span>  <span class=\"hljs-comment\"># extension du fichier, ex. `html` dans `path/index.html` (requis)</span>\n      <span class=\"hljs-attr\">exclude:</span> <span class=\"hljs-string\">[&lt;variable&gt;]</span>   <span class=\"hljs-comment\"># n’applique pas ce format aux pages identifiées par les variables listées, ex. `[redirect, paginated]` (facultatif)</span></code></pre>\n<p>Ces formats sont utilisés dans la configuration <a href=\"#output-pagetypeformats\"><code translate=\"no\">output.pagetypeformats</code></a> et dans la variable de page <a href=\"../content/2-front-matter.fr.md#output\"><code translate=\"no\">output</code></a>.</p>\n<h3 id=\"formats-par-defaut\">Formats par défaut</h3>\n<p>Cecil fournit quelques <a href=\"https://github.com/Cecilapp/Cecil/blob/main/config/base.php#L81-L162\" target=\"_blank\" rel=\"noopener noreferrer\">formats par défaut</a>, qui peuvent être surchargés dans le fichier de configuration : <code translate=\"no\">html</code> (par défaut), <code translate=\"no\">atom</code>, <code translate=\"no\">rss</code>, <code translate=\"no\">json</code>, <code translate=\"no\">xml</code>, <code translate=\"no\">txt</code>, <code translate=\"no\">amp</code>, <code translate=\"no\">js</code>, <code translate=\"no\">webmanifest</code>, <code translate=\"no\">xsl</code>, <code translate=\"no\">jsonfeed</code>, <code translate=\"no\">iframe</code>, <code translate=\"no\">oembed</code>.</p>\n<h2 id=\"output-pagetypeformats\">output.pagetypeformats</h2>\n<p>Il n’est pas nécessaire de définir la variable <code translate=\"no\">output</code> pour chaque page, car Cecil applique automatiquement les formats définis pour chaque type de page (<code translate=\"no\">homepage</code>, <code translate=\"no\">page</code>, <code translate=\"no\">section</code>, <code translate=\"no\">vocabulary</code> et <code translate=\"no\">term</code>).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">output:</span>\n  <span class=\"hljs-attr\">pagetypeformats:</span>\n    <span class=\"hljs-attr\">page:</span> <span class=\"hljs-string\">[&lt;format&gt;]</span>\n    <span class=\"hljs-attr\">homepage:</span> <span class=\"hljs-string\">[&lt;format&gt;]</span>\n    <span class=\"hljs-attr\">section:</span> <span class=\"hljs-string\">[&lt;format&gt;]</span>\n    <span class=\"hljs-attr\">vocabulary:</span> <span class=\"hljs-string\">[&lt;format&gt;]</span>\n    <span class=\"hljs-attr\">term:</span> <span class=\"hljs-string\">[&lt;format&gt;]</span></code></pre>\n<p>Plusieurs formats peuvent être définis pour un même type de page. Par exemple, le type de page <code translate=\"no\">section</code> peut être rendu automatiquement en HTML et Atom :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">output:</span>\n  <span class=\"hljs-attr\">pagetypeformats:</span>\n    <span class=\"hljs-attr\">section:</span> <span class=\"hljs-string\">[html,</span> <span class=\"hljs-string\">atom]</span></code></pre>\n<aside class=\"note note-info\"><p>Pour rendre une page, <a href=\"../templates/1-lookup-rules.fr.md#regles-de-recherche\">Cecil recherche un template</a> nommé <code translate=\"no\">&lt;layout&gt;.&lt;format&gt;.twig</code> (ex. <code translate=\"no\">page.html.twig</code>).</p></aside>\n<h2 id=\"exemple-de-output\">exemple de output</h2>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">output:</span>\n  <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">_site</span>\n  <span class=\"hljs-attr\">formats:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">html</span>\n      <span class=\"hljs-attr\">mediatype:</span> <span class=\"hljs-string\">text/html</span>\n      <span class=\"hljs-attr\">filename:</span> <span class=\"hljs-string\">index</span>\n      <span class=\"hljs-attr\">extension:</span> <span class=\"hljs-string\">html</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">name:</span> <span class=\"hljs-string\">atom</span>\n      <span class=\"hljs-attr\">mediatype:</span> <span class=\"hljs-string\">application/xml</span>\n      <span class=\"hljs-attr\">filename:</span> <span class=\"hljs-string\">atom</span>\n      <span class=\"hljs-attr\">extension:</span> <span class=\"hljs-string\">xml</span>\n      <span class=\"hljs-attr\">exclude:</span> <span class=\"hljs-string\">[redirect,</span> <span class=\"hljs-string\">paginated]</span>\n  <span class=\"hljs-attr\">pagetypeformats:</span>\n    <span class=\"hljs-attr\">page:</span> <span class=\"hljs-string\">[html]</span>\n    <span class=\"hljs-attr\">homepage:</span> <span class=\"hljs-string\">[html,</span> <span class=\"hljs-string\">atom]</span>\n    <span class=\"hljs-attr\">section:</span> <span class=\"hljs-string\">[html,</span> <span class=\"hljs-string\">atom]</span>\n    <span class=\"hljs-attr\">vocabulary:</span> <span class=\"hljs-string\">[html]</span>\n    <span class=\"hljs-attr\">term:</span> <span class=\"hljs-string\">[html,</span> <span class=\"hljs-string\">atom]</span></code></pre>\n<h2 id=\"post-process\">Post-process</h2>\n<p>Vous pouvez étendre les capacités de Cecil avec un <a href=\"../developers/1-extend.fr.md#post-processeur-de-rendu\">post-processeur de sortie</a> pour modifier les fichiers de sortie après leur génération.</p>\n<hr>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/cache/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/cache/",
      "title": "Cache",
      "summary": "Cache des assets, des templates et des traductions.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-05T00:00:00+00:00","content_text": "Cache\nOptions de cache.\ncache.enabled\nLe cache est activé par défaut (true), mais vous pouvez le désactiver avec :\ncache:\n  enabled: false\nIl n’est pas recommandé de désactiver le cache pour des raisons de performance.\ncache.dir\nRépertoire où les fichiers de cache sont stockés (.cache par défaut).\ncache:\n  dir: '.cache'\nLe répertoire de cache est relatif au répertoire du site, mais vous pouvez utiliser un chemin absolu : cela peut être utile pour stocker le cache dans un répertoire partagé.\ncache.assets\nOptions du cache des ressources.\ncache.assets.ttl\nTemps de vie du cache des ressources en secondes (null par défaut = aucune expiration).\ncache:\n  assets:\n    ttl: ~\ncache.assets.remote.ttl\nTemps de vie du cache des ressources distantes en secondes (7 jours par défaut).\ncache:\n  assets:\n    remotes:\n      ttl: 604800 # 7 jours\ncache.templates\nDésactive le cache des templates avec false (true par défaut).\ncache:\n  templates: true\nVoir la documentation du cache des templates pour plus de détails.\ncache.translations\nDésactive le cache des traductions avec false (true par défaut).\ncache:\n  translations: true\n",
      "content_html": "<h1>Cache</h1>\n<p>Options de cache.</p>\n<h2 id=\"cache-enabled\">cache.enabled</h2>\n<p>Le cache est activé par défaut (<code translate=\"no\">true</code>), mais vous pouvez le désactiver avec :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">cache:</span>\n  <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">false</span></code></pre>\n<aside class=\"note note-warning\"><p>Il n’est pas recommandé de désactiver le cache pour des raisons de performance.</p></aside>\n<h2 id=\"cache-dir\">cache.dir</h2>\n<p>Répertoire où les fichiers de cache sont stockés (<code translate=\"no\">.cache</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">cache:</span>\n  <span class=\"hljs-attr\">dir:</span> <span class=\"hljs-string\">'.cache'</span></code></pre>\n<aside class=\"note note-info\"><p>Le répertoire de cache est relatif au répertoire du site, mais vous pouvez utiliser un chemin absolu : cela peut être utile pour stocker le cache dans un répertoire partagé.</p></aside>\n<h2 id=\"cache-assets\">cache.assets</h2>\n<p>Options du cache des ressources.</p>\n<h3 id=\"cache-assets-ttl\">cache.assets.ttl</h3>\n<p>Temps de vie du cache des ressources en secondes (<code translate=\"no\">null</code> par défaut = aucune expiration).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">cache:</span>\n  <span class=\"hljs-attr\">assets:</span>\n    <span class=\"hljs-attr\">ttl:</span> <span class=\"hljs-string\">~</span></code></pre>\n<h3 id=\"cache-assets-remote-ttl\">cache.assets.remote.ttl</h3>\n<p>Temps de vie du cache des ressources distantes en secondes (7 jours par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">cache:</span>\n  <span class=\"hljs-attr\">assets:</span>\n    <span class=\"hljs-attr\">remotes:</span>\n      <span class=\"hljs-attr\">ttl:</span> <span class=\"hljs-number\">604800</span> <span class=\"hljs-comment\"># 7 jours</span></code></pre>\n<h2 id=\"cache-templates\">cache.templates</h2>\n<p>Désactive le cache des templates avec <code translate=\"no\">false</code> (<code translate=\"no\">true</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">cache:</span>\n  <span class=\"hljs-attr\">templates:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<aside class=\"note note-info\"><p>Voir la <a href=\"../templates/6-cache.fr.md\">documentation du cache des templates</a> pour plus de détails.</p></aside>\n<h2 id=\"cache-translations\">cache.translations</h2>\n<p>Désactive le cache des traductions avec <code translate=\"no\">false</code> (<code translate=\"no\">true</code> par défaut).</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">cache:</span>\n  <span class=\"hljs-attr\">translations:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<hr>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/serveur/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/serveur/",
      "title": "Serveur et optimisation",
      "summary": "En-têtes du serveur local et optimisation de la sortie.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Serveur et optimisation\nCes options configurent le serveur de prévisualisation local et l’optimisation des fichiers générés.\nServeur\nserver.headers\nVous pouvez définir des en-têtes HTTP personnalisés, utilisés par le serveur d’aperçu local.\nDepuis la version 8.38.0, l’option headers a été déplacée dans la section server.headers.\nserver:\n  headers:\n    - path: &lt;path&gt; # chemin relatif, préfixé par un slash. Prend en charge le joker \"*\".\n      headers:\n        - key: &lt;key&gt;\n          value: \"&lt;value&gt;\"\nC’est utile pour tester une Content Security Policy ou Cache-Control personnalisée.\nExemple :\nserver:\n  headers:\n    - path: \/*\n      headers:\n        - key: X-Frame-Options\n          value: \"SAMEORIGIN\"\n        - key: X-XSS-Protection\n          value: \"1; mode=block\"\n        - key: X-Content-Type-Options\n          value: \"nosniff\"\n        - key: Content-Security-Policy\n          value: \"default-src 'self'; object-src 'self'; img-src 'self'\"\n        - key: Strict-Transport-Security\n          value: \"max-age=31536000; includeSubDomains; preload\"\n    - path: \/assets\/*\n      headers:\n        - key: Cache-Control\n          value: \"public, max-age=31536000\"\n    - path: \/foo.html\n      headers:\n        - key: Foo\n          value: \"bar\"\n\nOptimisation\nLes options d’optimisation permettent d’activer la compression des fichiers de sortie : HTML, CSS, JavaScript et images.\noptimize:\n  enabled: false     # active l’optimisation des fichiers (`false` par défaut)\n  html:\n    enabled: true    # active l’optimisation des fichiers HTML\n    ext: [html, htm]   # extensions de fichiers prises en charge\n  css:\n    enabled: true    # active l’optimisation des fichiers CSS\n    ext: [css]         # extensions de fichiers prises en charge\n  js:\n    enabled: true    # active l’optimisation des fichiers JavaScript\n    ext: [js]          # extensions de fichiers prises en charge\n  images:\n    enabled: true    # active l’optimisation des fichiers images\n    ext: [jpeg, jpg, png, gif, webp, svg, avif] # extensions de fichiers prises en charge\nCette option est désactivée par défaut et peut être activée via :\noptimize: true\nUne fois l’option globale activée, les 4 types de fichiers seront traités.\nIl est possible de désactiver chacun d’eux via enabled: false et de modifier l’extension des fichiers traités via ext.\nIl est également possible d’activer cette option via la CLI lors de l’utilisation des commandes \"build\" et \"serve\" avec l’option --optimize.\nLe compresseur d’images utilisera les binaires suivants s’ils sont présents sur le système : JpegOptim, Optipng, Pngquant 2, SVGO, Gifsicle, cwebp et avifenc.\n",
      "content_html": "<h1>Serveur et optimisation</h1>\n<p>Ces options configurent le serveur de prévisualisation local et l’optimisation des fichiers générés.</p>\n<h2 id=\"serveur\">Serveur</h2>\n<h3 id=\"server-headers\">server.headers</h3>\n<p>Vous pouvez définir des <a href=\"https://developer.mozilla.org/docs/Glossary/Response_header\" target=\"_blank\" rel=\"noopener noreferrer\">en-têtes HTTP</a> personnalisés, utilisés par le serveur d’aperçu local.</p>\n<aside class=\"note note-warning\"><p>Depuis la version <ins>8.38.0</ins>, l’option <code translate=\"no\">headers</code> a été déplacée dans la section <code translate=\"no\">server.headers</code>.</p></aside>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">server:</span>\n  <span class=\"hljs-attr\">headers:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">&lt;path&gt;</span> <span class=\"hljs-comment\"># chemin relatif, préfixé par un slash. Prend en charge le joker \"*\".</span>\n      <span class=\"hljs-attr\">headers:</span>\n        <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">&lt;key&gt;</span>\n          <span class=\"hljs-attr\">value:</span> <span class=\"hljs-string\">\"&lt;value&gt;\"</span></code></pre>\n<aside class=\"note note-tip\"><p>C’est utile pour tester une <a href=\"https://developer.mozilla.org/docs/Web/HTTP/CSP\" target=\"_blank\" rel=\"noopener noreferrer\">Content Security Policy</a> ou <code translate=\"no\">Cache-Control</code> personnalisée.</p></aside>\n<p><em>Exemple :</em></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">server:</span>\n  <span class=\"hljs-attr\">headers:</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">/*</span>\n      <span class=\"hljs-attr\">headers:</span>\n        <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">X-Frame-Options</span>\n          <span class=\"hljs-attr\">value:</span> <span class=\"hljs-string\">\"SAMEORIGIN\"</span>\n        <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">X-XSS-Protection</span>\n          <span class=\"hljs-attr\">value:</span> <span class=\"hljs-string\">\"1; mode=block\"</span>\n        <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">X-Content-Type-Options</span>\n          <span class=\"hljs-attr\">value:</span> <span class=\"hljs-string\">\"nosniff\"</span>\n        <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">Content-Security-Policy</span>\n          <span class=\"hljs-attr\">value:</span> <span class=\"hljs-string\">\"default-src 'self'; object-src 'self'; img-src 'self'\"</span>\n        <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">Strict-Transport-Security</span>\n          <span class=\"hljs-attr\">value:</span> <span class=\"hljs-string\">\"max-age=31536000; includeSubDomains; preload\"</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">/assets/*</span>\n      <span class=\"hljs-attr\">headers:</span>\n        <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">Cache-Control</span>\n          <span class=\"hljs-attr\">value:</span> <span class=\"hljs-string\">\"public, max-age=31536000\"</span>\n    <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">path:</span> <span class=\"hljs-string\">/foo.html</span>\n      <span class=\"hljs-attr\">headers:</span>\n        <span class=\"hljs-bullet\">-</span> <span class=\"hljs-attr\">key:</span> <span class=\"hljs-string\">Foo</span>\n          <span class=\"hljs-attr\">value:</span> <span class=\"hljs-string\">\"bar\"</span></code></pre>\n<hr>\n<h2 id=\"optimisation\">Optimisation</h2>\n<p>Les options d’optimisation permettent d’activer la compression des fichiers de sortie : HTML, CSS, JavaScript et images.</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">optimize:</span>\n  <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">false</span>     <span class=\"hljs-comment\"># active l’optimisation des fichiers (`false` par défaut)</span>\n  <span class=\"hljs-attr\">html:</span>\n    <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>    <span class=\"hljs-comment\"># active l’optimisation des fichiers HTML</span>\n    <span class=\"hljs-attr\">ext:</span> <span class=\"hljs-string\">[html,</span> <span class=\"hljs-string\">htm]</span>   <span class=\"hljs-comment\"># extensions de fichiers prises en charge</span>\n  <span class=\"hljs-attr\">css:</span>\n    <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>    <span class=\"hljs-comment\"># active l’optimisation des fichiers CSS</span>\n    <span class=\"hljs-attr\">ext:</span> <span class=\"hljs-string\">[css]</span>         <span class=\"hljs-comment\"># extensions de fichiers prises en charge</span>\n  <span class=\"hljs-attr\">js:</span>\n    <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>    <span class=\"hljs-comment\"># active l’optimisation des fichiers JavaScript</span>\n    <span class=\"hljs-attr\">ext:</span> <span class=\"hljs-string\">[js]</span>          <span class=\"hljs-comment\"># extensions de fichiers prises en charge</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>    <span class=\"hljs-comment\"># active l’optimisation des fichiers images</span>\n    <span class=\"hljs-attr\">ext:</span> <span class=\"hljs-string\">[jpeg,</span> <span class=\"hljs-string\">jpg,</span> <span class=\"hljs-string\">png,</span> <span class=\"hljs-string\">gif,</span> <span class=\"hljs-string\">webp,</span> <span class=\"hljs-string\">svg,</span> <span class=\"hljs-string\">avif]</span> <span class=\"hljs-comment\"># extensions de fichiers prises en charge</span></code></pre>\n<p>Cette option est désactivée par défaut et peut être activée via :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">optimize:</span> <span class=\"hljs-literal\">true</span></code></pre>\n<p>Une fois l’option globale activée, les 4 types de fichiers seront traités.<br>\nIl est possible de désactiver chacun d’eux via <code translate=\"no\">enabled: false</code> et de modifier l’extension des fichiers traités via <code translate=\"no\">ext</code>.</p>\n<aside class=\"note note-tip\"><p>Il est également possible d’activer cette option via la CLI lors de l’utilisation des commandes \"build\" et \"serve\" avec l’option <code translate=\"no\">--optimize</code>.</p></aside>\n<aside class=\"note note-important\"><p>Le compresseur d’<strong>images</strong> utilisera les binaires suivants s’ils sont présents sur le système : <a href=\"https://github.com/tjko/jpegoptim\" target=\"_blank\" rel=\"noopener noreferrer\">JpegOptim</a>, <a href=\"http://optipng.sourceforge.net/\" target=\"_blank\" rel=\"noopener noreferrer\">Optipng</a>, <a href=\"https://pngquant.org/\" target=\"_blank\" rel=\"noopener noreferrer\">Pngquant 2</a>, <a href=\"https://github.com/svg/svgo\" target=\"_blank\" rel=\"noopener noreferrer\">SVGO</a>, <a href=\"http://www.lcdf.org/gifsicle/\" target=\"_blank\" rel=\"noopener noreferrer\">Gifsicle</a>, <a href=\"https://developers.google.com/speed/webp/docs/cwebp\" target=\"_blank\" rel=\"noopener noreferrer\">cwebp</a> et <a href=\"https://github.com/AOMediaCodec/libavif\" target=\"_blank\" rel=\"noopener noreferrer\">avifenc</a>.</p></aside>\n<hr>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/surcharge/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/surcharge/",
      "title": "Surcharge de configuration",
      "summary": "Surchargez la configuration avec des variables d’environnement ou une option CLI.",
      "date_published": "2026-03-27T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Surcharge de configuration\nLa configuration peut être surchargée sans modifier le fichier de configuration, via des variables d’environnement ou une option de la CLI.\nVariables d’environnement\nLa configuration peut être surchargée via des variables d’environnement.\nAu démarrage, Cecil essaie également de charger un fichier .env depuis le chemin du site courant (le répertoire de travail actuel, ou l’argument &lt;path&gt; s’il est fourni).\n\nSi le fichier .env n’existe pas, Cecil continue normalement.\nLes variables déjà définies par le shell\/système sont conservées.\n\nChaque nom de variable d’environnement doit être préfixé par CECIL_ et la clé de configuration doit être en majuscules.\nPar exemple, la commande suivante définit le baseurl du site :\nexport CECIL_BASEURL=\"https:\/\/example.com\/\"\nVous pouvez stocker la même valeur dans un fichier .env à la racine du projet :\nCECIL_BASEURL=\"https:\/\/example.com\/\"\nCECIL_TITLE=\"Mon site Cecil\"\nOption CLI\nVous pouvez combiner plusieurs fichiers de configuration avec l’option --config (priorité de gauche à droite) :\nphp cecil.phar --config config-1.yml,config-2.yml",
      "content_html": "<h1>Surcharge de configuration</h1>\n<p>La configuration peut être surchargée sans modifier le fichier de configuration, via des variables d’environnement ou une option de la CLI.</p>\n<h2 id=\"variables-d-environnement\">Variables d’environnement</h2>\n<p>La configuration peut être surchargée via des <a href=\"https://en.wikipedia.org/wiki/Environment_variable\" target=\"_blank\" rel=\"noopener noreferrer\">variables d’environnement</a>.</p>\n<p>Au démarrage, Cecil essaie également de charger un fichier <code translate=\"no\">.env</code> depuis le chemin du site courant (le répertoire de travail actuel, ou l’argument <code translate=\"no\">&lt;path&gt;</code> s’il est fourni).</p>\n<ul>\n<li>Si le fichier <code translate=\"no\">.env</code> n’existe pas, Cecil continue normalement.</li>\n<li>Les variables déjà définies par le shell/système sont conservées.</li>\n</ul>\n<p>Chaque nom de variable d’environnement doit être préfixé par <code translate=\"no\">CECIL_</code> et la clé de configuration doit être en majuscules.</p>\n<p>Par exemple, la commande suivante définit le <code translate=\"no\">baseurl</code> du site :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\"><span class=\"hljs-built_in\">export</span> CECIL_BASEURL=<span class=\"hljs-string\">\"https://example.com/\"</span></code></pre>\n<p>Vous pouvez stocker la même valeur dans un fichier <code translate=\"no\">.env</code> à la racine du projet :</p>\n<pre><code class=\"language-dotenv\" translate=\"no\">CECIL_BASEURL=\"https://example.com/\"\nCECIL_TITLE=\"Mon site Cecil\"</code></pre>\n<h2 id=\"option-cli\">Option CLI</h2>\n<p>Vous pouvez combiner plusieurs fichiers de configuration avec l’option <code translate=\"no\">--config</code> (priorité de gauche à droite) :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar --config config-1.yml,config-2.yml</code></pre>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/assets/fournisseurs-cdn/",
      "url": "https://cecil-945.pages.dev/fr/documentation/assets/fournisseurs-cdn/",
      "title": "Fournisseurs de CDN",
      "summary": "Exemples de configuration de fournisseurs de CDN d’images (Cloudinary, Cloudimage, TwicPics, imgix, Netlify Image CDN).",
      "date_published": "2023-10-23T00:00:00+00:00",
      "date_modified": "2026-10-02T00:00:00+00:00","content_text": "Fournisseurs de CDN\nExemples de configuration de fournisseurs de CDN pour les options de configuration.\nCloudinary\nhttps:\/\/cloudinary.com\nassets:\n  images:\n    cdn:\n      enabled: true\n      account: 'xxxx'\n      url: 'https:\/\/res.cloudinary.com\/%account%\/image\/fetch\/c_limit,w_%width%,q_%quality%,f_%format%,d_default\/%image_url%'\nCloudimage\nhttps:\/\/www.cloudimage.io\nassets:\n  images:\n    cdn:\n      enabled: true\n      account: 'xxxx'\n      url: 'https:\/\/%account%.cloudimg.io\/%image_url%?w=%width%&amp;q=%quality%&amp;force_format=%format%'\nTwicPics\nhttps:\/\/www.twicpics.com\nassets:\n  images:\n    cdn:\n      enabled: true\n      account: 'xxxx'\n      canonical: false\n      remote: false\n      url: 'https:\/\/%account%.twic.pics\/%image_url%?twic=v1\/resize=%width%\/quality=%quality%\/output=%format%'\nSource URL : URL de base de votre site.\nimgix\nhttps:\/\/imgix.com\nassets:\n  images:\n    cdn:\n      enabled: true\n      account: 'xxxx'\n      canonical: false\n      remote: false\n      url: 'https:\/\/%account%.imgix.net\/%image_url%?w=%width%&amp;q=%quality%&amp;fm=%format%'\nBase URL : URL de base de votre site.\nNetlify Image CDN\nhttps:\/\/docs.netlify.com\/image-cdn\/overview\/\nassets:\n  images:\n    cdn:\n      enabled: true\n      canonical: false\n      url: '\/.netlify\/images?url=%image_url%&amp;w=%width%&amp;fm=%format%'\nExécution en local\nInstaller Netlify CLI\nnpm install netlify-cli -g\nnetlify link\nnetlify.toml :\n[dev]\n  targetPort = 8000\nDémarrer le serveur local\nphp cecil.phar serve &amp; netlify dev\nOuvrez http:\/\/localhost:8888",
      "content_html": "<h1>Fournisseurs de CDN</h1>\n<p>Exemples de configuration de fournisseurs de CDN pour les <a href=\"../configuration/6-assets.fr.md#assets-images-cdn\"><code translate=\"no\">options de configuration</code></a>.</p>\n<h2 id=\"cloudinary\">Cloudinary</h2>\n<p><a href=\"https://cloudinary.com\" target=\"_blank\" rel=\"noopener noreferrer\">https://cloudinary.com</a></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">cdn:</span>\n      <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">account:</span> <span class=\"hljs-string\">'xxxx'</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">'https://res.cloudinary.com/%account%/image/fetch/c_limit,w_%width%,q_%quality%,f_%format%,d_default/%image_url%'</span></code></pre>\n<h2 id=\"cloudimage\">Cloudimage</h2>\n<p><a href=\"https://www.cloudimage.io\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.cloudimage.io</a></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">cdn:</span>\n      <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">account:</span> <span class=\"hljs-string\">'xxxx'</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">'https://%account%.cloudimg.io/%image_url%?w=%width%&amp;q=%quality%&amp;force_format=%format%'</span></code></pre>\n<h2 id=\"twicpics\">TwicPics</h2>\n<p><a href=\"https://www.twicpics.com\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.twicpics.com</a></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">cdn:</span>\n      <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">account:</span> <span class=\"hljs-string\">'xxxx'</span>\n      <span class=\"hljs-attr\">canonical:</span> <span class=\"hljs-literal\">false</span>\n      <span class=\"hljs-attr\">remote:</span> <span class=\"hljs-literal\">false</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">'https://%account%.twic.pics/%image_url%?twic=v1/resize=%width%/quality=%quality%/output=%format%'</span></code></pre>\n<p><code translate=\"no\">Source URL</code> : URL de base de votre site.</p>\n<h2 id=\"imgix\">imgix</h2>\n<p><a href=\"https://imgix.com\" target=\"_blank\" rel=\"noopener noreferrer\">https://imgix.com</a></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">cdn:</span>\n      <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">account:</span> <span class=\"hljs-string\">'xxxx'</span>\n      <span class=\"hljs-attr\">canonical:</span> <span class=\"hljs-literal\">false</span>\n      <span class=\"hljs-attr\">remote:</span> <span class=\"hljs-literal\">false</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">'https://%account%.imgix.net/%image_url%?w=%width%&amp;q=%quality%&amp;fm=%format%'</span></code></pre>\n<p><code translate=\"no\">Base URL</code> : URL de base de votre site.</p>\n<h2 id=\"netlify-image-cdn\">Netlify Image CDN</h2>\n<p><a href=\"https://docs.netlify.com/image-cdn/overview/\" target=\"_blank\" rel=\"noopener noreferrer\">https://docs.netlify.com/image-cdn/overview/</a></p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-attr\">assets:</span>\n  <span class=\"hljs-attr\">images:</span>\n    <span class=\"hljs-attr\">cdn:</span>\n      <span class=\"hljs-attr\">enabled:</span> <span class=\"hljs-literal\">true</span>\n      <span class=\"hljs-attr\">canonical:</span> <span class=\"hljs-literal\">false</span>\n      <span class=\"hljs-attr\">url:</span> <span class=\"hljs-string\">'/.netlify/images?url=%image_url%&amp;w=%width%&amp;fm=%format%'</span></code></pre>\n<h3 id=\"execution-en-local\">Exécution en local</h3>\n<h4>Installer Netlify CLI</h4>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">npm install netlify-cli -g\nnetlify link</code></pre>\n<p><code translate=\"no\">netlify.toml</code> :</p>\n<pre><code class=\"language-yaml hljs yaml\" translate=\"no\"><span class=\"hljs-string\">[dev]</span>\n  <span class=\"hljs-string\">targetPort</span> <span class=\"hljs-string\">=</span> <span class=\"hljs-number\">8000</span></code></pre>\n<h4>Démarrer le serveur local</h4>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar serve &amp; netlify dev</code></pre>\n<p>Ouvrez <a href=\"http://localhost:8888\" target=\"_blank\" rel=\"noopener noreferrer\">http://localhost:8888</a></p>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/bien-demarrer/demarrage-rapide/",
      "url": "https://cecil-945.pages.dev/fr/documentation/bien-demarrer/demarrage-rapide/",
      "title": "Démarrage rapide",
      "summary": "Installez Cecil, créez un site, ajoutez des pages, prévisualisez-le localement, puis générez-le et déployez-le.",
      "date_published": "2021-11-03T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Démarrage rapide\nCe guide vous accompagne dans la création de votre premier site Cecil, sa prévisualisation en local, puis sa construction et son déploiement.\nCréer un site web\nVous pouvez créer un nouveau site web en quelques minutes.\nSuivez les étapes ci-dessous pour créer votre premier site web Cecil.\n\n\n\n\n\n\n\n\nDémo du résultat attendu : https:\/\/cecilapp.github.io\/skeleton\/.\nPrérequis\n\nPHP 8.3+\nTerminal (une compréhension de base du terminal)\nÉditeur de texte, comme VS Code et\/ou Typora\n\n1. Télécharger Cecil\nTéléchargez cecil.phar depuis votre terminal:\ncurl -LO https:\/\/cecil.app\/cecil.phar\nVous pouvez également télécharger Cecil manuellement, ou utiliser :\n\nHomebrew: brew install cecilapp\/tap\/cecil\nScoop: scoop install https:\/\/cecil.app\/scoop\/cecil.json\n\n2. Créer un nouveau site\nCréez un répertoire pour le site Web (ex : &lt;monsiteweb&gt;), placez y cecil.phar, puis exécutez la commande new:site :\nphp cecil.phar new:site\n3. Ajouter une page\nExécutez la commande new:page :\nphp cecil.phar new:page\nVous pouvez maintenant modifier la page nouvellement créée avec votre éditeur Markdown : &lt;monsiteweb&gt;\/pages\/&lt;nouvelle-page&gt;.md.\nNous vous recommandons d’utiliser Typora pour éditer vos fichiers Markdown.\n4. Vérifier l’aperçu\nExécutez la commande suivante pour créer un aperçu du site Web :\nphp cecil.phar serve\nNaviguez ensuite sur http:\/\/localhost:8000.\nLa commande serve démarre un serveur HTTP local et un observateur : si un fichier (une page, un template ou la config) est modifié, la page active du navigateur est automatiquement rechargée.\n5. Générer et déployer\nQuand vous êtes satisfait du résultat, vous pouvez générer le site afin de le déployer sur le Web.\nExécutez la commande suivante pour générer le site :\nphp cecil.phar build\nVous pouvez maintenant copier le contenu du répertoire _site sur un serveur Web 🎉\n",
      "content_html": "<h1>Démarrage rapide</h1>\n<p>Ce guide vous accompagne dans la création de votre premier site Cecil, sa prévisualisation en local, puis sa construction et son déploiement.</p>\n<h2 id=\"creer-un-site-web\">Créer un site web</h2>\n<p>Vous pouvez créer un nouveau site web en quelques minutes.</p>\n<p>Suivez les étapes ci-dessous pour créer votre premier site web Cecil.</p>\n<p><a href=\"https://cecilapp.github.io/skeleton/\" target=\"_blank\" rel=\"noopener noreferrer\"><picture>\n<source media=\"(prefers-color-scheme: dark)\" type=\"image/avif\" srcset=\"/thumbnails/480x/docs/cecil-newsite.dark.19f0a851a99b34775f44b67c805a0815.avif 480w, /thumbnails/768x/docs/cecil-newsite.dark.19f0a851a99b34775f44b67c805a0815.avif 768w, /docs/cecil-newsite.dark.19f0a851a99b34775f44b67c805a0815.avif 1007w\" sizes=\"100vw\">\n<source media=\"(prefers-color-scheme: dark)\" type=\"image/webp\" srcset=\"/thumbnails/480x/docs/cecil-newsite.dark.19f0a851a99b34775f44b67c805a0815.webp 480w, /thumbnails/768x/docs/cecil-newsite.dark.19f0a851a99b34775f44b67c805a0815.webp 768w, /docs/cecil-newsite.dark.19f0a851a99b34775f44b67c805a0815.webp 1007w\" sizes=\"100vw\">\n<source media=\"(prefers-color-scheme: dark)\" srcset=\"/thumbnails/480x/docs/cecil-newsite.dark.19f0a851a99b34775f44b67c805a0815.png 480w, /thumbnails/768x/docs/cecil-newsite.dark.19f0a851a99b34775f44b67c805a0815.png 768w, /docs/cecil-newsite.dark.19f0a851a99b34775f44b67c805a0815.png 1007w\" sizes=\"100vw\">\n<source type=\"image/avif\" srcset=\"/thumbnails/480x/docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.avif 480w, /thumbnails/768x/docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.avif 768w, /docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.avif 1007w\" width=\"1007\" height=\"607\" sizes=\"100vw\">\n<source type=\"image/webp\" srcset=\"/thumbnails/480x/docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.webp 480w, /thumbnails/768x/docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.webp 768w, /docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.webp 1007w\" width=\"1007\" height=\"607\" sizes=\"100vw\">\n<img src=\"/docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.png\" alt=\"Example de nouveau site\" loading=\"lazy\" decoding=\"async\" class=\"dark:brightness-90\" width=\"1007\" height=\"607\" style=\";max-width:100%;height:auto;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAyCAYAAACqNX6+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEj0lEQVR4nN1b0ZKDIAxMHP//H+9HLvcg0QQCRATE2xmLrQghy4ZIW/z5+SEAgN/fXyAio6SjpKPk4wQRUCgBIJyDBgIgIiAibNvmOBA23AA3hA3xaKJSJh02IX/f0Q0Cd1ezxzTLgb3tNgAAShxvkjEYZPbnMcLyGBmORHW9nWwfmglRjmCVvALZ8x1n2ffFBCOOJ0HigUJAhyl10g85d6yrjOATYYodVm08IwTGkVF3wf9SBuMRIQQI5wDF6Uj8V2UwDELYs5h8alb1MCGyrMMD9bmP0Zvrs/+pDIYghPM5AiA8/ZwlGVE4CMuTCUN9cXiJOZtIkzr4ijLIkHVOPftVIZhBePKRdzDKOaYKu354iUipEiO45lcUrz6sqYyYJCZol0YgXOI4P1B3HRV0kPIRghlCcsSo/I1iQ54oo+T095TB2PV11OZsod/zwEtJkWEehcin2SIpFK8WlEi27javMqoNdUVOGYxLIUEZtn0IiAREmozoKSSLM8yEUGcSgSjCU2h3mjLuYIwyGJdC1NqBR4/hOBZUUgvr3YjL7cpSkSKmw7kFg3DYkMpSt6vwTWUwToUcixqAzJgQECgoA4EuH4nSAzxLvEq8Sukdq4+zb7Kv614kvqMMxs6TTxPBbgC+AgSoHAFgu6AEuQLw7ql1tYaYjHjF+aIyGPrBEMMsRIQrCzzmZ0xGK1TaWsytU+gJkp7LmvjYUt2rTxliyjV2v8MlEWWABCKGsNVpd0Tk1WmK7c+fUpWkdfyt9kWrMg+FKE+jLjhuI3VRyNULyjfFlq1JUFPJczvnKoMhHgz18njGaQ5jYg3phgdKqakkp5zReLpmqb0snqg6oyG5tdV9gCWl1MgvqaTdTqkMzkCjGpR6oleykN9+P0c4YY4VlZJHSSVzd6b6ZXN7rIxrmlEyorEDFMnrjY5yKjFDmYdktWbE18Ypg5EqZKYyrL49nwmUyFCrI97Osl3o/Zyzs4HUJwAPWvTv3WI/OJZRVobRz6D5einEkUJ1dXYJDYOtpcZJ8w8dOmoHIHlSf+r0aaQ5cfopyCZeIlVgeFEZjKYfOazmdImibXSpozVCj94byxLS6vSVyQKAbAxTa88LymBUFVJy8MrOrymlJAvr0qxdY3fI8jh/ZYJyUNkYGXtik7P/hJA4bYxLy+mrEvHULit8TVvUvRuHJWLA2cYKqO0Wy3ozoRRSU4c1CDmQFcnoZdMsYvaWLfUvEmNhJWUwdu7c2gfyqkSer0hGj7VkFm6vIVb9rxDjwVvKYDStId4t7y8R8zYRjO2JIXjz/E1Q5lgNyRrSgppKViHlC7j9YHgnfK2IVe1iNC/qMXJqWNUBKI6VsFtMtKjEun9lxISsQsxeCjke50t8IWRJWISgccxE8svFpwbw/SsrxMoCS0qZ/mCYCzEeQ+I6UxXSoZMcIUlIm/0FVfWvd07IZrqppLMzSip4e01xfUFlkZUz+P531Q1D7+itXFaY62L49yGef/jwr7zvhLCyOpyjGjj4rMPHdemCUyH3zfyCOp40P+w79ZKzrf/M9cP7Knmxqyz+AEm28LzQnWd/AAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:center;background-size:cover;\" srcset=\"/thumbnails/480x/docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.png 480w, /thumbnails/768x/docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.png 768w, /docs/cecil-newsite.94982e8ace758b40e6ff753807bdb42b.png 1007w\" sizes=\"100vw\">\n</picture></a></p>\n<aside class=\"note note-info\"><p>Démo du résultat attendu : <a href=\"https://cecilapp.github.io/skeleton/\" target=\"_blank\" rel=\"noopener noreferrer\">https://cecilapp.github.io/skeleton/</a>.</p></aside>\n<h3 id=\"prerequis\">Prérequis</h3>\n<ul>\n<li><a href=\"https://php.net/manual/fr/install.php\" target=\"_blank\" rel=\"noopener noreferrer\">PHP</a> 8.3+</li>\n<li>Terminal (une compréhension de base du <a href=\"https://fr.wikipedia.org/wiki/%C3%89mulateur_de_terminal\" target=\"_blank\" rel=\"noopener noreferrer\">terminal</a>)</li>\n<li>Éditeur de texte, comme <a href=\"https://code.visualstudio.com\" target=\"_blank\" rel=\"noopener noreferrer\">VS Code</a> et/ou <a href=\"https://typora.io\" target=\"_blank\" rel=\"noopener noreferrer\">Typora</a></li>\n</ul>\n<h3 id=\"1-telecharger-cecil\">1. Télécharger Cecil</h3>\n<p>Téléchargez <code translate=\"no\">cecil.phar</code> depuis votre terminal:</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">curl -LO https://cecil.app/cecil.phar</code></pre>\n<p>Vous pouvez également <a href=\"https://cecil.app/download/\" target=\"_blank\" rel=\"noopener noreferrer\">télécharger Cecil manuellement</a>, ou utiliser :</p>\n<ul>\n<li><a href=\"https://brew.sh\" target=\"_blank\" rel=\"noopener noreferrer\">Homebrew</a>: <code translate=\"no\">brew install cecilapp/tap/cecil</code></li>\n<li><a href=\"https://scoop.sh\" target=\"_blank\" rel=\"noopener noreferrer\">Scoop</a>: <code translate=\"no\">scoop install https://cecil.app/scoop/cecil.json</code></li>\n</ul>\n<h3 id=\"2-creer-un-nouveau-site\">2. Créer un nouveau site</h3>\n<p>Créez un répertoire pour le site Web (ex : <code translate=\"no\">&lt;monsiteweb&gt;</code>), placez y <code translate=\"no\">cecil.phar</code>, puis exécutez la commande <code translate=\"no\">new:site</code> :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar new:site</code></pre>\n<h3 id=\"3-ajouter-une-page\">3. Ajouter une page</h3>\n<p>Exécutez la commande <code translate=\"no\">new:page</code> :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar new:page</code></pre>\n<p>Vous pouvez maintenant modifier la page nouvellement créée avec votre éditeur Markdown : <code translate=\"no\">&lt;monsiteweb&gt;/pages/&lt;nouvelle-page&gt;.md</code>.</p>\n<aside class=\"note note-tip\"><p>Nous vous recommandons d’utiliser <a href=\"https://www.typora.io\" target=\"_blank\" rel=\"noopener noreferrer\">Typora</a> pour éditer vos fichiers Markdown.</p></aside>\n<h3 id=\"4-verifier-l-apercu\">4. Vérifier l’aperçu</h3>\n<p>Exécutez la commande suivante pour créer un aperçu du site Web :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar serve</code></pre>\n<p>Naviguez ensuite sur <code translate=\"no\">http://localhost:8000</code>.</p>\n<aside class=\"note note-info\"><p>La commande <code translate=\"no\">serve</code> démarre un serveur HTTP local et un observateur : si un fichier (une page, un template ou la config) est modifié, la page active du navigateur est automatiquement rechargée.</p></aside>\n<h3 id=\"5-generer-et-deployer\">5. Générer et déployer</h3>\n<p>Quand vous êtes satisfait du résultat, vous pouvez générer le site afin de le déployer sur le Web.</p>\n<p>Exécutez la commande suivante pour générer le site :</p>\n<pre><code class=\"language-bash hljs bash\" translate=\"no\">php cecil.phar build</code></pre>\n<p>Vous pouvez maintenant copier le contenu du répertoire <code translate=\"no\">_site</code> sur un serveur Web 🎉</p>\n<hr>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/bien-demarrer/kits-de-demarrage/",
      "url": "https://cecil-945.pages.dev/fr/documentation/bien-demarrer/kits-de-demarrage/",
      "title": "Kits de démarrage",
      "summary": "Démarrez rapidement avec un modèle de projet prêt à l’emploi.",
      "date_published": "2021-11-03T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Kits de démarrage\nPour démarrer rapidement, utilisez l’un des kits de démarrage Cecil prêts à l’emploi.\nKits de démarrage disponibles\n\nThe Butler : starter blog prêt à publier.\nLinks : alternative open source à Linktree.\nPhoto Stream : flux photo auto-hébergé minimaliste.\nStatidocs : site de documentation prêt à l’emploi.\n\n\n\n\n\n",
      "content_html": "<h1>Kits de démarrage</h1>\n<p>Pour démarrer rapidement, utilisez l’un des <a href=\"/fr/kits-de-demarrage/\">kits de démarrage</a> Cecil prêts à l’emploi.</p>\n<h2 id=\"kits-de-demarrage-disponibles\">Kits de démarrage disponibles</h2>\n<ul>\n<li><a href=\"https://github.com/Cecilapp/the-butler#readme\" target=\"_blank\" rel=\"noopener noreferrer\">The Butler</a> : starter blog prêt à publier.</li>\n<li><a href=\"https://github.com/Cecilapp/Links#readme\" target=\"_blank\" rel=\"noopener noreferrer\">Links</a> : alternative open source à Linktree.</li>\n<li><a href=\"https://github.com/Cecilapp/photo-stream#readme\" target=\"_blank\" rel=\"noopener noreferrer\">Photo Stream</a> : flux photo auto-hébergé minimaliste.</li>\n<li><a href=\"https://github.com/Cecilapp/statidocs#readme\" target=\"_blank\" rel=\"noopener noreferrer\">Statidocs</a> : site de documentation prêt à l’emploi.</li>\n</ul>\n<p><a href=\"https://github.com/Cecilapp/the-butler#readme\" target=\"_blank\" rel=\"noopener noreferrer\"><picture>\n<source type=\"image/avif\" srcset=\"/thumbnails/480x/docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.avif 480w, /thumbnails/768x/docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.avif 768w, /docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.avif 1014w\" width=\"1014\" height=\"713\" sizes=\"100vw\">\n<source type=\"image/webp\" srcset=\"/thumbnails/480x/docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.webp 480w, /thumbnails/768x/docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.webp 768w, /docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.webp 1014w\" width=\"1014\" height=\"713\" sizes=\"100vw\">\n<img src=\"/docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.png\" alt=\"Exemple de starter blog\" loading=\"lazy\" decoding=\"async\" class=\"dark:brightness-90\" width=\"1014\" height=\"713\" style=\";max-width:100%;height:auto;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAyCAYAAACqNX6+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAOtUlEQVR4nNWc63rjNg5AD0A5bb92v2nfoO//gptYIrA/AJKQ7Ex3urOtywxDWbFuPMSV1Mjvv//u/IVFVbndbvz444/8/PPP/Otf/+LLr7/y22+/8duvv/Jrtl++fOHLly/88ssv/PTTT7y9vdFao7WN1hQRRVUAQQREBBEByrYIEjvOLZL/oh3ngLq9zjX/sjYZm7XzvOxwfO5wB3fD3XEzzB0zm9Ut/wbo9+jk71L8cVy4+6nm3vzq2OfzcC/n8NiRfXJpT7/rOR9v5XzOsp+vwbhsn640b3ZWL/u3h174O4pzuqnTgxYg5o44CI65oMRIDDmZp5qf/dNWkHmVIQmOe/5VZII4bz8dN/UxLlDqYFlw/VIrmNcAMooXKBcQAcMRNzBB1bJjBXFAfG5L7Ij2pK5SVQmISx5zhsVXt6fCu9725RkGlSqZPqFUaX9NCUkSU6GUG5961wwxA1FcDDdN2+HZ0bK2yU4fNmLaFJ3ARCpMcn/cjTj4pODLjgxJmb9iY477B5U1nsfPUBjP98ISMsfMuHGYkjGMIGYBAzAdxnt1/AMMWMZdzsZ/wpQBRUICBx1nyYMMEINYueFqHy77/BmUWfPvryghY4RVWzdAdDO6GTq8EekYROdNT2oAgdltMmCAiD4BImiqNUnpKkcXKXjmZV3crYtduUrMSQNMyVgD72UkpHoq6yYDRrUdPdWVmqWaESRd3tFLU91ULBOAJxRHKxBNtSVSjj+fp+48Sci3PGTdSM/QrUgMryYh5V5Phtycbs5hDuZod8BCo4TOeuisNYizk0UiZklJ0JQWFUFtSc06VgqUSylSWPd9XooKLYZchst+Go0vICG1VNfQCCnpHjDUHO+GYiH6Ci7p8Fa1IrV/RqAoUzJCOmxuLwmhBI15jmlDqj6S0+VOZerJsySlQh2+RW7Hw8o0JKsTXgJICjGOY05IhsPhzuGhrswcwcK+GLhIHifLI+Ki+2WpJEXO6moCukrIAiH1Bk/xzoN+y3YMABgDQoS89mplnitd+QGIv1tCpqcxXMFqzEM6dgt9q93ABTMwcUwEYyiAS7mM1uHiagEUUNLGrK+vw70C8NmJ8+8P1xowqlcX12wCbWwDTUhA67yS0P9mCSmykVAMpnTs5kh3ejfAcBNMnC4aai1k5hz1Akt3r3aBuXyeaoTp4Q7EMjrMy4imgJO8piwHQyRsm4oiKjQRmiqbCJsKW8LZChQd55Y/kJCaWDt149fyB/9l8Sc1pINpO/Z0dbUb7oYJdFE6zsGCN0CO85YnmADW86zYZbrBFCi+Rq0SmYE1klfnjfPnSWKvRNIT1bRRypb1ppJV2RRMhKYsieFTlfU8e3ryo0d+55J3+l+K49nBy5hP6RDD1OgChziHC0fC6M50Ah7vZej6qpaqKuM84glvaABQdxTLURyfp9TkeRHBMwvgoiAjE91CMppyU+XWlB+a8qbOWxNchVuxf5kwOAOpQVOt8dUVcZ4ysKfczJ8BMaRj1LOre3THMEw7uzgHyu7M2t3pMFXeWXWdsDwAmRAYBpYJQnAahnq2GG2AKUBcQjJWbQGkNZo2bk15a40fNqVbw5qHnLlEDStPkyuQU8C05hueAsmcvpstVfEnoMwO9DOUYUM83d2OcZiwC9zduTvcHXZ3jiElJbD87E7OYNa+AWJKSEpGSxgNY8u2FSCSQEwaljBcGmhDm7E149YaP2zO4Q1zJ5SUI5sSvh9zEkSRBWS6h6oFSEk5IGl8Q2XJgDHyTN8A5dRpfoYy1NBh4f5aNw43dhU+gA8XPsz5cLhbADmGd3Y997zaY0wh+bG6uKGuQD06vrmxecC40dkSjOJoBhaO0qUllIZrQ7QhbWNrxttmHBaeI97i/IRhb3jYD18x0AbPVJXS2gIzdK0DbuFyTmNmHQh39Fug1J47qS2GhICY07uzu3E34R14d3g3eDfnbrBnzNJHQMnVlvhpW8ouKbCGytIE0fCA4cbNjTc6NwkoTRYQQzFpdBomGyYG6mhztuYxsPJ6Oj2tMPBdhD5d4nj27ew365SQWTPVMIi4WIp4GXW5H84zb9/A5ASle/rlBt2cHedDjA+Hf1vU976AHKm6lgt8nhlcUlJGwCmuSK8qDXpzZ0sgNw+VaXRMOl1SbRUJMXEOnC7FNBg0E3p6YqrGdnTeVHhT5TCna0y0eapcBbYFA0RL0k0KEJUiIcQVJw6fascMROyb7ckDFAIKKSn7gOLGhwnv5rx3+Og+7ciRLrOXn8czP1Ndsa1pR9oEYtw8HIqIeDqI4RguAS4kxMMdBw4RLO2KpKpDjdaNrRtvTWMAZY7O/HFQbqdgKaVkQNFiR0bQ5MqMYqvOCTDpAvLtRr56SMZSkd3hAHbCq7qbcTf4SJV1/wTI2cRHPcM4A5rqCmik04Jl7GHT7VWJQNHTADlOFw93HKfndSP/5qg6ew9vcYHw5YhcXMNtBk4TTIGjpSUEQ1zDkJPOQR2VKXZh5J+rr8v1/xCQEaMvDL1PiTk8YOzpbfUCZBx9BRJQ/HKVFX8IQ+2t74aHFR3dcVrauTFAh916VvFQpyO2MvMZ/H7WB1uFMQ11iT9GmqG6ilq+66qoe2RfNSQjFgbIJ5f878sAMqL37pJtSESHHJUBzT+BUOtlCcVsa6Q+YHRqhzPreDSHeG5fanIClWeQWDCe3R7Dy8oOPqUQSlsDqrkrJUc9ok7xqKoBo67W+F/LSZ15gcSq9pXjPz/rasfvoS6rC23D5R/fG4cKJSA9/3BqL1euvsWlbNdvPY4nzxUalyMl3YlLBvU8Z/3/gTIlh9Vx3+casrovxcBZ7VB4TsRiU0qgdL2ni/jn7mojDxWYqZDrMhwf882fXUPmr0v7/WBc2yfS/p2KlN9KKCyZkhKqR+YM4Ix9HBBHdKWUznEOxUbXK53L5u6z604L0kpaBFjzBpfvjhUUz7vt/1e+Hwh5+CSZlwibMsLGMd8fKnLcxZyTGaO1ZIuf1wr8sWyeJ4km0iAi8qCTT6n4Am6tUT3DOUN69bI66QQj9zphF1cm4WwfjJgaGFnfWNA30vWjPs69PCtbTaGPnFTt/CEND0DgtHD4cR3ut0Xtf32R07aQU6yQcx6ChHIKW2ExbnuqI/VhvQKYKbiGOyAS8YeO3BjEPh7V11WEtqvRdXd677NjxQxTncHj+M6AMmCcW14cRi1LLgJKgJHhzLiACW4RS2AxWaYWjnYUxdVBBWmGqCFuU1LWrGCJLD65mxOQusB4fJbM7F5nD+sa1ZmOH6rMvj198teX5XyMnzGaq5Tg+ayWWe3eceuY9TXqREAVadHxqCLa0M1QjzmVk7TwGGKMO5pu7+jAYUMmjOvMYflubZ+/OvCKpXqBSzqGZKisqF2GB5vTAPQD7wfWD+g99BgjJmvIFn6wioI2pD+DkdO1ctFWQ2Vdb3eqqicgrkDq9uuDgMfxOGDItB9LbfmE4d2w3vHjgH2HYwc7wEItoTFlq5aL+ETx1sA2xPoy8u4zU365DYYd+3SRQwXzRx39+iBquUqGsNZNRdZ3wBCPWVHvHT92uO/4fof9jvc95oKcyFi0jZZAmii+NTg26LcJrs7HT3vCickfLwP6Z3X218ozVaUBQWTBkDDmM69lPVTUHjDs4wPfP/Djjvcc/apo2/CeQFSxbcNvHazHaxQWqy4f76Iaevm712X9+XL1GL8+bD6xG1Kkw1ktuczTOt4P/NjxfcfuH9jHO3Z/x/c73o8pIW274R72t22N2+2GHUdIl4XPXFXW4zKk+PyPAPIsKfPMS/n60bEdHaC5inCsJJSy1CciC9xw69APbN+xlI7+8Y59/Ds+9yM6Whvt1nFAtbHdNvrxFjD7kI4RC1QoQ0Lknychz2BUF/VZkrFG2+OBRXSu81VymWca9OYgpKFOF9eOAzt2bP/guAeQ/vEeQI4DcFQbbh0RaK3R325xTD9wSwnJvPsjjLPE/GOAwBnAtQJz0dk5woCakQ4YWgx5iT985K9sqaseQPq+0/cP+j3B3D9CZRFSEWCUvt3o+x4gM2Zxt3SRVzpUquv7T5OQ64iKZTSs2TuIXNLpu2UGdKqqnKIuEjLjgjFyZyDYE8qOHzt23LF9px93+h7V+xHqrW1x/W3DMk6ZMIa6oq4RLpIh52d7eSBTPUnUsRa2ETfvxIP46ftj2T8FxCctlDd3AXy+ZOq9Zz2y7lOFed+nhADQWnxOCPEfBdiSjjJFOJMew9dNGl+NQ16hnGD4WtbfxNkkpAICzvx+AaEX6SAN+pyyZs1rDD0XWWxDrIP3aK1HZN57BoQ9YguzOEyj08cLOPIEQlVVFHU1rjue9WWBjEG0VvqF8d3UuTn0NBxVbUVWdcBYNoMC5ME380gcQiTTLTvT80UhrCM+qs1k4chjVedipNtX8vACI/ViSEidvFqu7+sDmVIBm5Gr/sZSobWCAwYQmepNsiUlxROIIwGCTBoKsVhB1sRwLvFGiXmf4Ra30ZFDzQjzbaymY/nUuAcpg2R0vl8gnOtLAXl2gy6CakhHU2HDuREQlLWKYxp8WW8rzeRoDss1ZZRBuAumMW9jEhiQtSBVc55QJaYaxrnRWAMdoz62W9N4/UCVTeNeW4FSpXdISbVjYwi+DBC5bA/9Gp2QRlzghsyYQ2Wsm12jrkl5ZWx2QPzVKHPjngu0DbqkUZfzypE223CpNU8qqnjT7FjJVw+UrbX5gs4mOtfszncZ+XqFFwIyysktzA+hsoTmQlNny45V97mQOWB4MfzrncIhHZa1eyxW6ASM2Ru57UOFEVBDSmPU0xRpinsBsilta/nfRwWcNqVkZJEf50Dk9NTRvgSQhxuUBWS8vjwCuJYdb0r8JzRCzkHEvPUmzPf4htoamtskYIhANynTmrnQj/EqW0igSW5LBJAuimvWpqBLQlRbWaRe4pzpXHBSTlViankJILUsD4Xlqk49HFOrmrknl2LQZb1vMZwAHe6tLDuDgLukEQ/191V1IqUdgFWIZZplwOjZZq3t8hxIeaYrlPj9H6oxhUTjWngBAAAAAElFTkSuQmCC);background-repeat:no-repeat;background-position:center;background-size:cover;\" srcset=\"/thumbnails/480x/docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.png 480w, /thumbnails/768x/docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.png 768w, /docs/cecil-newblog.c85c682e3bcb416589e2bc2bbcc2cfca.png 1014w\" sizes=\"100vw\">\n</picture></a></p>",
      "language": "fr"
    },
    {
      "id": "https://cecil-945.pages.dev/fr/documentation/configuration/codes-de-locale/",
      "url": "https://cecil-945.pages.dev/fr/documentation/configuration/codes-de-locale/",
      "title": "Codes de locale",
      "summary": "Liste des codes de locale à utiliser avec l’option languages.",
      "date_published": "2020-12-19T00:00:00+00:00",
      "date_modified": "2026-10-10T00:00:00+00:00","content_text": "Codes de locale\nCodes de locale disponibles (language_COUNTRY) utilisés par l’option languages.\nListe des codes de locale\n\n\n\nLocale\nCode\n\n\n\n\nAlbanais (Albanie)\nsq_AL\n\n\nAlbanais\nsq\n\n\nArabe (Algérie)\nar_DZ\n\n\nArabe (Bahreïn)\nar_BH\n\n\nArabe (Égypte)\nar_EG\n\n\nArabe (Irak)\nar_IQ\n\n\nArabe (Jordanie)\nar_JO\n\n\nArabe (Koweït)\nar_KW\n\n\nArabe (Liban)\nar_LB\n\n\nArabe (Libye)\nar_LY\n\n\nArabe (Maroc)\nar_MA\n\n\nArabe (Oman)\nar_OM\n\n\nArabe (Qatar)\nar_QA\n\n\nArabe (Arabie saoudite)\nar_SA\n\n\nArabe (Soudan)\nar_SD\n\n\nArabe (Syrie)\nar_SY\n\n\nArabe (Tunisie)\nar_TN\n\n\nArabe (Émirats arabes unis)\nar_AE\n\n\nArabe (Yémen)\nar_YE\n\n\nArabe\nar\n\n\nBiélorusse (Biélorussie)\nbe_BY\n\n\nBiélorusse\nbe\n\n\nBulgare (Bulgarie)\nbg_BG\n\n\nBulgare\nbg\n\n\nCatalan (Espagne)\nca_ES\n\n\nCatalan\nca\n\n\nChinois (Chine)\nzh_CN\n\n\nChinois (Hong Kong)\nzh_HK\n\n\nChinois (Singapour)\nzh_SG\n\n\nChinois (Taïwan)\nzh_TW\n\n\nChinois\nzh\n\n\nCroate (Croatie)\nhr_HR\n\n\nCroate\nhr\n\n\nTchèque (République tchèque)\ncs_CZ\n\n\nTchèque\ncs\n\n\nDanois (Danemark)\nda_DK\n\n\nDanois\nda\n\n\nNéerlandais (Belgique)\nnl_BE\n\n\nNéerlandais (Pays-Bas)\nnl_NL\n\n\nNéerlandais\nnl\n\n\nAnglais (Australie)\nen_AU\n\n\nAnglais (Canada)\nen_CA\n\n\nAnglais (Inde)\nen_IN\n\n\nAnglais (Irlande)\nen_IE\n\n\nAnglais (Malte)\nen_MT\n\n\nAnglais (Nouvelle-Zélande)\nen_NZ\n\n\nAnglais (Philippines)\nen_PH\n\n\nAnglais (Singapour)\nen_SG\n\n\nAnglais (Afrique du Sud)\nen_ZA\n\n\nAnglais (Royaume-Uni)\nen_GB\n\n\nAnglais (États-Unis)\nen_US\n\n\nAnglais\nen\n\n\nEstonien (Estonie)\net_EE\n\n\nEstonien\net\n\n\nFinnois (Finlande)\nfi_FI\n\n\nFinnois\nfi\n\n\nFrançais (Belgique)\nfr_BE\n\n\nFrançais (Canada)\nfr_CA\n\n\nFrançais (France)\nfr_FR\n\n\nFrançais (Luxembourg)\nfr_LU\n\n\nFrançais (Suisse)\nfr_CH\n\n\nFrançais\nfr\n\n\nAllemand (Autriche)\nde_AT\n\n\nAllemand (Allemagne)\nde_DE\n\n\nAllemand (Luxembourg)\nde_LU\n\n\nAllemand (Suisse)\nde_CH\n\n\nAllemand\nde\n\n\nGrec (Chypre)\nel_CY\n\n\nGrec (Grèce)\nel_GR\n\n\nGrec\nel\n\n\nHébreu (Israël)\niw_IL\n\n\nHébreu\niw\n\n\nHindi (Inde)\nhi_IN\n\n\nHongrois (Hongrie)\nhu_HU\n\n\nHongrois\nhu\n\n\nIslandais (Islande)\nis_IS\n\n\nIslandais\nis\n\n\nIndonésien (Indonésie)\nin_ID\n\n\nIndonésien\nin\n\n\nIrlandais (Irlande)\nga_IE\n\n\nIrlandais\nga\n\n\nItalien (Italie)\nit_IT\n\n\nItalien (Suisse)\nit_CH\n\n\nItalien\nit\n\n\nJaponais (Japon)\nja_JP\n\n\nJaponais (Japon,JP)\nja_JP_JP\n\n\nJaponais\nja\n\n\nCoréen (Corée du Sud)\nko_KR\n\n\nCoréen\nko\n\n\nLetton (Lettonie)\nlv_LV\n\n\nLetton\nlv\n\n\nLituanien (Lituanie)\nlt_LT\n\n\nLituanien\nlt\n\n\nMacédonien (Macédoine)\nmk_MK\n\n\nMacédonien\nmk\n\n\nMalais (Malaisie)\nms_MY\n\n\nMalais\nms\n\n\nMaltais (Malte)\nmt_MT\n\n\nMaltais\nmt\n\n\nNorvégien (Norvège)\nno_NO\n\n\nNorvégien (Norvège, Nynorsk)\nno_NO_NY\n\n\nNorvégien\nno\n\n\nPolonais (Pologne)\npl_PL\n\n\nPolonais\npl\n\n\nPortugais (Brésil)\npt_BR\n\n\nPortugais (Portugal)\npt_PT\n\n\nPortugais\npt\n\n\nRoumain (Roumanie)\nro_RO\n\n\nRoumain\nro\n\n\nRusse (Russie)\nru_RU\n\n\nRusse\nru\n\n\nSerbe (Bosnie-Herzégovine)\nsr_BA\n\n\nSerbe (Monténégro)\nsr_ME\n\n\nSerbe (Serbie et Monténégro)\nsr_CS\n\n\nSerbe (Serbie)\nsr_RS\n\n\nSerbe\nsr\n\n\nSlovaque (Slovaquie)\nsk_SK\n\n\nSlovaque\nsk\n\n\nSlovène (Slovénie)\nsl_SI\n\n\nSlovène\nsl\n\n\nEspagnol (Argentine)\nes_AR\n\n\nEspagnol (Bolivie)\nes_BO\n\n\nEspagnol (Chili)\nes_CL\n\n\nEspagnol (Colombie)\nes_CO\n\n\nEspagnol (Costa Rica)\nes_CR\n\n\nEspagnol (République dominicaine)\nes_DO\n\n\nEspagnol (Équateur)\nes_EC\n\n\nEspagnol (Salvador)\nes_SV\n\n\nEspagnol (Guatemala)\nes_GT\n\n\nEspagnol (Honduras)\nes_HN\n\n\nEspagnol (Mexique)\nes_MX\n\n\nEspagnol (Nicaragua)\nes_NI\n\n\nEspagnol (Panama)\nes_PA\n\n\nEspagnol (Paraguay)\nes_PY\n\n\nEspagnol (Pérou)\nes_PE\n\n\nEspagnol (Porto Rico)\nes_PR\n\n\nEspagnol (Espagne)\nes_ES\n\n\nEspagnol (États-Unis)\nes_US\n\n\nEspagnol (Uruguay)\nes_UY\n\n\nEspagnol (Venezuela)\nes_VE\n\n\nEspagnol\nes\n\n\nSuédois (Suède)\nsv_SE\n\n\nSuédois\nsv\n\n\nThaï (Thaïlande)\nth_TH\n\n\nThaï (Thaïlande,TH)\nth_TH_TH\n\n\nThaï\nth\n\n\nTurc (Turquie)\ntr_TR\n\n\nTurc\ntr\n\n\nUkrainien (Ukraine)\nuk_UA\n\n\nUkrainien\nuk\n\n\nVietnamien (Vietnam)\nvi_VN\n\n\nVietnamien\nvi\n\n\n",
      "content_html": "<h1>Codes de locale</h1>\n<p>Codes de locale disponibles (<code translate=\"no\">language_COUNTRY</code>) utilisés par l’option <a href=\"2-languages.fr.md#languages\"><code translate=\"no\">languages</code></a>.</p>\n<h2 id=\"liste-des-codes-de-locale\">Liste des codes de locale</h2>\n<table>\n<thead>\n<tr>\n<th>Locale</th>\n<th>Code</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Albanais (Albanie)</td>\n<td>sq_AL</td>\n</tr>\n<tr>\n<td>Albanais</td>\n<td>sq</td>\n</tr>\n<tr>\n<td>Arabe (Algérie)</td>\n<td>ar_DZ</td>\n</tr>\n<tr>\n<td>Arabe (Bahreïn)</td>\n<td>ar_BH</td>\n</tr>\n<tr>\n<td>Arabe (Égypte)</td>\n<td>ar_EG</td>\n</tr>\n<tr>\n<td>Arabe (Irak)</td>\n<td>ar_IQ</td>\n</tr>\n<tr>\n<td>Arabe (Jordanie)</td>\n<td>ar_JO</td>\n</tr>\n<tr>\n<td>Arabe (Koweït)</td>\n<td>ar_KW</td>\n</tr>\n<tr>\n<td>Arabe (Liban)</td>\n<td>ar_LB</td>\n</tr>\n<tr>\n<td>Arabe (Libye)</td>\n<td>ar_LY</td>\n</tr>\n<tr>\n<td>Arabe (Maroc)</td>\n<td>ar_MA</td>\n</tr>\n<tr>\n<td>Arabe (Oman)</td>\n<td>ar_OM</td>\n</tr>\n<tr>\n<td>Arabe (Qatar)</td>\n<td>ar_QA</td>\n</tr>\n<tr>\n<td>Arabe (Arabie saoudite)</td>\n<td>ar_SA</td>\n</tr>\n<tr>\n<td>Arabe (Soudan)</td>\n<td>ar_SD</td>\n</tr>\n<tr>\n<td>Arabe (Syrie)</td>\n<td>ar_SY</td>\n</tr>\n<tr>\n<td>Arabe (Tunisie)</td>\n<td>ar_TN</td>\n</tr>\n<tr>\n<td>Arabe (Émirats arabes unis)</td>\n<td>ar_AE</td>\n</tr>\n<tr>\n<td>Arabe (Yémen)</td>\n<td>ar_YE</td>\n</tr>\n<tr>\n<td>Arabe</td>\n<td>ar</td>\n</tr>\n<tr>\n<td>Biélorusse (Biélorussie)</td>\n<td>be_BY</td>\n</tr>\n<tr>\n<td>Biélorusse</td>\n<td>be</td>\n</tr>\n<tr>\n<td>Bulgare (Bulgarie)</td>\n<td>bg_BG</td>\n</tr>\n<tr>\n<td>Bulgare</td>\n<td>bg</td>\n</tr>\n<tr>\n<td>Catalan (Espagne)</td>\n<td>ca_ES</td>\n</tr>\n<tr>\n<td>Catalan</td>\n<td>ca</td>\n</tr>\n<tr>\n<td>Chinois (Chine)</td>\n<td>zh_CN</td>\n</tr>\n<tr>\n<td>Chinois (Hong Kong)</td>\n<td>zh_HK</td>\n</tr>\n<tr>\n<td>Chinois (Singapour)</td>\n<td>zh_SG</td>\n</tr>\n<tr>\n<td>Chinois (Taïwan)</td>\n<td>zh_TW</td>\n</tr>\n<tr>\n<td>Chinois</td>\n<td>zh</td>\n</tr>\n<tr>\n<td>Croate (Croatie)</td>\n<td>hr_HR</td>\n</tr>\n<tr>\n<td>Croate</td>\n<td>hr</td>\n</tr>\n<tr>\n<td>Tchèque (République tchèque)</td>\n<td>cs_CZ</td>\n</tr>\n<tr>\n<td>Tchèque</td>\n<td>cs</td>\n</tr>\n<tr>\n<td>Danois (Danemark)</td>\n<td>da_DK</td>\n</tr>\n<tr>\n<td>Danois</td>\n<td>da</td>\n</tr>\n<tr>\n<td>Néerlandais (Belgique)</td>\n<td>nl_BE</td>\n</tr>\n<tr>\n<td>Néerlandais (Pays-Bas)</td>\n<td>nl_NL</td>\n</tr>\n<tr>\n<td>Néerlandais</td>\n<td>nl</td>\n</tr>\n<tr>\n<td>Anglais (Australie)</td>\n<td>en_AU</td>\n</tr>\n<tr>\n<td>Anglais (Canada)</td>\n<td>en_CA</td>\n</tr>\n<tr>\n<td>Anglais (Inde)</td>\n<td>en_IN</td>\n</tr>\n<tr>\n<td>Anglais (Irlande)</td>\n<td>en_IE</td>\n</tr>\n<tr>\n<td>Anglais (Malte)</td>\n<td>en_MT</td>\n</tr>\n<tr>\n<td>Anglais (Nouvelle-Zélande)</td>\n<td>en_NZ</td>\n</tr>\n<tr>\n<td>Anglais (Philippines)</td>\n<td>en_PH</td>\n</tr>\n<tr>\n<td>Anglais (Singapour)</td>\n<td>en_SG</td>\n</tr>\n<tr>\n<td>Anglais (Afrique du Sud)</td>\n<td>en_ZA</td>\n</tr>\n<tr>\n<td>Anglais (Royaume-Uni)</td>\n<td>en_GB</td>\n</tr>\n<tr>\n<td>Anglais (États-Unis)</td>\n<td>en_US</td>\n</tr>\n<tr>\n<td>Anglais</td>\n<td>en</td>\n</tr>\n<tr>\n<td>Estonien (Estonie)</td>\n<td>et_EE</td>\n</tr>\n<tr>\n<td>Estonien</td>\n<td>et</td>\n</tr>\n<tr>\n<td>Finnois (Finlande)</td>\n<td>fi_FI</td>\n</tr>\n<tr>\n<td>Finnois</td>\n<td>fi</td>\n</tr>\n<tr>\n<td>Français (Belgique)</td>\n<td>fr_BE</td>\n</tr>\n<tr>\n<td>Français (Canada)</td>\n<td>fr_CA</td>\n</tr>\n<tr>\n<td>Français (France)</td>\n<td>fr_FR</td>\n</tr>\n<tr>\n<td>Français (Luxembourg)</td>\n<td>fr_LU</td>\n</tr>\n<tr>\n<td>Français (Suisse)</td>\n<td>fr_CH</td>\n</tr>\n<tr>\n<td>Français</td>\n<td>fr</td>\n</tr>\n<tr>\n<td>Allemand (Autriche)</td>\n<td>de_AT</td>\n</tr>\n<tr>\n<td>Allemand (Allemagne)</td>\n<td>de_DE</td>\n</tr>\n<tr>\n<td>Allemand (Luxembourg)</td>\n<td>de_LU</td>\n</tr>\n<tr>\n<td>Allemand (Suisse)</td>\n<td>de_CH</td>\n</tr>\n<tr>\n<td>Allemand</td>\n<td>de</td>\n</tr>\n<tr>\n<td>Grec (Chypre)</td>\n<td>el_CY</td>\n</tr>\n<tr>\n<td>Grec (Grèce)</td>\n<td>el_GR</td>\n</tr>\n<tr>\n<td>Grec</td>\n<td>el</td>\n</tr>\n<tr>\n<td>Hébreu (Israël)</td>\n<td>iw_IL</td>\n</tr>\n<tr>\n<td>Hébreu</td>\n<td>iw</td>\n</tr>\n<tr>\n<td>Hindi (Inde)</td>\n<td>hi_IN</td>\n</tr>\n<tr>\n<td>Hongrois (Hongrie)</td>\n<td>hu_HU</td>\n</tr>\n<tr>\n<td>Hongrois</td>\n<td>hu</td>\n</tr>\n<tr>\n<td>Islandais (Islande)</td>\n<td>is_IS</td>\n</tr>\n<tr>\n<td>Islandais</td>\n<td>is</td>\n</tr>\n<tr>\n<td>Indonésien (Indonésie)</td>\n<td>in_ID</td>\n</tr>\n<tr>\n<td>Indonésien</td>\n<td>in</td>\n</tr>\n<tr>\n<td>Irlandais (Irlande)</td>\n<td>ga_IE</td>\n</tr>\n<tr>\n<td>Irlandais</td>\n<td>ga</td>\n</tr>\n<tr>\n<td>Italien (Italie)</td>\n<td>it_IT</td>\n</tr>\n<tr>\n<td>Italien (Suisse)</td>\n<td>it_CH</td>\n</tr>\n<tr>\n<td>Italien</td>\n<td>it</td>\n</tr>\n<tr>\n<td>Japonais (Japon)</td>\n<td>ja_JP</td>\n</tr>\n<tr>\n<td>Japonais (Japon,JP)</td>\n<td>ja_JP_JP</td>\n</tr>\n<tr>\n<td>Japonais</td>\n<td>ja</td>\n</tr>\n<tr>\n<td>Coréen (Corée du Sud)</td>\n<td>ko_KR</td>\n</tr>\n<tr>\n<td>Coréen</td>\n<td>ko</td>\n</tr>\n<tr>\n<td>Letton (Lettonie)</td>\n<td>lv_LV</td>\n</tr>\n<tr>\n<td>Letton</td>\n<td>lv</td>\n</tr>\n<tr>\n<td>Lituanien (Lituanie)</td>\n<td>lt_LT</td>\n</tr>\n<tr>\n<td>Lituanien</td>\n<td>lt</td>\n</tr>\n<tr>\n<td>Macédonien (Macédoine)</td>\n<td>mk_MK</td>\n</tr>\n<tr>\n<td>Macédonien</td>\n<td>mk</td>\n</tr>\n<tr>\n<td>Malais (Malaisie)</td>\n<td>ms_MY</td>\n</tr>\n<tr>\n<td>Malais</td>\n<td>ms</td>\n</tr>\n<tr>\n<td>Maltais (Malte)</td>\n<td>mt_MT</td>\n</tr>\n<tr>\n<td>Maltais</td>\n<td>mt</td>\n</tr>\n<tr>\n<td>Norvégien (Norvège)</td>\n<td>no_NO</td>\n</tr>\n<tr>\n<td>Norvégien (Norvège, Nynorsk)</td>\n<td>no_NO_NY</td>\n</tr>\n<tr>\n<td>Norvégien</td>\n<td>no</td>\n</tr>\n<tr>\n<td>Polonais (Pologne)</td>\n<td>pl_PL</td>\n</tr>\n<tr>\n<td>Polonais</td>\n<td>pl</td>\n</tr>\n<tr>\n<td>Portugais (Brésil)</td>\n<td>pt_BR</td>\n</tr>\n<tr>\n<td>Portugais (Portugal)</td>\n<td>pt_PT</td>\n</tr>\n<tr>\n<td>Portugais</td>\n<td>pt</td>\n</tr>\n<tr>\n<td>Roumain (Roumanie)</td>\n<td>ro_RO</td>\n</tr>\n<tr>\n<td>Roumain</td>\n<td>ro</td>\n</tr>\n<tr>\n<td>Russe (Russie)</td>\n<td>ru_RU</td>\n</tr>\n<tr>\n<td>Russe</td>\n<td>ru</td>\n</tr>\n<tr>\n<td>Serbe (Bosnie-Herzégovine)</td>\n<td>sr_BA</td>\n</tr>\n<tr>\n<td>Serbe (Monténégro)</td>\n<td>sr_ME</td>\n</tr>\n<tr>\n<td>Serbe (Serbie et Monténégro)</td>\n<td>sr_CS</td>\n</tr>\n<tr>\n<td>Serbe (Serbie)</td>\n<td>sr_RS</td>\n</tr>\n<tr>\n<td>Serbe</td>\n<td>sr</td>\n</tr>\n<tr>\n<td>Slovaque (Slovaquie)</td>\n<td>sk_SK</td>\n</tr>\n<tr>\n<td>Slovaque</td>\n<td>sk</td>\n</tr>\n<tr>\n<td>Slovène (Slovénie)</td>\n<td>sl_SI</td>\n</tr>\n<tr>\n<td>Slovène</td>\n<td>sl</td>\n</tr>\n<tr>\n<td>Espagnol (Argentine)</td>\n<td>es_AR</td>\n</tr>\n<tr>\n<td>Espagnol (Bolivie)</td>\n<td>es_BO</td>\n</tr>\n<tr>\n<td>Espagnol (Chili)</td>\n<td>es_CL</td>\n</tr>\n<tr>\n<td>Espagnol (Colombie)</td>\n<td>es_CO</td>\n</tr>\n<tr>\n<td>Espagnol (Costa Rica)</td>\n<td>es_CR</td>\n</tr>\n<tr>\n<td>Espagnol (République dominicaine)</td>\n<td>es_DO</td>\n</tr>\n<tr>\n<td>Espagnol (Équateur)</td>\n<td>es_EC</td>\n</tr>\n<tr>\n<td>Espagnol (Salvador)</td>\n<td>es_SV</td>\n</tr>\n<tr>\n<td>Espagnol (Guatemala)</td>\n<td>es_GT</td>\n</tr>\n<tr>\n<td>Espagnol (Honduras)</td>\n<td>es_HN</td>\n</tr>\n<tr>\n<td>Espagnol (Mexique)</td>\n<td>es_MX</td>\n</tr>\n<tr>\n<td>Espagnol (Nicaragua)</td>\n<td>es_NI</td>\n</tr>\n<tr>\n<td>Espagnol (Panama)</td>\n<td>es_PA</td>\n</tr>\n<tr>\n<td>Espagnol (Paraguay)</td>\n<td>es_PY</td>\n</tr>\n<tr>\n<td>Espagnol (Pérou)</td>\n<td>es_PE</td>\n</tr>\n<tr>\n<td>Espagnol (Porto Rico)</td>\n<td>es_PR</td>\n</tr>\n<tr>\n<td>Espagnol (Espagne)</td>\n<td>es_ES</td>\n</tr>\n<tr>\n<td>Espagnol (États-Unis)</td>\n<td>es_US</td>\n</tr>\n<tr>\n<td>Espagnol (Uruguay)</td>\n<td>es_UY</td>\n</tr>\n<tr>\n<td>Espagnol (Venezuela)</td>\n<td>es_VE</td>\n</tr>\n<tr>\n<td>Espagnol</td>\n<td>es</td>\n</tr>\n<tr>\n<td>Suédois (Suède)</td>\n<td>sv_SE</td>\n</tr>\n<tr>\n<td>Suédois</td>\n<td>sv</td>\n</tr>\n<tr>\n<td>Thaï (Thaïlande)</td>\n<td>th_TH</td>\n</tr>\n<tr>\n<td>Thaï (Thaïlande,TH)</td>\n<td>th_TH_TH</td>\n</tr>\n<tr>\n<td>Thaï</td>\n<td>th</td>\n</tr>\n<tr>\n<td>Turc (Turquie)</td>\n<td>tr_TR</td>\n</tr>\n<tr>\n<td>Turc</td>\n<td>tr</td>\n</tr>\n<tr>\n<td>Ukrainien (Ukraine)</td>\n<td>uk_UA</td>\n</tr>\n<tr>\n<td>Ukrainien</td>\n<td>uk</td>\n</tr>\n<tr>\n<td>Vietnamien (Vietnam)</td>\n<td>vi_VN</td>\n</tr>\n<tr>\n<td>Vietnamien</td>\n<td>vi</td>\n</tr>\n</tbody>\n</table>",
      "language": "fr"
    }
  ]
}
