Templates
Registre serveur des templates de rendu public, mise en page qui enveloppe un contenu CMS.
Un template enveloppe le rendu public d'un contenu CMS : page, post. Il porte l'en-tête, la mise en page et le branding du site. Il est résolu au moment du rendu RSC à partir du couple (kind, id).
core/templates ne fait que stocker et retrouver ces templates. Le rendu des blocs est fait par le template lui-même, via blocks-registry.
Import
import { registerTemplate, getTemplate, listTemplates } from '@lrvo/core/templates';Registre purement serveur. Voir les notes pour la raison : ce n'est pas un oubli.
Qui alimente le registre
- Le projet hôte dépose un fichier dans
components/lrvo/templates/<id>.jsexportantmetaet un composant par défaut. Le CLIlrvo-modules syncgénère le manifesteapp/.lrvo/templates.server.jsqui appelleregisterTemplateau boot. C'est de là que vient le templatedefaultde@lrvo/module-pages, qui n'en enregistre aucun lui-même.@lrvo/module-postsen enregistre un par type déclaré, que le projet peut écraser en reprenant le même identifiant. - Un module peut enregistrer un template à l'exécution via l'API impérative, quand l'identifiant dépend d'une condition inconnue au build.
API
registerTemplate({ id, label, kind, postType, Component })
| Champ | Type | Obligatoire | Rôle |
|---|---|---|---|
id | string | oui | Identifiant du template, unique par kind (et postType). |
label | string | non | Libellé affiché dans l'admin. Défaut : id. |
kind | 'page' | 'post' | oui | Nature du contenu enveloppé. |
postType | string | si kind === 'post' | Type de post concerné, par exemple blogue. |
Component | Function | oui | Composant React serveur. |
Chaque champ est validé : un kind invalide, un postType manquant sur un template de post ou un Component non-fonction lèvent immédiatement, au boot plutôt qu'au premier rendu.
import { registerTemplate } from '@lrvo/core/templates';
registerTemplate({
id: 'default',
label: 'Par défaut',
kind: 'page',
Component: ({ page, blocks }) => (
<article>
<h1>{page.title}</h1>
<Content blocks={blocks} />
</article>
),
});Props reçues par le composant
Le registre est agnostique : ce sont les modules qui décident des props passées à leur template.
kind | Props |
|---|---|
'page' | { page, blocks, url, breadcrumb }. Voir Templates de page. |
'post' | { post, blocks, url, breadcrumb }. Voir Templates de post. |
Le template est responsable du rendu des blocs. Il importe son propre <Content> depuis components/lrvo/templates/content.js et l'utilise avec <Content blocks={blocks} />. Aucun children n'est injecté implicitement : le template a la main complète sur sa JSX.
getTemplate({ kind, id, postType })
Retourne l'entrée enregistrée, ou null. Retourne null aussi quand kind ou id manque, ce qui évite de résoudre par accident un template arbitraire.
listTemplates({ kind, postType })
Retourne les métadonnées seules, sans le Component : { id, label, kind, postType }. C'est ce qu'on envoie à un <Select> côté client.
const options = listTemplates({ kind: 'post', postType: 'blogue' });Notes
Pourquoi il n'existe pas de manifeste client équivalent. Générer un manifeste 'use client' pour les templates tirerait les fichiers de components/lrvo/templates/ dans le graphe client. Le composant compilé côté client écraserait alors l'entrée RSC dans la même Map de globalThis : deux enregistrements, même clé, dernier arrivé gagnant. Le rendu RSC recevrait un composant client, et next/link comme next/image casseraient.
Conséquence pratique : le formulaire d'admin ne lit pas ce registre depuis le navigateur. Il liste les templates via des routes REST (listPostTemplates / listPageTemplates exposées dans les api.server.js des modules).
Stockage sur globalThis via Symbol.for pour survivre au hot-reload de Next.js. Voir Registres et singletons.