<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://cecil-945.pages.dev/fr/xsl/atom.xsl" media="all"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
  <id>https://cecil-945.pages.dev/fr/comment-faire/</id>
  <title>Cecil - Comment faire ?</title>
  <subtitle><![CDATA[Cecil est une application PHP en ligne de commande qui fusionne des pages Markdown, des médias et des templates Twig afin de générer un site web statique.]]></subtitle>
  <link href="https://cecil-945.pages.dev/fr/comment-faire/atom.xml" rel="self" type="application/atom+xml" />
  <link href="https://cecil-945.pages.dev/fr/comment-faire/" rel="alternate" type="text/html" />
  <updated>2026-10-14T15:46:02+00:00</updated>
  <author>
    <name>Cecil</name>
    <uri>https://cecil-945.pages.dev/</uri>
  </author>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/markdown-sommaire-notes/</id>
    <title>Ajouter une table des matières et des notes</title>
    <published>2026-10-14T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/markdown-sommaire-notes/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Cecil étend Markdown avec quelques fonctionnalités pratiques pour les pages longues : une table des matières automatique, des blocs de notes et des attributs sur les éléments.</p>
<h2 id="inserer-une-table-des-matieres">Insérer une table des matières</h2>
<p>Ajoutez la balise <code translate="no">[toc]</code> à l’endroit où la table des matières doit apparaître dans le corps de la page :</p>
<pre><code class="language-markdown hljs markdown" translate="no">[toc]

<span class="hljs-section">## Installation</span>
<span class="hljs-section">### Requirements</span>
<span class="hljs-section">## Usage</span></code></pre>
<p>Par défaut, la table des matières est construite à partir des titres H2 et H3. Modifiez ce comportement dans <code translate="no">cecil.yml</code> :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">pages:</span>
  <span class="hljs-attr">body:</span>
    <span class="hljs-attr">toc:</span> <span class="hljs-string">[h2,</span> <span class="hljs-string">h3,</span> <span class="hljs-string">h4]</span></code></pre>
<h2 id="afficher-la-table-des-matieres-dans-un-template">Afficher la table des matières dans un template</h2>
<p>Pour placer la table des matières en dehors du contenu (ex. dans une barre latérale), utilisez le filtre <code translate="no">toc</code> sur le corps de la page :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">aside</span>&gt;</span>
  </span><span class="hljs-template-variable">{{ page.body|toc }}</span><span class="xml">
<span class="hljs-tag">&lt;/<span class="hljs-name">aside</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">article</span>&gt;</span>
  </span><span class="hljs-template-variable">{{ page.content }}</span><span class="xml">
<span class="hljs-tag">&lt;/<span class="hljs-name">article</span>&gt;</span></span></code></pre>
<p>Le filtre accepte aussi les titres à extraire, ex. <code translate="no">{{ page.body|toc(selectors=['h2']) }}</code>.</p>
<h2 id="ajouter-des-notes">Ajouter des notes</h2>
<p>Mettez en avant une information avec un bloc de note :</p>
<pre><code class="language-markdown hljs markdown" translate="no">:::tip
<span class="hljs-strong">**Tip:**</span> This is advice.
:::</code></pre>
<p>Est converti en :</p>
<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>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
    <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.
  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">aside</span>&gt;</span></code></pre>
<p>Les types disponibles sont <code translate="no">info</code>, <code translate="no">tip</code>, <code translate="no">important</code>, <code translate="no">warning</code> et <code translate="no">caution</code> (ou aucun type). Stylisez-les avec les classes CSS <code translate="no">note</code> et <code translate="no">note-&lt;type&gt;</code>.</p>
<h2 id="ajouter-des-attributs">Ajouter des attributs</h2>
<p>Définissez un id, une classe ou n’importe quel attribut sur un titre, un bloc de code, un lien ou une image, entre accolades à la fin de la ligne :</p>
<pre><code class="language-markdown hljs markdown" translate="no"><span class="hljs-section">## Installation {#install .highlighted}</span></code></pre>
<p>L’id <code translate="no">#install</code> fournit une ancre stable vers laquelle créer un lien : <code translate="no">[Voir l’installation](#install)</code>.</p>
<aside class="note note-warning"><p>Pour un élément en ligne, comme un lien, ajoutez un saut de ligne après l’accolade fermante.</p></aside>
<aside class="note note-info"><p>Consultez la documentation de la <a href="/documentation/content/#table-of-contents">table des matières</a>, des <a href="/documentation/content/#notes">notes</a>, des <a href="/documentation/content/#attributes">attributs</a> et du <a href="/documentation/templates/#toc">filtre <code translate="no">toc</code></a>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/contenu-redirection-alias/</id>
    <title>Rediriger d’anciennes URL</title>
    <published>2026-10-13T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/contenu-redirection-alias/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Quand une page est déplacée ou renommée, son ancienne URL ne doit pas mener à une erreur 404. Cecil propose deux variables de front matter pour cela : <code translate="no">alias</code> et <code translate="no">redirect</code>.</p>
<h2 id="rediriger-d-anciennes-url-vers-une-page">Rediriger d’anciennes URL vers une page</h2>
<p>La variable <code translate="no">alias</code> liste les anciens chemins de la page courante. Chacun d’eux redirige vers la page :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">About</span>
<span class="hljs-attr">alias:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">contact</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">about-us</span>
<span class="hljs-meta">---</span></code></pre>
<p>Dans cet exemple, <code translate="no">/contact/</code> et <code translate="no">/about-us/</code> redirigent vers <code translate="no">/about/</code>.</p>
<h2 id="rediriger-une-page-vers-une-autre-url">Rediriger une page vers une autre URL</h2>
<p>La variable <code translate="no">redirect</code> transforme une page en redirection vers l’URL indiquée, interne ou externe :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">Ancienne</span> <span class="hljs-string">documentation</span>
<span class="hljs-attr">redirect:</span> <span class="hljs-string">"https://cecil.app/documentation/"</span>
<span class="hljs-meta">---</span></code></pre>
<h2 id="sans-fichier-markdown">Sans fichier Markdown</h2>
<p>Si l’ancienne page n’a plus de contenu, déclarez-la comme <a href="/documentation/configuration/#pages-virtual">page virtuelle</a> dans <code translate="no">cecil.yml</code> :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">pages:</span>
  <span class="hljs-attr">virtual:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">path:</span> <span class="hljs-string">code</span>
      <span class="hljs-attr">redirect:</span> <span class="hljs-string">https://github.com/Cecilapp/Cecil</span></code></pre>
<h2 id="pages-generees">Pages générées</h2>
<p>Pour chaque alias et chaque redirection, Cecil génère une page avec le template intégré <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>. Elle contient :</p>
<ul>
<li>un <code translate="no">&lt;link rel="canonical"&gt;</code> vers l’URL cible</li>
<li>une balise <code translate="no">&lt;meta name="robots" content="noindex"&gt;</code>, pour que les moteurs de recherche ne l’indexent pas</li>
<li>une balise <code translate="no">&lt;meta http-equiv="refresh"&gt;</code> et une redirection JavaScript</li>
<li>un lien de secours pour les visiteurs</li>
</ul>
<aside class="note note-tip"><p>Pour personnaliser cette page, créez votre propre template <code translate="no">layouts/redirect.html.twig</code> : il est prioritaire sur le template intégré.</p></aside>
<aside class="note note-info"><p>Consultez la documentation des variables <a href="/documentation/content/#redirect"><code translate="no">redirect</code></a> et <a href="/documentation/content/#alias"><code translate="no">alias</code></a>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/configuration-environnements/</id>
    <title>Utiliser des réglages différents selon l’environnement</title>
    <published>2026-10-12T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/configuration-environnements/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Le site local et le site de production partagent rarement les mêmes réglages : URL de base, mode debug, répertoire de sortie… Cecil permet de conserver un unique <code translate="no">cecil.yml</code> et de le surcharger selon l’environnement.</p>
