Référence des hooks

C'est la liste complète de chaque filtre et action que le cœur déclenche. Pour des conseils pratiques sur comment s'abonner, voir Créer des plugins → Hooks.

C'est la liste complète de chaque filtre et action que le cœur déclenche. Pour des conseils pratiques sur comment s'abonner, voir Créer des plugins → Hooks.

Hooks de filtre

Les filtres mutent des valeurs. Chaque handler reçoit la valeur courante, retourne une nouvelle valeur (ou inchangée). Composés dans l'ordre des priorités (priorité plus basse en premier ; défaut 10).

post.markdown.before

Type : filtre (async) Reçoit : (markdown: string, post: Post) => string Déclenché par : publisher.publishPost, publisher.regenerateAllPagesAndPosts Objet : muter le markdown brut avant sa conversion en HTML.

TS
api.addFilter<string>("post.markdown.before", (md, post) => {
  return md.replace(/{{\s*author\s*}}/g, post.authorId);
});

À utiliser pour des remplacements façon shortcode qui opèrent sur le markdown source. La plupart des plugins préfèrent post.html.body car il opère sur le HTML rendu (après sanitisation).

post.html.body

Type : filtre (async) Reçoit : (html: string, post: Post, ctx: PublishContext) => string Déclenché par : publisher.publishPost, publisher.regenerateAllPagesAndPosts Objet : muter le corps HTML rendu après la conversion markdown + DOMPurify.

Le filtre le plus utilisé par les plugins / thèmes. Utilisé par : blocs de thème (default, magazine, corporate), blocs de plugin (colonnes / html du flexweg-blocks), plugins d'embed (flexweg-embeds).

post.template.props

Type : filtre (async) Reçoit : (props: SingleTemplateProps, post: Post, ctx: PublishContext) => SingleTemplateProps Déclenché par : publisher.publishPost Objet : muter les props passées au SingleTemplate du thème actif avant le rendu.

Utile pour enrichir le template avec des données calculées (posts liés, recommandations, CTAs personnalisés).

page.head.extra

Type : filtre (sync — déclenché via applyFiltersSync) Reçoit : (current: string, baseProps: BaseLayoutProps) => string Déclenché par : core/render.tsx.renderPageToHtml (chaque page) Objet : injecter du markup dans <head>, en remplaçant le sentinel <meta name="x-cms-head-extra" />.

Synchrone — les handlers async ne fonctionnent pas. Utilisé par : core-seo (Twitter Card), flexweg-favicon (favicon link cluster), flexweg-custom-code (head injection user-supplied), flexweg-blocks (CSS de baseline colonnes, conditionnel), flexweg-embeds (CSS de baseline embed, conditionnel).

page.body.end

Type : filtre (sync) Reçoit : (current: string, baseProps: BaseLayoutProps) => string Déclenché par : core/render.tsx.renderPageToHtml Objet : injecter du markup juste avant </body>, en remplaçant le sentinel <script type="application/x-cms-body-end" />.

Utilisé par : flexweg-custom-code (body-end injection user-supplied), flexweg-search (script runtime de recherche), flexweg-embeds (scripts détectés par provider par page).

menu.json.resolved

Type : filtre (async) Reçoit : (menu: MenuJson, ctx: MenuFilterContext) => MenuJson Déclenché par : services/menuPublisher.ts.publishMenuJson Objet : muter la structure du menu résolu avant son upload comme /menu.json.

MenuFilterContext = { settings, posts, pages, terms }. Utilisé par flexweg-rss (entrées de footer pour les feeds activés).

publish.additional

Type : filtre (async) Reçoit : (existing: AdditionalRender[], post: Post, ctx: PublishContext) => AdditionalRender[] Déclenché par : publisher.publishPost, publisher.regenerateAllPagesAndPosts Objet : laisser un plugin retourner plus d'enregistrements { path, html } à uploader aux côtés du fichier principal (typiquement des variantes par langue).

TS
api.addFilter("publish.additional", async (extras, post, ctx) => {
  const variants = await renderLocalized(post, ctx);
  return [...extras, ...variants];
});

