Extending
The ways to add behaviour to a Meridian site without changing the engine: configuration and declared endpoints, templates and components, Go extensions loaded from engine.yaml, and experimental out-of-process plugins, with how to choose between them.
You are given the engine as a binary (engine-dmo or engine-cms) and never its source. Everything a site needs beyond what the binary does is added from the project directory, in one of four ways. Start with the first that can express what you need: each later one costs more to build, test and keep in step with engine releases.
| Way | What it adds | Written in | Runs | Where it is described |
|---|---|---|---|---|
| Configuration | Content types and fields, routes, sites and locales, declared endpoints (forms, JSON projections, calls to upstream APIs), outbound webhooks, scheduled feed imports, roles | YAML under config/ | Inside the engine | Content modelling, Forms and submissions, Integrating |
| Templates | Every page’s markup, components, blocks, partials, the portal’s look | Pongo2 templates under templates/ | Inside the engine | Templates |
| Extensions | Template globals and filters, HTTP routes, commands, the asset helpers’ resolver, a dev server under serve --dev | Go, as a plugin (.so) built against github.com/wrux/meridian-extend | Inside the engine process | Extensions |
| Project plugins (experimental) | Logic a declared endpoint calls when YAML cannot express it: branching rules, a calculation, a partner SDK | Any language that speaks the protocol; Go with github.com/wrux/meridian-plugin | A separate process the engine supervises | Project plugins |
Choosing
- A new field, type, page or form. Configuration and templates. The engine validates both with
engine-dmo check, renders them through the real pipeline withengine-dmo render, and reports every mistake at its file, line and column. - Reading another service’s JSON on a page or from an endpoint. A source in
sources.yamland thesource()template function or asourcestep. See Sources and importers. - Telling another system that content changed. An outbound webhook in
webhooks.yaml. See Webhooks. - A template function or filter the engine does not have (a class-name merger, a formatter for a house style, a lookup in a file the project ships). An extension.
- An HTTP route that is not a page, a form or a JSON projection, or a command of your own beside the engine’s. An extension.
- Wiring a frontend toolchain into the asset helpers and the dev loop. The first-party
viteextension, or an extension of your own built the same way. - An endpoint whose answer needs control flow (a market that runs every Thursday except over Christmas, a price that depends on three inputs). A project plugin, marked experimental: its protocol may change in any release.
What none of them can do
- Change how content is stored, validated, versioned or published, or add a field type. Field types are the engine’s.
- Reach the database. Extensions and plugins see what the interfaces below hand them, and nothing else.
- Change the admin’s screens. The admin’s look is themed with
admin.themeinengine.yaml; its screens are the engine’s. - Bypass permissions. An extension’s route secures itself; it is given no session or permission check of the engine’s.
The checks that hold it together
Whichever way you choose, the same loop applies:
engine-dmo check --project . # configuration, schema, templates and extensions, every problem at once
engine-dmo render / --project . # a page through the real pipeline, in process
engine-dmo template api --project . # the template surface, including what your extensions declare engine-dmo check loads every extension the project names and runs its Register, so a template that calls a global no extension declares, or passes a keyword the global does not take, fails the check rather than the page.
engine-cms behaves the same for everything on these pages: extensions and project plugins are core features of both bundles.
Multisite and networks
How several sites in one install share or separate partners: networks of sites that share organisations, people and portal accounts, what stays per site (tiers, slots, portals, landing pages), how staff are scoped to a network, and moving a site out with site export and retire.
Extensions
How to write a Meridian extension, a Go plugin built against github.com/wrux/meridian-extend that adds template globals and filters, HTTP routes, commands, an asset resolver and a dev server; every interface it offers, how to build it so the engine will load it, how to name it in engine.yaml, and every error the loader gives.