<h2 id="garder-les-valeurs-de-production-dans-cecil-yml">Garder les valeurs de production dans <code translate="no">cecil.yml</code></h2>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">title:</span> <span class="hljs-string">"My site"</span>
<span class="hljs-attr">baseurl:</span> <span class="hljs-string">https://example.com/</span>
<span class="hljs-attr">debug:</span> <span class="hljs-literal">false</span></code></pre>
<h2 id="surcharger-avec-des-fichiers-de-configuration-supplementaires">Surcharger avec des fichiers de configuration supplémentaires</h2>
<p>Créez un fichier contenant uniquement les clés à modifier, par exemple <code translate="no">config/dev.yml</code> :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">baseurl:</span> <span class="hljs-string">http://localhost:8000/</span>
<span class="hljs-attr">debug:</span> <span class="hljs-literal">true</span></code></pre>
<p>Puis chargez-le avec l’option <code translate="no">--config</code>, disponible avec les commandes <code translate="no">build</code> et <code translate="no">serve</code> :</p>
<pre><code class="language-bash hljs bash" translate="no">php cecil.phar serve --config=config/dev.yml</code></pre>
<p>Vous pouvez passer plusieurs fichiers, séparés par des virgules. Ils sont fusionnés dans l’ordre après <code translate="no">cecil.yml</code> : chaque fichier surcharge donc les précédents.</p>
<pre><code class="language-bash hljs bash" translate="no">php cecil.phar build --config=config/prod.yml,config/local.yml</code></pre>
<h2 id="surcharger-avec-des-variables-d-environnement">Surcharger avec des variables d’environnement</h2>
<p>Toute clé de configuration peut être définie par une variable d’environnement préfixée par <code translate="no">CECIL_</code>, en majuscules. Les clés imbriquées sont séparées par un underscore (par exemple <code translate="no">CECIL_OUTPUT_DIR</code> définit <code translate="no">output.dir</code>) :</p>
<pre><code class="language-bash hljs bash" translate="no"><span class="hljs-built_in">export</span> CECIL_BASEURL=<span class="hljs-string">"https://staging.example.com/"</span>
<span class="hljs-built_in">export</span> CECIL_DEBUG=<span class="hljs-literal">true</span>
php cecil.phar build</code></pre>
<p>Cecil charge aussi un fichier <code translate="no">.env</code> à la racine du site, s’il existe (les variables déjà définies par le système sont conservées) :</p>
<pre><code class="language-dotenv" translate="no">CECIL_BASEURL="http://localhost:8000/"
CECIL_DEBUG=true</code></pre>
<p>Les variables d’environnement sont appliquées par-dessus les fichiers de configuration, ce qui les rend pratiques en CI, par exemple :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-comment"># .gitlab-ci.yml</span>
<span class="hljs-attr">pages:</span>
  <span class="hljs-attr">variables:</span>
    <span class="hljs-attr">CECIL_ENV:</span> <span class="hljs-string">production</span>
    <span class="hljs-attr">CECIL_OUTPUT_DIR:</span> <span class="hljs-string">public</span></code></pre>
<h2 id="lire-l-environnement-dans-les-templates">Lire l’environnement dans les templates</h2>
<p>Utilisez la fonction <code translate="no">getenv</code> pour adapter les templates, par exemple pour n’inclure les statistiques d’audience qu’en production :</p>
<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> getenv('CECIL_ENV') == 'production' %}</span><span class="xml">
  </span><span class="hljs-template-variable">{{ <span class="hljs-name">include</span><span class="hljs-params">('partials/analytics.html.twig')</span> }}</span><span class="xml">
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span></code></pre>
<p>La variable <code translate="no">site.debug</code> indique si le mode debug est activé :</p>
<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> site.debug %}</span><span class="hljs-template-variable">{{ <span class="hljs-name">dump</span><span class="hljs-params">(page)</span> }}</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span></code></pre>
<aside class="note note-info"><p>Consultez la documentation pour <a href="/documentation/configuration/#override-configuration">surcharger la configuration</a>, l’<a href="/documentation/configuration/#debug">option <code translate="no">debug</code></a> et la <a href="/documentation/templates/#getenv">fonction <code translate="no">getenv</code></a>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/templates-assets-scss/</id>
    <title>Compiler, minifier et empreinter CSS et JavaScript</title>
    <published>2026-10-11T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/templates-assets-scss/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Cecil peut compiler des fichiers <a href="https://sass-lang.com" target="_blank" rel="noopener noreferrer">Sass</a>, minifier le CSS et le JavaScript, et ajouter une empreinte du contenu aux noms de fichiers (cache busting) directement depuis vos templates, sans outil de build externe.</p>
<h2 id="configurer-le-traitement-des-assets">Configurer le traitement des assets</h2>
<p>Les fichiers sources sont stockés dans le répertoire <code translate="no">assets/</code>. Le traitement est activé par défaut et peut être ajusté dans <code translate="no">cecil.yml</code> :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">assets:</span>
  <span class="hljs-attr">compile:</span>
    <span class="hljs-attr">style:</span> <span class="hljs-string">compressed</span>    <span class="hljs-comment"># `expanded` ou `compressed`</span>
    <span class="hljs-attr">import:</span> <span class="hljs-string">[sass,</span> <span class="hljs-string">scss]</span> <span class="hljs-comment"># chemins importés</span>
  <span class="hljs-attr">minify:</span> <span class="hljs-literal">true</span>           <span class="hljs-comment"># minifie le CSS et le JS</span>
  <span class="hljs-attr">fingerprint:</span> <span class="hljs-literal">true</span>      <span class="hljs-comment"># ajoute l’empreinte du contenu aux noms de fichiers</span></code></pre>
<h2 id="charger-une-feuille-de-style">Charger une feuille de style</h2>
<p>Créez un <em>asset</em> à partir d’un fichier Sass, compilez-le avec <code translate="no">to_css</code> et générez l’élément <code translate="no">&lt;link&gt;</code> avec la fonction <code translate="no">html</code> :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="hljs-template-variable">{{ html(asset('css/styles.scss')|to_css|minify) }}</span></code></pre>
<p>Les filtres peuvent être chaînés pour contrôler chaque étape explicitement, ce qui est utile si une fonctionnalité est désactivée globalement :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="hljs-template-variable">{{ asset('css/styles.scss')|to_css|minify|fingerprint }}</span></code></pre>
<h2 id="regrouper-des-fichiers-javascript">Regrouper des fichiers JavaScript</h2>
<p>Passez un tableau de chemins pour créer un bundle unique, avec un nom de fichier personnalisé :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="hljs-template-variable">{{ html(asset(['js/menu.js', 'js/search.js'], {filename: 'scripts.js'})) }}</span></code></pre>
<p>Les options peuvent aussi être définies par asset, par exemple pour laisser un fichier distant intact :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="hljs-template-variable">{{ html(asset('https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.3.1/anchor.<span class="hljs-name">min</span>.js', {minify: false})) }}</span></code></pre>
<h2 id="ajouter-l-integrite-des-sous-ressources">Ajouter l’intégrité des sous-ressources</h2>
<p>Utilisez la fonction <code translate="no">integrity</code> (ou l’attribut <code translate="no">integrity</code> de l’asset) pour générer un hash <code translate="no">sha384</code> :</p>
<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 = asset('css/styles.scss')|to_css %}</span><span class="xml">
<span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ url(styles) }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ integrity(styles) }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span></span></code></pre>
<h2 id="integrer-le-css-critique">Intégrer le CSS critique</h2>
<p>Affichez le contenu d’un asset avec le filtre <code translate="no">inline</code> :</p>
<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></span><span class="hljs-template-variable">{{ asset('css/critical.scss')|to_css|minify|inline }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></span></code></pre>
<p>Pour quelques lignes de styles écrites directement dans le template, utilisez les filtres <code translate="no">scss_to_css</code> et <code translate="no">minify_css</code> :</p>
<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>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">apply</span></span> scss_to_css|minify_css %}</span><span class="xml">
  $color: #fcfcfc;
  body {
    background-color: $color;
  }
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endapply</span></span> %}</span><span class="xml">
<span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></span></code></pre>
<aside class="note note-info"><p>Consultez la documentation de la <a href="/documentation/templates/#asset">fonction <code translate="no">asset</code></a>, des <a href="/documentation/templates/#filters">filtres</a> et de la <a href="/documentation/configuration/#assets">configuration des assets</a>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/contenu-taxonomies/</id>
    <title>Organiser les pages avec des tags et des catégories</title>
    <published>2026-10-10T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/contenu-taxonomies/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Les taxonomies permettent de classer les pages avec des termes (ex. <code translate="no">PHP</code>) regroupés dans des vocabulaires (ex. <code translate="no">tags</code>). Cecil génère ensuite une page par vocabulaire et une page par terme.</p>