Le cleanup des orphelins est automatique : le publisher diff les chemins retournés contre Post.lastPublishedPathsByLocale et supprime ceux qui ont disparu. Le plugin est responsable d'écrire lastPublishedPathsByLocale via updatePost(...) après chaque sauvegarde. Utilisé par flexweg-multilang.

publish.extraListings

Type : filtre (async) Reçoit : (existing: AdditionalListingRender[], ctx: PublishContext) => AdditionalListingRender[] Déclenché par : publisher.regenerateListings, regenerateHomeOnly, regenerateAll Objet : retourner des fichiers de listings supplémentaires (homes par langue, archives de catégories par langue) à uploader. Pas de bookkeeping de chemin — ceux-là sont régénérés en gros à chaque fois. Utilisé par flexweg-multilang.

rss.site.locales

Type : filtre (async) Reçoit : (existing: RssLocaleEntry[], { posts, terms, mediaMap, settings, config, baseUrl, xslHref }) => RssLocaleEntry[] Déclenché par : flexweg-rss/generator.ts.regenerateSiteFeed (uniquement quand config.site.enabled === true) Objet : retourner des feeds RSS de site par langue (ex. <lang>/rss.xml pour chaque langue non-primaire). flexweg-rss gère la sérialisation XML + upload + cleanup d'orphelins via config.site.lastLocalePaths.

TS
// RssLocaleEntry = {
//   language: string;
//   path: string;
//   channelTitle: string;
//   channelLink: string;
//   channelDescription: string;
//   items: RssItem[];
// }

Utilisé par flexweg-multilang.

sitemap.urlset.namespaces

Type : filtre (sync) Reçoit : (namespaces: string[], { settings }) => string[] Déclenché par : flexweg-sitemaps/generator.ts.buildYearSitemap Objet : ajouter des déclarations de namespace XML à chaque root <urlset>. Utilisé par flexweg-multilang pour ajouter le namespace xhtml pour les entrées hreflang.

sitemap.url.entry

Type : filtre (sync) Reçoit : (xml: string, { entry, settings, config }) => string Déclenché par : flexweg-sitemaps/generator.ts.buildYearSitemap (par entrée) Objet : muter le bloc <url> d'une entrée. Utilisé par flexweg-multilang pour injecter les <xhtml:link rel="alternate" hreflang="…"> pour chaque variante de langue disponible.

sitemap.urls.extra

Type : filtre (async) Reçoit : (existing: SitemapEntity[], { posts, pages, terms, settings, config, year }) => SitemapEntity[] Déclenché par : flexweg-sitemaps/generator.ts.regenerateSitemaps Objet : ajouter des entrées d'URL supplémentaires à l'urlset d'une année (ex. URLs de post localisées par langue). Utilisé par flexweg-multilang.

sitemap.index.extra

