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

  1. Le projet hôte dépose un fichier dans components/lrvo/templates/<id>.js exportant meta et un composant par défaut. Le CLI lrvo-modules sync génère le manifeste app/.lrvo/templates.server.js qui appelle registerTemplate au boot. C'est de là que vient le template default de @lrvo/module-pages, qui n'en enregistre aucun lui-même. @lrvo/module-posts en enregistre un par type déclaré, que le projet peut écraser en reprenant le même identifiant.
  2. 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 })

ChampTypeObligatoireRôle
idstringouiIdentifiant du template, unique par kind (et postType).
labelstringnonLibellé affiché dans l'admin. Défaut : id.
kind'page' | 'post'ouiNature du contenu enveloppé.
postTypestringsi kind === 'post'Type de post concerné, par exemple blogue.
ComponentFunctionouiComposant 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.

kindProps
'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.

Sur cette page