<h2 id="declarer-les-vocabulaires">Déclarer les vocabulaires</h2>
<p>Les vocabulaires sont déclarés dans <code translate="no">cecil.yml</code>, par paires de noms au pluriel et au singulier :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">taxonomies:</span>
  <span class="hljs-attr">categories:</span> <span class="hljs-string">category</span>
  <span class="hljs-attr">tags:</span> <span class="hljs-string">tag</span></code></pre>
<aside class="note note-warning"><p>Il n’existe pas de vocabulaire par défaut : vous devez les déclarer pour les utiliser.</p></aside>
<h2 id="classer-les-pages">Classer les pages</h2>
<p>Ajoutez les termes dans le front matter de vos pages, en utilisant le nom au pluriel du vocabulaire :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">Mon</span> <span class="hljs-string">premier</span> <span class="hljs-string">billet</span>
<span class="hljs-attr">categories:</span> <span class="hljs-string">["Development"]</span>
<span class="hljs-attr">tags:</span> <span class="hljs-string">["PHP",</span> <span class="hljs-string">"Static site"</span><span class="hljs-string">]</span>
<span class="hljs-meta">---</span></code></pre>
<p>Cecil génère :</p>
<ul>
<li><code translate="no">/tags/</code> : la liste des termes du vocabulaire</li>
<li><code translate="no">/tags/php/</code> et <code translate="no">/tags/static-site/</code> : la liste des pages de chaque terme</li>
</ul>
<h2 id="personnaliser-la-liste-des-termes">Personnaliser la liste des termes</h2>
<p>Le template de <em>vocabulaire</em> est nommé d’après le <strong>pluriel</strong>, ex. <code translate="no">layouts/taxonomy/tags.html.twig</code> :</p>
<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">

</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">block</span></span> content %}</span><span class="xml">
  <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>
  <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  </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">
    <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>
  </span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endfor</span></span> %}</span><span class="xml">
  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endblock</span></span> %}</span></code></pre>
<h2 id="personnaliser-les-pages-d-un-terme">Personnaliser les pages d’un terme</h2>
<p>Le template de <em>terme</em> est nommé d’après le <strong>singulier</strong>, ex. <code translate="no">layouts/taxonomy/tag.html.twig</code> :</p>
<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">

</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">block</span></span> content %}</span><span class="xml">
  <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>
  </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">
    <span class="hljs-tag">&lt;<span class="hljs-name">article</span>&gt;</span>
      <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>
    <span class="hljs-tag">&lt;/<span class="hljs-name">article</span>&gt;</span>
  </span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endfor</span></span> %}</span><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.plural) }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span>All </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>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endblock</span></span> %}</span></code></pre>
<h2 id="afficher-les-termes-d-une-page">Afficher les termes d’une page</h2>
<p>Dans un template de page, liez chaque terme à sa page :</p>
<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> tag in page.tags ?? [] %}</span><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('tags/' ~ tag) }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span></span><span class="hljs-template-variable">{{ tag }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endfor</span></span> %}</span></code></pre>
<p>Ou utilisez le partial intégré : <code translate="no">{{ include('partials/terms-list.html.twig', {vocabulary: 'tags'}) }}</code>.</p>
<aside class="note note-info"><p>Consultez la documentation de la <a href="/documentation/configuration/#taxonomies">configuration des taxonomies</a>, des <a href="/documentation/templates/#type-vocabulary">règles de sélection des templates</a> et des <a href="/documentation/templates/#page">variables de taxonomie</a>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/templates-menus/</id>
    <title>Construire un menu de navigation</title>
    <published>2026-10-09T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/templates-menus/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Cecil gère les menus de navigation comme des collections d’entrées (nom, URL, poids) que vous pouvez déclarer dans la configuration ou directement dans les pages, puis afficher n’importe où dans vos templates.</p>
<h2 id="declarer-des-entrees-dans-la-configuration">Déclarer des entrées dans la configuration</h2>
<p>Ajoutez une section <code translate="no">menus</code> dans <code translate="no">cecil.yml</code>. Chaque menu (ex. : <code translate="no">main</code>, <code translate="no">footer</code>) est une liste d’entrées avec un <code translate="no">id</code> unique :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">menus:</span>
  <span class="hljs-attr">main:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">id:</span> <span class="hljs-string">about</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">"About"</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">/about/</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">1</span>
  <span class="hljs-attr">footer:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">id:</span> <span class="hljs-string">github</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">"GitHub"</span>
      <span class="hljs-attr">url:</span> <span class="hljs-string">https://github.com/Cecilapp/Cecil</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">99</span></code></pre>
<aside class="note note-info"><p>Un menu <code translate="no">main</code> est automatiquement créé avec l’entrée de la page d’accueil et celles de toutes les sections.</p></aside>
<h2 id="ajouter-une-page-depuis-son-front-matter">Ajouter une page depuis son front matter</h2>
<p>Une page peut s’ajouter à un ou plusieurs menus avec la variable <code translate="no">menu</code>. Le nom de l’entrée est le <code translate="no">title</code> de la page et l’URL est son chemin :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">Our</span> <span class="hljs-string">Expertise</span>
<span class="hljs-attr">menu:</span>
  <span class="hljs-attr">main:</span>
    <span class="hljs-attr">weight:</span> <span class="hljs-number">15</span>
  <span class="hljs-attr">footer:</span>
    <span class="hljs-attr">weight:</span> <span class="hljs-number">15</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">"Expertise"</span> <span class="hljs-comment"># surcharge le nom de l’entrée dans ce menu</span>
<span class="hljs-meta">---</span></code></pre>
<h2 id="surcharger-ou-desactiver-une-entree">Surcharger ou désactiver une entrée</h2>
<p>Utilisez l’ID de la page comme <code translate="no">id</code> pour surcharger une entrée existante, ou <code translate="no">enabled: false</code> pour la retirer :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">menus:</span>
  <span class="hljs-attr">main:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">id:</span> <span class="hljs-string">index</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">"Home"</span>
      <span class="hljs-attr">weight:</span> <span class="hljs-number">1</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">id:</span> <span class="hljs-string">about</span>
      <span class="hljs-attr">enabled:</span> <span class="hljs-literal">false</span></code></pre>
<h2 id="afficher-le-menu">Afficher le menu</h2>
<p>Bouclez sur <code translate="no">site.menus.&lt;menu&gt;</code>, trié par poids, et comparez l’ID de chaque entrée avec celui de la page courante pour mettre en évidence l’élément actif :</p>
<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>
  <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  </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">
    <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></span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">if</span></span> entry.id == page.id %}</span><span class="xml"><span class="hljs-tag"> <span class="hljs-attr">aria-current</span>=<span class="hljs-string">"page"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"active"</span></span></span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span><span class="xml"><span class="hljs-tag">&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>
  </span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endfor</span></span> %}</span><span class="xml">
  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span></span></code></pre>