Type : filtre (async) Reçoit : (existing: SitemapIndexEntry[], { settings, config }) => SitemapIndexEntry[] Déclenché par : flexweg-sitemaps/generator.ts.regenerateSitemaps (après calcul des sitemaps annuels + de l'index) Objet : ajouter des références <sitemap> à l'index — utilisé par flexweg-multilang pour ajouter les références sitemap-news-<lang>.xml par langue, gated sur settings.pluginConfigs["flexweg-sitemaps"]?.newsEnabled === true.

sitemap.news.locales

Type : filtre (async) Reçoit : (existing: NewsLocaleEntry[], { posts, pages, terms, settings, config }) => NewsLocaleEntry[] Déclenché par : flexweg-sitemaps/generator.ts.regenerateSitemaps (uniquement quand News est activé) Objet : retourner des fichiers de sitemap News par langue à écrire. flexweg-sitemaps construit le XML + upload chacun. Couplé avec sitemap.index.extra pour que les refs par langue dans l'index restent synchronisées avec les fichiers réels sur disque. Utilisé par flexweg-multilang.

Hooks d'action

Les actions sont des effets de bord. Chaque handler tourne ; rien n'est retourné ; un handler ne peut pas court-circuiter un autre. Les erreurs dans un handler sont loggées et avalées — elles n'empêchent pas les autres de tourner.

publish.before

Type : action (async) Reçoit : (post: Post) => void Déclenché par : publisher.publishPost Objet : réagir juste avant qu'une publication commence. Usage limité — typiquement on veut publish.complete pour réagir à une publication réussie, pas publish.before.

publish.after

Type : action (async) Reçoit : (post: Post, ctx: PublishContext) => void Déclenché par : publisher.publishPost Objet : se déclenche après l'upload du HTML du post mais avant les cascades de régénération. Largement identique à publish.complete — la plupart des plugins utilisent ce dernier.

publish.complete

Type : action (async) Reçoit : (post: Post, ctx: PublishContext) => void Déclenché par : publisher.publishPost Objet : se déclenche à la toute fin d'une publication réussie, après les cascades.

ctx est déjà patché avec l'état post-publication — ctx.posts reflète le nouvel état du post. Utilisé par : flexweg-sitemaps, flexweg-rss, flexweg-archives, flexweg-search.

post.unpublished

Type : action (async) Reçoit : (post: Post, ctx: PublishContext) => void Déclenché par : publisher.unpublishPost, publisher.deletePostAndUnpublish (quand le post était en ligne) Objet : réagir à un post mis hors ligne. ctx.posts reflète déjà le post hors ligne. Utilisé par tous les quatre plugins générateurs de fichiers.

post.deleted

Type : action (async) Reçoit : (post: Post, ctx: PublishContext) => void Déclenché par : publisher.deletePostAndUnpublish Objet : réagir à un post définitivement supprimé. Se déclenche APRÈS post.unpublished si le post était en ligne avant suppression. Utilisé par tous les quatre plugins générateurs de fichiers.

regenerate.listings.before

Type : action (async) Reçoit : (ctx: PublishContext) => void Déclenché par : publisher.regenerateListings Objet : réagir juste avant un pass de régénération des listings (home + archives de catégorie). Laisse les plugins rafraîchir les caches par langue que le pass de publication va lire.

Registries d'extensibilité éditeur (API ≥ 1.2)

Au-delà des filtres et actions, les plugins peuvent étendre l'UI éditeur via des registries dédiés. Chaque appel dans register(api) ajoute une entrée ; applyPluginRegistration() les reset entre les changements de plugin de la même façon qu'il reset filtres / actions.

pluginApi.registerInspectorTab(manifest)

Ajoute un onglet supplémentaire dans le panneau Inspecteur droit de l'éditeur de post / page (à côté de Document et Bloc). Le composant reçoit { entity, updateEntity, save }.

pluginApi.registerTermEditorSection(manifest)

Ajoute une section pliable à chaque ligne de la page Catégories / Tags. Le composant reçoit { term, updateTerm }. Utilisé par flexweg-multilang pour les traductions de termes par langue.

pluginApi.registerEditorVariantProvider(manifest) (API ≥ 1.3)

Rend une bande d'onglets au-dessus de l'éditeur qui swap l'état complet de l'éditeur (titre, slug, WYSIWYG, extrait, SEO) par variante, en préservant la même instance Tiptap pour que les blocs + drag-and-drop restent vivants. Utilisé par flexweg-multilang pour l'édition par langue.

pluginApi.registerRegenerationTarget(manifest)

Ajoute une entrée au menu déroulant Thèmes ▸ Regenerate ▾. Chaque cible exécute un callback async run(ctx, log). Utilisé par flexweg-sitemaps, flexweg-rss, flexweg-archives, flexweg-search pour l'UX Force-regenerate par plugin.

pluginApi.registerDashboardCard(manifest)

Ajoute une carte self-contained au tableau de bord admin (sous les quatre cartes stat intégrées). Le composant ne prend aucune prop — fetche ses propres données. Utilisé par flexweg-metrics.

pluginApi.registerBlock(manifest)

Enregistre un bloc d'éditeur basé sur Tiptap, surfacé dans l'inserter /. Les blocs portent un inspecteur optionnel + un renderHtml côté serveur qu'ils exposent via le filtre post.html.body au moment de la publication.