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.
engine-dmo
One install can run several sites, each a property with its own domains, locales, routes and templates, sharing one body of content (see Sites, locales and routes). For the partner side of the platform there is one more decision to make: do two sites deal with the same businesses? A county guide and a town guide inside it may both list the same pub, but if the town’s businesses deal with the town council and not the county, their records, their people and their portal accounts must not be the county’s.
That boundary is a network: a set of sites that share organisations, people and partner accounts. Sites in different networks share none of them.
Networks
Every install has a network called default, which a site joins by leaving network: out. Declare others in config/networks.yaml and name one in a site’s site.yaml:
networks:
- key: llanwynd
name: { en-GB: Llanwynd Town partners } site:
name: { en-GB: Llanwynd Town }
network: llanwynd
domains: [town.example.org] | Key | Meaning |
|---|---|
networks[].key | Lowercase letters, digits and hyphens. default is reserved: it is never declared. |
networks[].id | The stable id (net_), written by check --fix. Records are stored against it, so renaming a network keeps them. |
networks[].name | Its name per locale |
site.network in site.yaml | The network the site belongs to; default when absent |
engine-dmo dev network add <key> --name <name> --site <site> declares a network and joins sites to it, and engine-dmo dev site add <key> --network <key> adds a site in a network (declaring the network when it is new). check refuses a site naming an undeclared network and warns about a network no site uses. engine-dmo describe project lists networks with their sites.
What a network separates
| Per network | Shared across the whole install |
|---|---|
| Organisations and people, and the contacts between them | Content (documents, revisions, publish state) |
| Portal accounts and member sessions | Tags and the vocabulary |
| Claims, imports (a source belongs to a network) | Media |
| Smart lists of organisations and people (read only within the list’s networks) | Schema, templates, strings |
| Broadcasts’ audiences | Staff accounts, roles and the admin |
So the same pub on both sites is two organisations, one in each network; the same owner’s email address is two people with two portal accounts; and a portal session on one site is not signed in on a site of another network. A document’s organisation must be in the network of the document’s owner site.
Within one network, an organisation listed on several sites is one record with one portal account, and its member report shows its figures on each site and their total.
What stays per site
These belong to a site whichever network it is in:
| What | Where |
|---|---|
| The tiers it sells | memberships.tiers in site.yaml (every tier when absent) |
| Memberships | One per organisation per site |
| Who may edit what, per tier | member_editable in the type, or in the site’s own schema file |
| Its portal path, mode, routes, hidden screens, screens and actions | config/sites/<site>/portal.yaml |
| Its promotion slots and label | config/sites/<site>/promotions.yaml |
| Its landing pages | landings: on its routes |
| Its prices | sites.<site> in config/paidlistings.yaml |
| Affiliate programmes | Set up per site in the admin |
path: /partners
routes:
organisation: "/businesses/{org}"
hide: [membership] A town that handles memberships on paper hides the membership screen and moves its portal to /partners, while the county keeps the install’s /members.
Staff and networks
Staff accounts are install-wide, but what they reach of the CRM follows their grants: a staff user reaches the networks of the sites their grants are scoped to, and every network through a grant with no site scope. A town officer granted the partnership-manager role scoped to the town site sees only the town’s businesses and people:
grants:
- group: town-team
role: partnership-manager
scope: { site: [town] } See Users, roles and permissions for grants and scopes.
Templates shared between sites
A template in a shared root is checked against every site whose chain includes it. Two things to watch in the DMO bundle:
promoted('<slot>')must name a slot each such site declares, orcheckfails on the site that does not (see Promotions);- a link to the claim form or the portal written as a literal path must match each site’s portal path. Read the path from a site setting, or override the template in the site’s own root.
A site leaving the install
When a site’s organisation leaves, its site can be moved to an install of its own and then removed here.
engine-dmo site export --site town --out ./town-export --scratch-database-url "$SCRATCH_DATABASE_URL" --plan
engine-dmo site export --site town --out ./town-export --scratch-database-url "$SCRATCH_DATABASE_URL" --signing-key-env TOWN_SIGNING_KEY
engine-dmo site retire --site town --plan
engine-dmo site retire --site town --yes | Command and flag | Meaning |
|---|---|
site export --site | The site to export |
--out | The directory to write, created with mode 0700; it must be empty or absent |
--scratch-database-url | A PostgreSQL server on which the export may create two databases and drop them; the export is verified by restoring it there and serving its home page |
--signing-key-env | An environment variable holding the receiving install’s signing key, to reseal second factors; without it they are cleared |
--staff | A staff user whose grants reach every site, by address, to copy as well; repeatable |
--plan | Print what would be copied and stop |
site retire --site | The site to remove: its rows, analytics and search indexes, and the people and organisations connected only to it, erased |
--plan | Print what would be removed and erased, and stop |
--yes | Retire without asking |
Both need the database. site export and site retire are core commands and also exist in engine-cms; in engine-dmo they carry the site’s partners with it. Retiring cannot be undone: export first and check the export.
Paid listings
How to sell membership tiers and promotions: prices in config/paidlistings.yaml, Stripe Checkout or staff invoices, the portal's billing screen, the Stripe webhook, orders and their statuses, and how a paid order grants, renews, refunds and lapses a membership or a promotion.
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.