<p>Une entrée peut aussi être atteinte directement par son ID :</p>
<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> site.menus.main.about is defined %}</span><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(site.menus.main.about.url) }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span></span><span class="hljs-template-variable">{{ site.menus.main.about.name }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span></code></pre>
<aside class="note note-tip"><p>Cecil fournit également un partial intégré : <code translate="no">{{ include('partials/navigation.html.twig', {menu: 'main'}) }}</code>.</p></aside>
<aside class="note note-info"><p>Consultez la documentation de la <a href="/documentation/configuration/#menus">configuration des menus</a>, de la <a href="/documentation/content/#menu">variable de front matter <code translate="no">menu</code></a> et de la <a href="/documentation/templates/#site">variable <code translate="no">site.menus</code></a>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/sortie-index-de-recherche/</id>
    <title>Ajouter une recherche côté client</title>
    <published>2026-10-08T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/sortie-index-de-recherche/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Un site statique n’a pas de recherche côté serveur, mais Cecil peut générer un <strong>index JSON de vos pages</strong> au moment du build. Quelques lignes de JavaScript suffisent ensuite pour l’interroger dans le navigateur.</p>
<h2 id="creer-la-page-d-index">Créer la page d’index</h2>
<p>Créez une page dont le seul <a href="/documentation/content/#output">format de sortie</a> est <code translate="no">json</code>, avec un layout dédié :</p>
<p><em>pages/search.md</em></p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">Search</span> <span class="hljs-string">index</span>
<span class="hljs-attr">layout:</span> <span class="hljs-string">search</span>
<span class="hljs-attr">output:</span> <span class="hljs-string">json</span>
<span class="hljs-attr">excluded:</span> <span class="hljs-literal">true</span>
<span class="hljs-meta">---</span></code></pre>
<p><a href="/documentation/content/#excluded"><code translate="no">excluded: true</code></a> exclut cette page technique des pages de liste et du sitemap.</p>
<h2 id="ecrire-le-template-json">Écrire le template JSON</h2>
<p>Selon les <a href="/documentation/templates/#lookup-rules">règles de recherche</a>, Cecil génère cette page avec <code translate="no">layouts/search.json.twig</code>. Construisez un tableau des pages <a href="/documentation/templates/#site">affichables</a> (<em>showable</em>), puis encodez-le :</p>
<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> index = [] -%}</span><span class="xml">
</span><span class="hljs-template-tag">{%- <span class="hljs-name"><span class="hljs-keyword">for</span></span> p in site.pages.showable|<span class="hljs-keyword">filter</span>(p =&gt; p.type == 'page') -%}</span><span class="xml">
  </span><span class="hljs-template-tag">{%- <span class="hljs-name"><span class="hljs-keyword">set</span></span> index = index|<span class="hljs-keyword">merge</span>([{
    title: p.title,
    url: url(p),
    description: p.description|<span class="hljs-keyword">default</span>(''),
    content: p.content|<span class="hljs-keyword">striptags</span>|excerpt(300)
  }]) -%}</span><span class="xml">
</span><span class="hljs-template-tag">{%- <span class="hljs-name"><span class="hljs-keyword">endfor</span></span> -%}</span><span class="xml">
</span><span class="hljs-template-variable">{{ index|<span class="hljs-keyword">json_encode</span>(<span class="hljs-name">constant</span><span class="hljs-params">('JSON_UNESCAPED_UNICODE')</span> b-or <span class="hljs-name">constant</span><span class="hljs-params">('JSON_UNESCAPED_SLASHES')</span>)|<span class="hljs-keyword">raw</span> }}</span></code></pre>
<p>Après <code translate="no">php cecil.phar build</code>, l’index est disponible à l’adresse <code translate="no">/search.json</code>.</p>
<aside class="note note-info"><p>Consultez la documentation de la <a href="/documentation/content/#output">variable <code translate="no">output</code></a>, des <a href="/documentation/configuration/#output-formats">formats de sortie</a> et de la <a href="/documentation/templates/#url">fonction <code translate="no">url</code></a>.</p></aside>
<h2 id="rechercher-avec-fuse-js">Rechercher avec Fuse.js</h2>
<p>Ajoutez un champ de recherche dans un template et chargez <a href="https://www.fusejs.io" target="_blank" rel="noopener noreferrer">Fuse.js</a> depuis un CDN pour interroger l’index :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"search"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"search"</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Rechercher…"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"results"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>&gt;</span><span class="javascript">
  <span class="hljs-keyword">import</span> Fuse <span class="hljs-keyword">from</span> <span class="hljs-string">'https://cdn.jsdelivr.net/npm/fuse.js@7/dist/fuse.mjs'</span>;

  <span class="hljs-keyword">const</span> index = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'</span></span></span><span class="hljs-template-variable">{{ url('search', {format: 'json'}) }}</span><span class="xml">').then(r =&gt; r.json());
  const fuse = new Fuse(index, { keys: ['title', 'description', 'content'], threshold: 0.3 });
  const results = document.getElementById('results');

  document.getElementById('search').addEventListener('input', (e) =&gt; {
    results.replaceChildren(...fuse.search(e.target.value, { limit: 10 }).map(({ item }) =&gt; {
      const li = document.createElement('li');
      const a = document.createElement('a');
      a.href = item.url;
      a.textContent = item.title;
      li.append(a);
      return li;
    }));
  });
<span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span></code></pre>
<h2 id="alternative-pagefind">Alternative : Pagefind</h2>
<p><a href="https://pagefind.app" target="_blank" rel="noopener noreferrer">Pagefind</a> indexe directement les fichiers HTML générés : aucun template JSON n’est nécessaire. Lancez-le après le build, sur le répertoire de sortie (<code translate="no">_site</code> par défaut) :</p>
<pre><code class="language-bash hljs bash" translate="no">php cecil.phar build
npx pagefind --site _site</code></pre>
<p>Chargez ensuite son interface dans un template :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/pagefind/pagefind-ui.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/pagefind/pagefind-ui.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"search"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
  <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">'DOMContentLoaded'</span>, () =&gt; <span class="hljs-keyword">new</span> PagefindUI({ <span class="hljs-attr">element</span>: <span class="hljs-string">'#search'</span> }));
</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span></span></code></pre>
<aside class="note note-tip"><p>L’index est une page comme les autres : pour ne régénérer que les sorties JSON, déclarez un <a href="/documentation/configuration/#pages-subsets">sous-ensemble</a> et lancez <code translate="no">php cecil.phar build --render-subset=&lt;name&gt;</code>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/deploiement-github-pages/</id>
    <title>Déployer sur GitHub Pages avec GitHub Actions</title>
    <published>2026-10-07T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/deploiement-github-pages/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Avec la <a href="https://github.com/Cecilapp/Cecil-Action" target="_blank" rel="noopener noreferrer">Cecil Action</a>, chaque push sur votre dépôt génère le site et le publie sur <strong>GitHub Pages</strong>, sans serveur à gérer.</p>
<h2 id="activer-github-pages">Activer GitHub Pages</h2>
<p>Dans votre dépôt, allez dans <strong>Settings</strong> → <strong>Pages</strong> puis, dans <strong>Build and deployment</strong>, choisissez <strong>GitHub Actions</strong> comme <strong>Source</strong>.</p>
<h2 id="ajouter-le-workflow">Ajouter le workflow</h2>
<p>Créez le fichier <code translate="no">.github/workflows/build-and-deploy.yml</code> :</p>
<pre><code class="language-yaml 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>
<span class="hljs-attr">on:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span> <span class="hljs-string">[master,</span> <span class="hljs-string">main]</span>
  <span class="hljs-attr">workflow_dispatch:</span>
