Engine-arkitektur
3. Engine-arkitektur
TesseraCMS har tre kode-lag: engine, sitetypes, modules. Forstå hvor hvert af jeres ændringer hører hjemme, så du ikke bygger noget der senere brydes af refactors.
Engine (src/engine/)
Universelle byggesten der ikke ved noget om specifikke sites. Lag-niveauer:
- Fields (
engine/fields/) — primitiverne (Text, RichText, Image, Url, Number, Boolean, Date, Money, …). Hver Field har et input-component i admin og en render-helper i public-rendering. - Blocks (
engine/blocks/) — komposable byggeklodser i rich content (Text, Image, Spacer, CTA, Columns, RollupBlock, FormBlock, …). Hver Block har config-fields + en Render-komponent. - Content-types (
engine/types/) — schemas for record-shapes (BaseContentItem, Image, Page, Rollup, Hero, Form, Brand, Snippet, …). Genbruges på tværs af sitetypes. - Rollup-layouts (
engine/rollup-layouts/) — visuelle templates for rollups (grid, list, masonry, …) - Modules (
engine/modules/) — modul-registry; selve modul-koden lever isrc/modules/ - Views (
engine/views/) — registry over hvordan content-types render'es på public-side - Site-layouts (
engine/site-layouts/) — registry over hvilke layout-packages der findes
Engine MÅ IKKE importere fra src/sitetypes/*. Pilen peger kun den ene vej.
Sitetypes (src/sitetypes/)
Kategorier af site med shared content-shapes. I dag:
- artist_portfolio — kunstner-portfolio (Frontpage, ContentPage, Artwork, Hero-block, AboutRollup-block, ContactSection-block)
- riding_club — rideklub-website (Pony, Tournament, Sponsor, News + relaterede blocks)
- docs — docs-style (genbruger Frontpage/ContentPage + DocsHero-block)
Hver sitetype:
- Registrerer sine egne content-types der
extends: "Page"eller andre engine-types - Registrerer site-specifikke blocks (Hero, AboutRollup, …)
- Registrerer sine rollup-layout-variants
- Har et bootstrap-callback der kører ved opstart
Når du tilføjer en ny site-type-feature, hold den scoped til sitetypen — engine kender ikke til kunsts dybdegående eller riding-clubs.
Modules (src/modules/)
Genbrugelige features uafhængigt af sitetype. Eksempler:
- pages — page-CRUD (alle sites bruger det)
- media — billede-upload + admin (alle sites bruger det)
- images — image-records (alle)
- branding — brand + snippet (alle)
- navigation — menus (alle)
- forms — formularer + submissions (alle)
- mail — mail-templates + ACS-send (alle)
- heroes — hero-records (alle som vil have heros)
- art — artwork + galleries (kun artist_portfolio)
- riding-club-admin — pony+tournament+sponsor admin-UI (kun riding_club)
- site-layouts/artsite-classic,
/riding-club-classic,/docs-classic— layout-pakker (én pr. site-look) - social — social-channel + featured-post (alle der vil have SoMe-integration)
- documents — PDF/DOCX-arkiv (alle)
Hvert modul har en manifest.ts der erklærer name, version, dependencies, admin-route, dashboardCategory. Manifester registreres i engine/bootstrap.ts.
Site-layouts (src/modules/site-layouts/)
Layout-packages er en speciel form for module — de definerer shell (header/footer/layout) plus slot-fillers (default brand, default footer-snippet) som tenant kan overskrive.
Hvert layout-package har:
manifest.tsx— registrerSiteLayoutManifestmed slots, defaults, Shell componentShell.tsx— komposite layout-shell (Navbar + children + Footer)Navbar.tsx,Footer.tsx— sub-komponenteri18n.ts— display-strings
Når en tenant har layoutPackage = "artsite-classic", render'er routen den pakke's Shell rundt om content.
Hvor tilføjer jeg X?
- Ny primitive field-type →
engine/fields/ - Ny generic block (genbruges af alle sites) →
engine/blocks/ - Ny site-type-specifik block (kun til kunstnere fx) →
sitetypes/<sitetype>/blocks/ - Ny generic content-type →
engine/types/ - Ny site-type-specifik type →
sitetypes/<sitetype>/types/ - Ny feature i admin-UI der virker for alle sites → nyt module under
src/modules/ - Ny visual look for sites → nyt site-layout under
src/modules/site-layouts/ - Helt ny kategori af site (fx restaurants) → nyt sitetype under
src/sitetypes/
Når i tvivl: start specifik (sitetype) og generaliser senere hvis et andet sitetype får brug for det.
Lag-grænse-håndhævelse
- Engine
src/engine/må ikke importere fra sitetypes - Sitetypes må importere fra engine (én vej)
- Moduler må importere fra engine
- Site-layouts må importere fra engine + moduler
- Hver sitetype er sealing —
artist_portfoliomå ikke importere frariding_club
Hvis du har brug for at krydse en grænse, er der typisk et missing engine-abstraktion. Lift det op, og brug det fra begge sider.
Theme preset system — nyt i 2026-06
Engine har nu en preset-baseret theme-arkitektur. Hver layout-modul registrerer en LayoutThemeBinding der mapper semantiske preset-vars til layoutens egen CSS-var-konvention. Editor vælger en af 5 presets per layout via /admin/theme.
import { registerLayoutThemeBinding } from "@/engine";
registerLayoutThemeBinding({
layoutId: "creator-classic",
scopeSelector: ".theme-creator-classic",
emitVars: (preset) => [
`--cp-bg: ${preset.vars.bg};`,
`--cp-text: ${preset.vars.text};`,
// ... 7 vars total: bg, surface, text, textMuted, heading, border, accent
],
});
buildThemeCss(theme, layoutPackage) slår binding op + emitter preset's var-set under binding's scope-selector + tenant's per-var-tweaks ovenpå med !important.
Fuld guide: Tema-systemet.