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.
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).
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.
// 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.