<span class="hljs-attr">concurrency:</span>
  <span class="hljs-attr">group:</span> <span class="hljs-string">pages</span>
  <span class="hljs-attr">cancel-in-progress:</span> <span class="hljs-literal">true</span>
<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">build:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">source</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v6</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">site</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">Cecilapp/Cecil-Action@v4</span>
  <span class="hljs-attr">deploy:</span>
    <span class="hljs-attr">needs:</span> <span class="hljs-string">build</span>
    <span class="hljs-attr">permissions:</span>
      <span class="hljs-attr">pages:</span> <span class="hljs-string">write</span>
      <span class="hljs-attr">id-token:</span> <span class="hljs-string">write</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">github-pages</span>
      <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>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">steps:</span>
      <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>
        <span class="hljs-attr">id:</span> <span class="hljs-string">deployment</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/deploy-pages@v5</span></code></pre>
<p>Le job <code translate="no">build</code> télécharge Cecil, installe les thèmes (si un fichier <code translate="no">composer.json</code> existe), génère le site et envoie le répertoire de sortie en tant qu’artefact Pages. Le job <code translate="no">deploy</code> le publie ensuite.</p>
<h2 id="url-de-base">URL de base</h2>
<p>Inutile de modifier <code translate="no">baseurl</code> dans <code translate="no">cecil.yml</code> : l’action génère le site avec l’URL fournie par GitHub Pages (par exemple <code translate="no">https://&lt;user&gt;.github.io/&lt;repository&gt;/</code>), via l’option <code translate="no">--baseurl</code>.</p>
<h2 id="personnaliser-la-generation">Personnaliser la génération</h2>
<p>L’action accepte les paramètres optionnels suivants :</p>
<pre><code class="language-yaml hljs yaml" translate="no">      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">site</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">Cecilapp/Cecil-Action@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">version:</span> <span class="hljs-string">'9.6.2'</span>       <span class="hljs-comment"># version de Cecil (la dernière par défaut)</span>
          <span class="hljs-attr">install_themes:</span> <span class="hljs-string">'no'</span>   <span class="hljs-comment"># ne pas installer les thèmes (`yes` par défaut)</span>
          <span class="hljs-attr">options:</span> <span class="hljs-string">'-v --drafts'</span> <span class="hljs-comment"># options de la commande build (`-v` par défaut)</span></code></pre>
<aside class="note note-tip"><p>Pour accélérer la génération, vous pouvez aussi restaurer et sauvegarder le répertoire <code translate="no">.cache</code> entre deux exécutions : consultez le workflow complet dans la <a href="/documentation/deploy/#github-pages">documentation du déploiement sur GitHub Pages</a>, ainsi que la liste des <a href="/documentation/commands/#build">options de build</a>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/sortie-flux-rss-json/</id>
    <title>Publier un flux RSS ou JSON</title>
    <published>2026-10-06T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/sortie-flux-rss-json/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Cecil génère les flux grâce aux <strong>formats de sortie</strong> : par défaut, la page d’accueil, les sections et les termes de taxonomie sont déjà publiés en HTML <strong>et en Atom</strong> (ex. <code translate="no">/atom.xml</code>, <code translate="no">/blog/atom.xml</code>). Ajoutez les formats <code translate="no">rss</code> ou <code translate="no">jsonfeed</code> pour publier aussi des fichiers RSS 2.0 ou <a href="https://www.jsonfeed.org" target="_blank" rel="noopener noreferrer">JSON Feed</a>.</p>
<h2 id="activer-les-flux-pour-toutes-les-pages-de-liste">Activer les flux pour toutes les pages de liste</h2>
<p>Définissez les formats appliqués à chaque type de page avec <code translate="no">output.pagetypeformats</code> :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">output:</span>
  <span class="hljs-attr">pagetypeformats:</span>
    <span class="hljs-attr">homepage:</span> <span class="hljs-string">[html,</span> <span class="hljs-string">atom,</span> <span class="hljs-string">rss,</span> <span class="hljs-string">jsonfeed]</span>
    <span class="hljs-attr">section:</span> <span class="hljs-string">[html,</span> <span class="hljs-string">atom,</span> <span class="hljs-string">rss,</span> <span class="hljs-string">jsonfeed]</span></code></pre>
<p>Cecil génère alors <code translate="no">rss.xml</code> et <code translate="no">feed.json</code> à côté de chaque <code translate="no">index.html</code> de la page d’accueil et des sections (ex. <code translate="no">/blog/rss.xml</code>, <code translate="no">/blog/feed.json</code>).</p>
<aside class="note note-info"><p>Les formats sont remplacés, pas fusionnés : conservez <code translate="no">html</code> dans la liste. Voir <a href="/documentation/configuration/#output-pagetypeformats"><code translate="no">output.pagetypeformats</code></a> et la liste des <a href="/documentation/configuration/#output-formats">formats par défaut</a>.</p></aside>
<h2 id="activer-un-flux-pour-une-seule-section">Activer un flux pour une seule section</h2>
<p>Pour publier un flux pour une seule section, utilisez la variable <a href="/documentation/content/#output"><code translate="no">output</code></a> dans le front matter de la page d’index de la section :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">Blog</span>
<span class="hljs-attr">output:</span> <span class="hljs-string">[html,</span> <span class="hljs-string">rss]</span>
<span class="hljs-meta">---</span></code></pre>
<h2 id="signaler-le-flux">Signaler le flux</h2>
<p>Si vos templates incluent le <a href="/documentation/configuration/#metatags">partial metatags</a>, les balises <code translate="no">&lt;link rel="alternate"&gt;</code> pointant vers les flux de la page courante sont ajoutées automatiquement dans le <code translate="no">&lt;head&gt;</code>.</p>
<p>Sinon, ajoutez le lien vous-même avec la fonction <code translate="no">url()</code> et son option <code translate="no">format</code> :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"alternate"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"application/rss+xml"</span> <span class="hljs-attr">title</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ site.title }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ url(page, {canonical: true, format: 'rss'}) }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span></span></code></pre>
<h2 id="personnaliser-le-template-du-flux">Personnaliser le template du flux</h2>
<p>Les flux sont générés par les <a href="/documentation/templates/#built-in-templates">templates intégrés</a> <code translate="no">_default/list.rss.twig</code>, <code translate="no">_default/list.atom.twig</code> et <code translate="no">_default/list.jsonfeed.twig</code>. Selon les <a href="/documentation/templates/#lookup-rules">règles de recherche</a>, créez <code translate="no">layouts/list.rss.twig</code> (toutes les pages de liste) ou <code translate="no">layouts/blog/list.rss.twig</code> (section <code translate="no">blog</code> uniquement) pour les surcharger.</p>
<p>Vous pouvez étendre le template intégré et redéfinir uniquement le bloc <code translate="no">item</code>, par exemple pour publier un extrait plutôt que le contenu complet :</p>
<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> '_default/list.rss.twig' %}</span><span class="xml">

