blueprint.json¶
What it is¶
In this repository, blueprint.json is the portable description of the initial Omeka S state that should exist inside a playground scope.
The default file is:
assets/blueprints/default.blueprint.json
It is inspired by WordPress Playground blueprints, but it is not the upstream WordPress schema. The authoritative implementation for this project is:
- schema:
assets/blueprints/blueprint-schema.json - normalization logic:
src/shared/blueprint.js
How the repository uses it¶
The shell loads a blueprint, normalizes missing values, and stores the active version for the current scope. The runtime then consumes that normalized blueprint during boot to:
- set install metadata such as title, locale, and timezone
- create and authenticate the primary admin account
- create additional users and apply per-user settings
- install or activate modules and themes
- create item sets, items, and media
- create one or more sites, assign per-site user permissions, and pick the default
- choose the landing page after boot
Because the blueprint influences first-boot behavior, a small JSON change can alter installation, login, routing, or demo content.
Structure used by this project¶
The most important top-level properties are:
| Property | Purpose | Notes |
|---|---|---|
$schema |
Editor/schema reference | Point at the repository schema when possible |
meta |
Human-readable metadata | Good place for title, author, and description |
preferredVersions |
Informational runtime targets | Useful for intent, not a strict installer lockfile |
debug.enabled |
Enables development-style diagnostics | Helpful for install/debug sessions |
landingPage |
Initial post-boot path | Should usually begin with / |
siteOptions |
Install-wide defaults | Title, locale, timezone |
login |
Credentials used by autologin | Usually mirror the first user |
users |
Omeka users to create | First user becomes the effective admin source; each may carry settings |
themes |
Themes to install | Supports bundled, URL, and omeka.org sources |
modules |
Modules to install or activate | Module names must stay unique |
itemSets |
Collections created before items | Referenced by item titles later |
items |
Sample resources and media | Media currently uses URL sources; items[].sites assigns sites by slug |
site |
A single public site | Optional; legacy shorthand for a one-entry sites |
sites |
One or more public sites with per-site permissions | Takes precedence over site; one is the default |
Example¶
{
"$schema": "./assets/blueprints/blueprint-schema.json",
"meta": {
"title": "Demo classroom blueprint",
"author": "ateeducacion",
"description": "Creates a reusable demo site with sample media."
},
"debug": {
"enabled": false
},
"landingPage": "/admin",
"siteOptions": {
"title": "Classroom Demo",
"locale": "es",
"timezone": "Atlantic/Canary"
},
"login": {
"email": "admin@example.com",
"password": "password"
},
"users": [
{
"username": "admin",
"email": "admin@example.com",
"password": "password",
"role": "global_admin"
}
],
"themes": [
{
"name": "Foundation",
"source": { "type": "omeka.org", "slug": "foundation-s" }
}
],
"modules": [
{ "name": "CSVImport", "state": "activate" }
],
"itemSets": [
{ "title": "Playground Collection" }
],
"items": [
{
"title": "Openverse Sample Image",
"itemSets": ["Playground Collection"],
"media": [
{
"type": "url",
"url": "./assets/samples/playground-sample.png",
"title": "Playground sample image"
}
]
}
],
"site": {
"title": "Demo Site",
"slug": "demo-site",
"theme": "Foundation",
"setAsDefault": true
}
}
Multiple sites, permissions, and per-user settings¶
Use the sites array to provision more than one site and to grant users access
to specific sites. This is what makes access-control modules such as
IsolatedSites testable
in the browser: give a user a per-site role, flip a per-user setting, and assign
items to individual sites.
sites[]accepts the same fields as the singularsite(title,slug,summary,theme,isPublic,setAsDefault) pluspermissions.sites[].permissions[]grants an existing blueprint user (by email) a site role ofviewer,editor, oradmin.- Exactly one site is the default. If no entry sets
setAsDefault: true, the first one is used. The legacy singularsitestill works and is treated as a one-entrysiteslist (keeping its historical default ofsetAsDefault: true). users[].settingsis an object written verbatim to each user's settings (user_setting), e.g.limit_to_granted_sites.items[].siteslists the site slugs (titles are also accepted and slugified) an item is assigned to. Without it, items go to the default site.
{
"users": [
{ "username": "admin", "email": "admin@example.com", "password": "password", "role": "global_admin" },
{
"username": "editor_a",
"email": "editor.a@example.com",
"password": "password",
"role": "site_editor",
"settings": { "limit_to_granted_sites": true, "limit_to_own_assets": true }
}
],
"sites": [
{
"title": "Site A",
"slug": "site-a",
"setAsDefault": true,
"permissions": [{ "user": "editor.a@example.com", "role": "admin" }]
},
{ "title": "Site B", "slug": "site-b" }
],
"items": [
{ "title": "Doc A1", "sites": ["site-a"] },
{ "title": "Doc B1", "sites": ["site-b"] }
]
}
With this blueprint, signing in as editor.a@example.com (with IsolatedSites
active) shows only Site A and its items, while the admin keeps full visibility.
Example file for Common + EasyAdmin¶
There is a ready-to-copy example at:
blueprint-sample.json
That sample installs Common first and then EasyAdmin. It is the better file to reuse here because it is already tracked as a real project sample, so the documentation should point at it instead of duplicating a second near-identical blueprint under docs/.
How to write and maintain it well¶
Keep it readable¶
- Prefer one clear responsibility per section.
- Keep related values grouped together instead of scattering overrides.
- Use descriptive
meta.titleandmeta.descriptionvalues so future contributors understand intent immediately.
Keep it stable¶
- Prefer bundled addons or known-good
omeka.orgslugs before remote ZIP URLs. - Avoid duplicate module or theme names;
src/shared/blueprint.jsrejects duplicates. - Keep
landingPagesimple and explicit./adminis the safest default for contributor-oriented blueprints.
Keep it maintainable¶
- Treat the first user as the canonical admin account because normalization uses it to derive effective admin config.
- Keep
loginaligned with the first user unless you have a strong reason not to. - Use a small number of representative sample items instead of large demo datasets that slow down resets and reviews.
- Prefer relative media URLs for repository-bundled samples when possible.
Project-specific rules and conventions¶
These conventions come from the current implementation, not generic JSON style advice:
landingPageis normalized to start with/.- User roles such as
adminandsupervisorare normalized to Omeka roles likeglobal_adminandsite_admin. - Addon names must be a single path segment; slashes and traversal-like names are rejected.
- Remote addon URLs are absolutized against the current page URL.
modules[].statecurrently supportsinstallandactivate.items[].media[].typecurrently supportsurl.sitestakes precedence over the singularsite; exactly one site is forced to be the default (the first one if none is flagged), and duplicate site slugs are rejected.sites[].permissions[].roleis clamped to one ofviewer,editor,admin(defaults toviewer); a permission whoseuseremail matches no created user is skipped with a warning.items[].sitesentries are slugified to match site slugs; items with no match fall back to the default site.users[].settingskeys are written verbatim touser_setting; values are stored as-is.
If you change the semantics of any of those rules, update both the schema and the documentation together.
How to validate changes¶
- Edit the blueprint JSON.
- Compare it with
assets/blueprints/blueprint-schema.json. - Start the app and trigger a clean boot by importing the blueprint or using a new scope.
- Confirm the expected landing page, users, modules, themes, and sample content appear.
- If something fails during boot, temporarily enable
debug.enabled.
Useful targeted checks:
node --check src/shared/blueprint.js
node --check src/runtime/bootstrap.js
Common mistakes to avoid¶
- Using the upstream WordPress Playground schema as if it were identical. This repository implements its own Omeka-specific blueprint format.
- Adding hidden assumptions to runtime code instead of the blueprint. That makes the setup harder to reason about.
- Leaving
loginout of sync with the first user. Autologin can become confusing. - Using fragile remote ZIP URLs. If the URL needs unusual redirects or post-install steps, it may not work in-browser.
- Overloading the blueprint with too much sample content. Large initial datasets slow resets and make review harder.
Troubleshooting¶
The playground boots but lands on the wrong page¶
Check landingPage, current shell session state, and whether autologin bypassed a saved /login path.
A module or theme does not install¶
Verify the addon name, the source definition, and whether the remote host is compatible with the configured proxy and outbound HTTP policy.
Media fails to load¶
Confirm the URL resolves correctly from the deployed base path or local dev server. Relative sample paths are resolved against the current page URL.
A blueprint import appears to do nothing¶
The shell only applies imported data after parsing and normalization. Check the browser console, shell logs, and whether the payload is valid JSON/base64url for blueprint-data.