</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">block</span></span> item %}</span><span class="xml">
      <span class="hljs-tag">&lt;<span class="hljs-name">guid</span>&gt;</span></span><span class="hljs-template-variable">{{ url(item, {canonical: true}) }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">guid</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span></span><span class="hljs-template-variable">{{ item.title|e }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">pubDate</span>&gt;</span></span><span class="hljs-template-variable">{{ item.<span class="hljs-name">date</span>|<span class="hljs-keyword">date</span>('r') }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">pubDate</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">link</span>&gt;</span></span><span class="hljs-template-variable">{{ url(item, {canonical: true}) }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">link</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">description</span>&gt;</span>&lt;![CDATA[</span><span class="hljs-template-variable">{{ item.content|excerpt_html }}</span><span class="xml">]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">description</span>&gt;</span>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endblock</span></span> %}</span></code></pre>
<aside class="note note-tip"><p>Définissez <a href="/documentation/configuration/#baseurl"><code translate="no">baseurl</code></a> dans <code translate="no">cecil.yml</code> : les flux utilisent des URL absolues.</p>
<p>Le flux RSS peut aussi être mis en forme dans les navigateurs en activant la <a href="/documentation/configuration/#pages-default">page par défaut</a> <code translate="no">xsl/rss</code> :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">pages:</span>
  <span class="hljs-attr">default:</span>
    <span class="hljs-attr">xsl/rss:</span>
      <span class="hljs-attr">published:</span> <span class="hljs-literal">true</span></code></pre></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/templates-pagination/</id>
    <title>Paginer une liste de pages</title>
    <published>2026-10-05T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/templates-pagination/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Lorsqu’une section contient de nombreuses pages, Cecil peut découper sa liste en plusieurs pages (ex. : <code translate="no">/blog/</code>, <code translate="no">/blog/page/2/</code>, <code translate="no">/blog/page/3/</code>, etc.) et fournit un <em>paginator</em> pour construire les liens de navigation.</p>
<h2 id="configurer-la-pagination">Configurer la pagination</h2>
<p>La pagination est activée par défaut pour les pages de liste (<em>homepage</em>, <em>section</em> et <em>term</em>), avec 5 entrées par page. Modifiez-la dans <code translate="no">cecil.yml</code> :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">pages:</span>
  <span class="hljs-attr">pagination:</span>
    <span class="hljs-attr">max:</span> <span class="hljs-number">10</span>    <span class="hljs-comment"># nombre maximum d’entrées par page</span>
    <span class="hljs-attr">path:</span> <span class="hljs-string">page</span> <span class="hljs-comment"># chemin des pages paginées</span></code></pre>
<h2 id="la-surcharger-pour-une-section">La surcharger pour une section</h2>
<p>Définissez la variable <code translate="no">pagination</code> dans le front matter du fichier index de la section (ex. : <code translate="no">pages/blog/index.md</code>) :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">Blog</span>
<span class="hljs-attr">pagination:</span>
  <span class="hljs-attr">max:</span> <span class="hljs-number">20</span>
<span class="hljs-meta">---</span></code></pre>
<p>Ou désactivez-la pour cette section uniquement :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-meta">---</span>
<span class="hljs-attr">pagination:</span> <span class="hljs-literal">false</span>
<span class="hljs-meta">---</span></code></pre>
<h2 id="afficher-les-pages-paginees">Afficher les pages paginées</h2>
<p>Dans le template de liste (ex. : <code translate="no">layouts/blog/list.html.twig</code>), bouclez sur <code translate="no">page.paginator.pages</code> et utilisez <code translate="no">page.pages</code> lorsque la pagination est désactivée :</p>
<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> p in page.paginator.pages ?? page.pages %}</span><span class="xml">
  <span class="hljs-tag">&lt;<span class="hljs-name">article</span>&gt;</span>
    <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>
    <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">{{ p.<span class="hljs-name">date</span>|<span class="hljs-keyword">date</span>('c') }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span></span><span class="hljs-template-variable">{{ p.<span class="hljs-name">date</span>|<span class="hljs-keyword">date</span>('j M Y') }}</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">article</span>&gt;</span>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endfor</span></span> %}</span></code></pre>
<h2 id="ajouter-les-liens-de-navigation">Ajouter les liens de navigation</h2>
<p>Les liens du paginator sont des identifiants de pages : utilisez la fonction <code translate="no">url()</code> pour créer des liens fonctionnels :</p>
<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">
<span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
  </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">
  <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> <span class="hljs-attr">rel</span>=<span class="hljs-string">"prev"</span>&gt;</span>Previous<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
  </span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span><span class="xml">
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Page </span><span class="hljs-template-variable">{{ page.paginator.current }}</span><span class="xml"> of </span><span class="hljs-template-variable">{{ page.paginator.count }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  </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">
  <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> <span class="hljs-attr">rel</span>=<span class="hljs-string">"next"</span>&gt;</span>Next<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
  </span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span><span class="xml">
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span></code></pre>
<p>Pour lister tous les numéros de page, itérez de <code translate="no">1</code> à <code translate="no">page.paginator.count</code> :</p>
<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">
<span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
  </span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">for</span></span> i in 1..page.paginator.count %}</span><span class="xml">
    </span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">if</span></span> i == page.paginator.current %}</span><span class="xml">
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">aria-current</span>=<span class="hljs-string">"page"</span>&gt;</span></span><span class="hljs-template-variable">{{ i }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    </span><span class="hljs-template-tag">{% <span class="hljs-name">elseif</span> i == 1 %}</span><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.paginator.links.first) }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span></span><span class="hljs-template-variable">{{ i }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    </span><span class="hljs-template-tag">{% <span class="hljs-name">else</span> %}</span><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.paginator.links.path ~ '/' ~ i) }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span></span><span class="hljs-template-variable">{{ i }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
    </span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span><span class="xml">
  </span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endfor</span></span> %}</span><span class="xml">
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endif</span></span> %}</span></code></pre>
<aside class="note note-info"><p>Consultez la documentation de la <a href="/documentation/templates/#page">variable <code translate="no">page.paginator</code></a>, de la <a href="/documentation/configuration/#pages-pagination">configuration de la pagination</a> et de la <a href="/documentation/content/#section">variable <code translate="no">pagination</code> des sections</a>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/contenu-multilingue/</id>
    <title>Traduire un site en plusieurs langues</title>
    <published>2026-10-04T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/contenu-multilingue/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Cecil gère nativement les sites multilingues : il suffit de déclarer les langues, d’ajouter les pages traduites, puis de les relier entre elles et de traduire les templates.</p>
<h2 id="declarer-les-langues">Déclarer les langues</h2>
<p>Définissez la langue principale et la liste des langues disponibles dans <code translate="no">cecil.yml</code> :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">language:</span> <span class="hljs-string">en</span>
<span class="hljs-attr">languages:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">code:</span> <span class="hljs-string">en</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">English</span>
    <span class="hljs-attr">locale:</span> <span class="hljs-string">en_US</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">code:</span> <span class="hljs-string">fr</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">Français</span>
    <span class="hljs-attr">locale:</span> <span class="hljs-string">fr_FR</span>
    <span class="hljs-attr">config:</span>
      <span class="hljs-attr">title:</span> <span class="hljs-string">"Mon site en français"</span></code></pre>
<p>Les options placées sous la clé <code translate="no">config</code> d’une langue remplacent les options globales (ici le <code translate="no">title</code> du site).</p>
<h2 id="traduire-une-page">Traduire une page</h2>
<p>Dupliquez la page de référence et suffixez son nom de fichier avec le code de la langue :</p>
<pre><code class="language-plaintext hljs plaintext" translate="no">pages/
├─ about.md    # la page de référence
└─ about.fr.md # la version française</code></pre>
<p>Utilisez la variable <code translate="no">slug</code> pour traduire l’URL de la page :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-meta">---</span>
<span class="hljs-attr">title:</span> <span class="hljs-string">À</span> <span class="hljs-string">propos</span>
<span class="hljs-attr">slug:</span> <span class="hljs-string">a-propos</span>
<span class="hljs-meta">---</span></code></pre>
<p><code translate="no">about.md</code> est publiée sur <code translate="no">/about/</code> et <code translate="no">about.fr.md</code> sur <code translate="no">/fr/a-propos/</code>.</p>
<aside class="note note-tip"><p>Pour créer une page qui n’existe que dans une autre langue (sans être une traduction), définissez <code translate="no">language: fr</code> dans son front matter.</p></aside>
<h2 id="relier-les-pages-traduites">Relier les pages traduites</h2>
<p>Chaque page expose ses traductions via <code translate="no">page.translations</code>. Ajoutez un sélecteur de langue à votre template :</p>
<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> p in page.translations %}</span><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(p) }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span> <span class="hljs-attr">hreflang</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ p.language }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span></span><span class="hljs-template-variable">{{ site.language.name(p.language) }}</span><span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
</span><span class="hljs-template-tag">{% <span class="hljs-name"><span class="hljs-keyword">endfor</span></span> %}</span></code></pre>
<p>Vous pouvez aussi inclure le partial intégré : <code translate="no">{{ include('partials/languages.html.twig') }}</code>.</p>
<h2 id="traduire-les-textes-des-templates">Traduire les textes des templates</h2>
<p>Encadrez les textes avec le tag ou le filtre <code translate="no">trans</code> :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="hljs-template-tag">{% <span class="hljs-name">trans</span> %}</span><span class="xml">Read more</span><span class="hljs-template-tag">{% <span class="hljs-name">endtrans</span> %}</span><span class="xml">
</span><span class="hljs-template-variable">{{ 'Read more'|trans }}</span></code></pre>
<p>Ajoutez ensuite un fichier de traduction nommé d’après la locale de la langue dans le dossier <code translate="no">translations</code> :</p>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-comment"># translations/messages.fr_FR.yaml</span>
<span class="hljs-attr">Read more:</span> <span class="hljs-string">Lire</span> <span class="hljs-string">la</span> <span class="hljs-string">suite</span></code></pre>
<p>Extrayez les textes de vos templates avec :</p>
<pre><code class="language-bash hljs bash" translate="no">php cecil.phar util:translations:extract --locale=fr_FR --save</code></pre>
<aside class="note note-info"><p>Consultez la documentation du <a href="/documentation/content/#multilingual">contenu multilingue</a>, de la <a href="/documentation/configuration/#languages">configuration des langues</a> et de la <a href="/documentation/templates/#localization">localisation des templates</a>.</p></aside>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/templates-metatags/</id>
    <title>Appliquer les fonctionnalités SEO dans les templates</title>
    <published>2026-06-09T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/templates-metatags/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Cecil expose sa feature SEO via le template <code translate="no">partials/metatags.html.twig</code>. Il suffit de l’inclure dans le <code translate="no">&lt;head&gt;</code> du template de base pour que chaque page bénéficie automatiquement <strong>des balises meta, des liens canoniques, des cartes sociales et des données structurées</strong>.</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"</span></span></span><span class="hljs-template-variable">{{ site.language }}</span><span class="xml"><span class="hljs-tag"><span class="hljs-string">"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>&gt;</span>
    </span><span class="hljs-template-variable">{{ <span class="hljs-name">include</span><span class="hljs-params">('partials/metatags.html.twig')</span> }}</span><span class="xml">
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    ...
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></span></code></pre>
<p>Le partial lit d’abord le front matter de la page, puis reprend les options du site si nécessaire. Consultez la <a href="/documentation/configuration/#metatags">documentation de configuration des metatags</a> pour voir toutes les options disponibles.</p>
<p>Si vous devez surcharger le titre ou l’image, passez des valeurs directement au partial :</p>
<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>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/markdown-performance-images/</id>
    <title>Optimiser les images dans Markdown</title>
    <published>2025-07-25T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/markdown-performance-images/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>L'optimisation des images est l'un des moyens les plus efficaces d'améliorer les performances de votre site web.</p>
<p>Cecil gère automatiquement les optimisations suivantes pour les images Markdown :</p>
<ol>
<li><strong>Dimensions</strong> : Les dimensions des images sont définies pour garantir une mise en page correcte et éviter les décalages.</li>
<li><strong>Compression</strong> : L'image est compressée pour réduire la taille du fichier sans perte significative de qualité.</li>
<li><strong>Formats d'image</strong> : Cecil génère les formats AVIF et WebP pour l'image.</li>
<li><strong>Images responsives</strong> : Cecil génère deux tailles d'image différentes (selon la configuration) pour s'adapter à la taille des différents appareils.</li>
<li><strong>Chargement différé</strong> : L'image est configurée pour se charger de manière différée, c'est-à-dire uniquement lorsqu'elle apparaît dans la fenêtre d'affichage.</li>
<li><strong>Décodage</strong> : Le décodage de l'image est configuré pour être asynchrone, ce qui améliore le temps de chargement initial de la page.</li>
<li><strong>Espace réservé</strong> : Un espace réservé de couleur est utilisé pendant le chargement de l'image.</li>
</ol>
<aside class="note note-info"><p>Consultez la documentation pour plus de détails sur la <a href="/documentation/configuration/#assets-images">configuration des ressources globales</a> et la <a href="/documentation/configuration/#pages-body">configuration des pages</a>.</p></aside>
<h2 id="exemple">Exemple</h2>
<p>Ci-dessous un exemple avec une image PNG 1920x1276 pixels.</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="xml">![Une région de formation d’étoiles dans le ciel](../../assets/arnaud-girault-IjEtFjxXweE-unsplash.jpg "Photo de Arnaud Girault"){placeholder=color}</span></code></pre>
<figure>
<picture title="Photo de Arnaud Girault">
<source type="image/avif" srcset="/thumbnails/480x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.avif 480w, /thumbnails/768x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.avif 768w, /thumbnails/1024x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.avif 1024w" width="1024" height="681" sizes="100vw">
<source type="image/webp" srcset="/thumbnails/480x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.webp 480w, /thumbnails/768x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.webp 768w, /thumbnails/1024x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.webp 1024w" width="1024" height="681" sizes="100vw">
<img src="/thumbnails/1024x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.jpg" alt="Une région de formation d’étoiles dans le ciel" loading="lazy" decoding="async" class="dark:brightness-90" width="1024" height="681" style=";max-width:100%;height:auto;background-color:rgb(20 28 29);" srcset="/thumbnails/480x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.jpg 480w, /thumbnails/768x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.jpg 768w, /thumbnails/1024x/images/examples/arnaud-girault-IjEtFjxXweE-unsplash.9f9b5448197aded5325854d4f3c79652.jpg 1024w" sizes="100vw">
</picture>
<figcaption>Photo de <a href="https://unsplash.com/fr/photos/une-region-de-formation-detoiles-dans-le-ciel-IjEtFjxXweE" target="_blank" rel="noopener noreferrer">Arnaud Girault</a></figcaption>
</figure>
<h3 id="configuration">Configuration</h3>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-comment"># configuration globale des assets</span>
<span class="hljs-attr">assets:</span>
  <span class="hljs-attr">images:</span>
    <span class="hljs-attr">optimize:</span> <span class="hljs-literal">true</span>
    <span class="hljs-attr">responsive:</span>
      <span class="hljs-attr">widths:</span> <span class="hljs-string">[768,</span> <span class="hljs-number">1024</span><span class="hljs-string">]</span>
<span class="hljs-comment"># configuration des images dans du Markdown</span>
<span class="hljs-attr">pages:</span>
  <span class="hljs-attr">body:</span>
    <span class="hljs-attr">images:</span>
      <span class="hljs-attr">formats:</span> <span class="hljs-string">[avif,</span> <span class="hljs-string">webp]</span>
      <span class="hljs-attr">responsive:</span> <span class="hljs-literal">true</span>
      <span class="hljs-attr">lazy:</span> <span class="hljs-literal">true</span>
      <span class="hljs-attr">decoding:</span> <span class="hljs-literal">true</span>
      <span class="hljs-attr">placeholder:</span> <span class="hljs-string">color</span></code></pre>
<h3 id="html-genere">HTML généré</h3>
<pre><code class="language-html hljs xml" translate="no"><span class="hljs-tag">&lt;<span class="hljs-name">picture</span>&gt;</span>
  <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">"/thumbnails/1024/arnaud-girault-IjEtFjxXweE-unsplash.c0bdd31264ac3d0d364d02bced31038f.avif 1024w,
            /thumbnails/768/arnaud-girault-IjEtFjxXweE-unsplash.c0bdd31264ac3d0d364d02bced31038f.avif 768w"</span>
    <span class="hljs-attr">sizes</span>=<span class="hljs-string">"100vw"</span>
    <span class="hljs-attr">width</span>=<span class="hljs-string">"1024"</span>
    <span class="hljs-attr">height</span>=<span class="hljs-string">"681"</span>
  &gt;</span>
  <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">"/thumbnails/1024/arnaud-girault-IjEtFjxXweE-unsplash.c0bdd31264ac3d0d364d02bced31038f.webp 1024w,
            /thumbnails/768/arnaud-girault-IjEtFjxXweE-unsplash.c0bdd31264ac3d0d364d02bced31038f.webp 768w"</span>
    <span class="hljs-attr">sizes</span>=<span class="hljs-string">"100vw"</span>
    <span class="hljs-attr">width</span>=<span class="hljs-string">"1024"</span>
    <span class="hljs-attr">height</span>=<span class="hljs-string">"681"</span>
  &gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/thumbnails/1024/arnaud-girault-IjEtFjxXweE-unsplash.c0bdd31264ac3d0d364d02bced31038f.jpg"</span>
    <span class="hljs-attr">alt</span>=<span class="hljs-string">"Photo de Arnaud Girault"</span>
    <span class="hljs-attr">loading</span>=<span class="hljs-string">"lazy"</span>
    <span class="hljs-attr">decoding</span>=<span class="hljs-string">"async"</span>
    <span class="hljs-attr">width</span>=<span class="hljs-string">"1024"</span>
    <span class="hljs-attr">height</span>=<span class="hljs-string">"681"</span>
    <span class="hljs-attr">style</span>=<span class="hljs-string">";max-width:100%;height:auto;background-color:rgb(58, 56, 44);"</span>
    <span class="hljs-attr">srcset</span>=<span class="hljs-string">"/thumbnails/1024/arnaud-girault-IjEtFjxXweE-unsplash.c0bdd31264ac3d0d364d02bced31038f.jpg 1024w,
            /thumbnails/768/arnaud-girault-IjEtFjxXweE-unsplash.c0bdd31264ac3d0d364d02bced31038f.jpg 768w"</span>
    <span class="hljs-attr">sizes</span>=<span class="hljs-string">"100vw"</span>
  &gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">picture</span>&gt;</span></code></pre>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/templates-image-formats/</id>
    <title>Générer plusieurs formats d&#039;images dans des modèles</title>
    <published>2025-07-25T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/templates-image-formats/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Pour optimiser les performances et la bande passante, Cecil peut générer plusieurs formats d'image, tels qu'AVIF et WebP. Cela permet au navigateur de sélectionner le format le plus adapté à ses capacités :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="hljs-template-variable">{{ html(asset('image.jpg'), attributes={alt: 'Description alternative'}, options={formats: ['avif', 'webp']}) }}</span></code></pre>
<blockquote>
<p>AVIF et WebP sont des formats d'image offrant des caractéristiques de compression et de qualité supérieures à leurs homologues JPEG et PNG plus anciens. Encoder vos images dans ces formats plutôt que JPEG ou PNG permet un chargement plus rapide et une consommation de données mobiles réduite.</p>
<p>AVIF est pris en charge par Chrome, Firefox et Opera et offre des tailles de fichier plus petites que d'autres formats à qualité égale.</p>
<p>WebP est pris en charge par les dernières versions de Chrome, Firefox, Safari, Edge et Opera et offre une meilleure compression avec et sans perte pour les images sur le Web.</p>
</blockquote>
<p>– <a href="https://developer.chrome.com/docs/lighthouse/performance/uses-webp-images?hl=fr" target="_blank" rel="noopener noreferrer">Documentation Chrome Lighthouse</a></p>
<h2 id="exemple">Exemple</h2>
<p>Ci-dessous un exemple de génération des formats AVIF et WebP d'une image :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="hljs-template-variable">{{ html(asset('cecil-logo.png'), attributes={alt: 'Cecil logo'}, options={formats: ['avif', 'webp']}) }}</span></code></pre>
<h3 id="html-genere">HTML généré</h3>
<pre><code class="language-html hljs xml" translate="no"><span class="hljs-tag">&lt;<span class="hljs-name">picture</span>&gt;</span>
  <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">"/cecil-logo.c1af8a129a0cde81f9b94ffbf452e10b.avif"</span>&gt;</span>
  <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">"/cecil-logo.c1af8a129a0cde81f9b94ffbf452e10b.webp"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"/cecil-logo.c1af8a129a0cde81f9b94ffbf452e10b.png"</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"250"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"250"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"Cecil logo"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">picture</span>&gt;</span></code></pre>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://cecil-945.pages.dev/fr/comment-faire/templates-responsive-images/</id>
    <title>Rendre des images réactives dans des modèles</title>
    <published>2025-07-25T00:00:00+00:00</published>
    <link href="https://cecil-945.pages.dev/fr/comment-faire/templates-responsive-images/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>La manière la plus simple de rendre des <a href="https://developer.mozilla.org/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images" target="_blank" rel="noopener noreferrer">images réactives</a> dans des modèles est d'utiliser la <a href="/documentation/templates/#html">fonction html</a> :</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="hljs-template-variable">{{ html(asset('image.jpg'), attributes={alt: 'Description alternative'}, options={responsive: true}) }}</span></code></pre>
<aside class="note note-important"><p>Les valeurs de largeur par défaut des images générées sont 480, 640, 768, 1024, 1366, 1600 et 1920. Elles peuvent être modifiées dans la section <em>assets</em> de la <a href="/documentation/configuration/#assets-images">configuration</a>.</p></aside>
<h2 id="exemple">Exemple</h2>
<p>Ci-dessous un exemple avec une image PNG 1000x1000 pixels.</p>
<pre><code class="language-twig hljs twig" translate="no"><span class="hljs-template-variable">{{ html(asset('cecil-logo-1000.png'), attributes={alt: 'Cecil logo'}, options={responsive: true}) }}</span></code></pre>
<h3 id="configuration">Configuration</h3>
<pre><code class="language-yaml hljs yaml" translate="no"><span class="hljs-attr">assets:</span>
  <span class="hljs-attr">images:</span>
    <span class="hljs-attr">responsive:</span>
      <span class="hljs-attr">widths:</span> <span class="hljs-string">[768,</span> <span class="hljs-number">1024</span><span class="hljs-string">]</span></code></pre>
<h3 id="html-genere">HTML généré</h3>
<pre><code class="language-html hljs xml" translate="no"><span class="hljs-tag">&lt;<span class="hljs-name">img</span>
  <span class="hljs-attr">alt</span>=<span class="hljs-string">"Cecil logo"</span>
  <span class="hljs-attr">width</span>=<span class="hljs-string">"1000"</span>
  <span class="hljs-attr">height</span>=<span class="hljs-string">"1000"</span>
  <span class="hljs-attr">src</span>=<span class="hljs-string">"/cecil-logo-1000.fbacb922cddbcdb7ca9a03a3ca3cf2ca.png"</span>
  <span class="hljs-attr">srcset</span>=<span class="hljs-string">"/thumbnails/768/cecil-logo-1000.fbacb922cddbcdb7ca9a03a3ca3cf2ca.png 768w,
          /cecil-logo-1000.fbacb922cddbcdb7ca9a03a3ca3cf2ca.png 1000w"</span>
  <span class="hljs-attr">sizes</span>=<span class="hljs-string">"100vw"</span>
&gt;</span></code></pre>]]>
    </content>
  </entry>
</feed>
