domma-cms 1.6.60 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4344 -0
- package/README.md +1 -1
- package/admin/dist/domma/domma-tools.css +3 -3
- package/admin/dist/domma/domma-tools.min.js +3 -3
- package/admin/js/lib/effect-defs.js +1 -1
- package/admin/js/lib/effects-builder.js +2 -2
- package/admin/js/lib/page-editor-reference.js +5 -5
- package/admin/js/lib/shortcode-tags.js +1 -1
- package/admin/js/templates/docs/usage-shortcodes.html +39 -0
- package/docs/DommaFeatures.md +3005 -0
- package/docs/MultiTenant.md +176 -0
- package/docs/api-reference.md +1667 -0
- package/docs/cache.md +96 -0
- package/docs/configuration.md +1811 -0
- package/docs/editions-and-licences.md +190 -0
- package/docs/getting-started.md +201 -0
- package/docs/guides/form-triggers.md +260 -0
- package/docs/guides/mongodb-storage-adapter.md +282 -0
- package/docs/guides/multi-page-forms.md +121 -0
- package/docs/images/scribe-composer.png +0 -0
- package/docs/markdown-shortcodes.md +1738 -0
- package/docs/pentest-report-2026-04-03.md +181 -0
- package/docs/plans/2026-02-28-admin-topbar-login-forms.md +349 -0
- package/docs/plans/2026-02-28-domma-ui-polish.md +286 -0
- package/docs/plans/2026-02-28-reset-seed-fresh-commands.md +520 -0
- package/docs/plans/2026-03-02-cookie-consent-design.md +86 -0
- package/docs/plans/2026-03-02-cookie-consent-plugin.md +453 -0
- package/docs/plans/2026-03-02-tooltip-sweep-and-back-to-top-plugin-design.md +126 -0
- package/docs/plans/2026-03-02-tooltip-sweep-back-to-top.md +427 -0
- package/docs/plans/2026-03-05-cookie-consent-btt-core.md +115 -0
- package/docs/plans/2026-03-05-custom-css-migrate-to-core-design.md +35 -0
- package/docs/plans/2026-03-05-custom-css-migrate-to-core.md +352 -0
- package/docs/plans/2026-03-05-scribe-script-shortcode.md +373 -0
- package/docs/plans/2026-03-05-user-types-design.md +139 -0
- package/docs/plans/2026-03-05-user-types-implementation.md +1035 -0
- package/docs/plans/2026-03-09-page-editor-view-cta-inserts-design.md +78 -0
- package/docs/plans/2026-03-09-page-editor-view-cta-inserts.md +388 -0
- package/docs/plans/2026-03-09-pro-documentation-design.md +80 -0
- package/docs/plans/2026-03-09-pro-documentation.md +1017 -0
- package/docs/plans/2026-06-10-core-project-design.md +240 -0
- package/docs/plugin-development.md +827 -0
- package/docs/recruitment-recipe.md +501 -0
- package/docs/scaffolding.md +312 -0
- package/docs/screenshots/calculator-floating.png +0 -0
- package/docs/screenshots/calculator-standard.png +0 -0
- package/docs/screenshots/email-settings.png +0 -0
- package/docs/screenshots/messages-count.png +0 -0
- package/docs/structure/user-types.md +107 -0
- package/docs/superpowers/plans/2026-05-25-admin-sidebar-via-menus.md +1112 -0
- package/docs/superpowers/plans/2026-06-08-navbar-mobile-drawer-and-menu-enrichment.md +1161 -0
- package/docs/superpowers/plans/2026-06-25-domma-docs-project.md +695 -0
- package/docs/superpowers/plans/2026-06-26-surveys-HANDOFF.md +68 -0
- package/docs/superpowers/plans/2026-06-26-surveys-pro-plugin.md +1902 -0
- package/docs/superpowers/plans/2026-08-19-collection-context-sort-export.md +1577 -0
- package/docs/superpowers/plans/2026-10-09-content-api.md +1192 -0
- package/docs/superpowers/specs/2026-03-12-form-followup-actions-design.md +152 -0
- package/docs/superpowers/specs/2026-03-12-page-editor-form-insert-and-per-page-theme-design.md +115 -0
- package/docs/superpowers/specs/2026-03-17-nav-hidden-items-design.md +85 -0
- package/docs/superpowers/specs/2026-03-19-accordion-insert-design.md +175 -0
- package/docs/superpowers/specs/2026-03-25-static-block-shortcode-design.md +153 -0
- package/docs/superpowers/specs/2026-03-25-text-shortcode-design.md +168 -0
- package/docs/superpowers/specs/2026-04-05-card-builder-design.md +315 -0
- package/docs/superpowers/specs/2026-04-06-insert-builders-design.md +278 -0
- package/docs/superpowers/specs/2026-04-06-layouts-design.md +226 -0
- package/docs/superpowers/specs/2026-04-07-blog-plugin-design.md +300 -0
- package/docs/superpowers/specs/2026-04-07-calendar-plugin-design.md +538 -0
- package/docs/superpowers/specs/2026-04-17-components-area-design.md +368 -0
- package/docs/superpowers/specs/2026-05-02-effects-slideover-overhaul-design.md +193 -0
- package/docs/superpowers/specs/2026-05-06-dashboard-rebuild-design.md +257 -0
- package/docs/superpowers/specs/2026-05-24-menus-design.md +466 -0
- package/docs/superpowers/specs/2026-05-25-admin-sidebar-via-menus-design.md +358 -0
- package/docs/superpowers/specs/2026-05-25-projects-design.md +380 -0
- package/docs/superpowers/specs/2026-06-08-navbar-mobile-drawer-and-menu-enrichment-design.md +292 -0
- package/docs/superpowers/specs/2026-06-08-sidebar-tools-plugins-folders-design.md +59 -0
- package/docs/superpowers/specs/2026-06-25-domma-docs-project-design.md +192 -0
- package/docs/superpowers/specs/2026-06-26-domma-charts-upstream-proposal.md +44 -0
- package/docs/superpowers/specs/2026-06-26-manager-scheduler-upstream-proposal.md +46 -0
- package/docs/superpowers/specs/2026-06-26-surveys-pro-plugin-design.md +206 -0
- package/docs/superpowers/specs/2026-07-02-shortcode-context-menu-design.md +96 -0
- package/docs/superpowers/specs/2026-08-19-collection-context-sort-export-design.md +330 -0
- package/docs/superpowers/specs/2026-09-22-dcms-marketplace-design.md +1150 -0
- package/docs/superpowers/specs/2026-10-09-content-api-design.md +325 -0
- package/docs/superpowers/specs/plans/2026-03-12-form-followup-actions.md +624 -0
- package/docs/superpowers/specs/plans/2026-03-12-page-editor-form-insert-and-per-page-theme.md +125 -0
- package/docs/superpowers/specs/plans/2026-03-17-nav-hidden-items.md +578 -0
- package/docs/superpowers/specs/plans/2026-03-19-accordion-insert.md +635 -0
- package/docs/superpowers/specs/plans/2026-03-25-text-shortcode.md +545 -0
- package/docs/superpowers/specs/plans/2026-04-05-card-builder.md +1970 -0
- package/docs/superpowers/specs/plans/2026-04-06-insert-builders.md +1049 -0
- package/docs/superpowers/specs/plans/2026-04-06-layouts.md +1015 -0
- package/docs/superpowers/specs/plans/2026-04-07-calendar-plugin.md +1526 -0
- package/docs/superpowers/specs/plans/2026-04-08-plugin-monetisation-split.md +242 -0
- package/docs/superpowers/specs/plans/2026-04-17-components-area.md +2038 -0
- package/docs/superpowers/specs/plans/2026-05-02-effects-slideover-overhaul.md +2335 -0
- package/docs/superpowers/specs/plans/2026-05-06-dashboard-rebuild.md +1999 -0
- package/docs/superpowers/specs/plans/2026-05-17-cache-system.md +1436 -0
- package/docs/superpowers/specs/plans/2026-05-24-menus.md +3096 -0
- package/docs/superpowers/specs/plans/2026-05-25-projects.md +2869 -0
- package/docs/superpowers/specs/plans/2026-09-22-marketplace-step2-consolidation.md +505 -0
- package/docs/superpowers/specs/plans/2026-09-22-marketplace-step3-catalogue-and-key.md +154 -0
- package/docs/superpowers/specs/plans/2026-09-22-tools-promotion.md +260 -0
- package/docs/theming.md +320 -0
- package/package.json +2 -2
- package/public/js/celebrations/core/canvas.js +1 -1
- package/public/js/celebrations/index.js +1 -1
- package/public/js/celebrations/licenses/ABeeZee-Regular-OFL.txt +93 -0
- package/public/js/celebrations/licenses/Allura-Regular-OFL.txt +93 -0
- package/public/js/celebrations/message-attrs.mjs +1 -0
- package/public/js/celebrations/themes/anniversary.js +1 -0
- package/public/js/celebrations/themes/autumn.js +1 -0
- package/public/js/celebrations/themes/birthday.js +1 -0
- package/public/js/celebrations/themes/butterfly-flight.js +1 -0
- package/public/js/celebrations/themes/calendar.js +1 -0
- package/public/js/celebrations/themes/chinese-new-year-dates.js +1 -0
- package/public/js/celebrations/themes/chinese-new-year.js +1 -0
- package/public/js/celebrations/themes/christmas.js +1 -1
- package/public/js/celebrations/themes/easter.js +1 -0
- package/public/js/celebrations/themes/garden-drawing.js +1 -0
- package/public/js/celebrations/themes/garden.js +1 -0
- package/public/js/celebrations/themes/graduation.js +1 -0
- package/public/js/celebrations/themes/greeting.js +1 -0
- package/public/js/celebrations/themes/make-it-rain.js +1 -0
- package/public/js/celebrations/themes/money-rain.js +1 -0
- package/public/js/celebrations/themes/new-year.js +1 -0
- package/public/js/celebrations/themes/occasion-drawing.js +1 -0
- package/public/js/celebrations/themes/occasions.js +1 -0
- package/public/js/celebrations/themes/rain-control.js +1 -0
- package/public/js/celebrations/themes/sparkler-font-data.js +1 -0
- package/public/js/celebrations/themes/sparkler-font.js +1 -0
- package/public/js/celebrations/themes/sparkler-writing.js +1 -0
- package/public/js/celebrations/themes/summer-garden.js +1 -0
- package/public/js/celebrations/themes/winter.js +1 -0
- package/public/js/celebrations/trait-data.mjs +1 -1
- package/public/js/effects.js +1 -1
- package/scripts/build.js +4 -0
- package/server/services/markdown.js +5 -2
- package/server/templates/page.html +1 -1
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# MongoDB Storage Adapter (Pro Feature)
|
|
2
|
+
|
|
3
|
+
Domma CMS stores collection entries as JSON files by default. The MongoDB Storage Adapter is an optional Pro feature
|
|
4
|
+
that lets you store collection entries in a MongoDB database instead - with zero changes to the CMS admin interface.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Why Use It
|
|
9
|
+
|
|
10
|
+
| Reason | Detail |
|
|
11
|
+
|-------------------|------------------------------------------------------------|
|
|
12
|
+
| **Scale** | Handle thousands of entries without directory I/O overhead |
|
|
13
|
+
| **Query power** | Rich filtering, sorting, and aggregation via MongoDB |
|
|
14
|
+
| **Mixed mode** | Some collections on MongoDB, others on file - your choice |
|
|
15
|
+
| **Seamless swap** | Change one line in `schema.json`; no code changes needed |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
- MongoDB 6.0 or later (local or hosted - MongoDB Atlas works)
|
|
22
|
+
- Node.js 24+
|
|
23
|
+
- Domma CMS 0.4.0+
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Quick Setup
|
|
28
|
+
|
|
29
|
+
The fastest way to enable Pro mode:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm run pro enable
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This will:
|
|
36
|
+
|
|
37
|
+
1. Copy `config/connections.json.example` → `config/connections.json`
|
|
38
|
+
2. Prompt you for your MongoDB URI and database name
|
|
39
|
+
3. Run `npm install mongodb`
|
|
40
|
+
|
|
41
|
+
Then restart the server and configure individual collections (see below).
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Manual Setup
|
|
46
|
+
|
|
47
|
+
If you prefer to configure manually:
|
|
48
|
+
|
|
49
|
+
### 1. Copy the example connections file
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cp config/connections.json.example config/connections.json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2. Edit `config/connections.json`
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"default": {
|
|
60
|
+
"type": "mongodb",
|
|
61
|
+
"uri": "mongodb://localhost:27017",
|
|
62
|
+
"database": "domma_cms",
|
|
63
|
+
"options": {}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Field | Description |
|
|
69
|
+
|------------|------------------------------------------------|
|
|
70
|
+
| `type` | Must be `"mongodb"` |
|
|
71
|
+
| `uri` | MongoDB connection string |
|
|
72
|
+
| `database` | Name of the database to use |
|
|
73
|
+
| `options` | Optional extra options passed to `MongoClient` |
|
|
74
|
+
|
|
75
|
+
> `config/connections.json` is gitignored - credentials stay local and are never committed.
|
|
76
|
+
|
|
77
|
+
### 3. Install the mongodb package
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npm install mongodb
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4. Restart the server
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npm start
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
You should see connection log lines like:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
[connectionManager] Connected: default → domma_cms
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Multiple Connections
|
|
98
|
+
|
|
99
|
+
You can define any number of named connections:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"default": {
|
|
104
|
+
"type": "mongodb",
|
|
105
|
+
"uri": "mongodb://localhost:27017",
|
|
106
|
+
"database": "domma_cms",
|
|
107
|
+
"options": {}
|
|
108
|
+
},
|
|
109
|
+
"atlas": {
|
|
110
|
+
"type": "mongodb",
|
|
111
|
+
"uri": "mongodb+srv://user:pass@cluster.mongodb.net",
|
|
112
|
+
"database": "domma_prod",
|
|
113
|
+
"options": {}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Each collection then references a connection by name in its `schema.json`.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Connections in the admin
|
|
123
|
+
|
|
124
|
+
Admins can edit `config/connections.json` on the **Database connections** tab of **Collections** (`GET`/`PUT /api/collections/connections`)
|
|
125
|
+
instead of by hand; URIs are masked on screen. Connections are opened at startup, so restart after adding or changing
|
|
126
|
+
one.
|
|
127
|
+
|
|
128
|
+
If a connection fails, collections on it fall back to file storage and the admin raises a critical **Database
|
|
129
|
+
unavailable** notification (source `core:storage`) naming the connection, so the empty lists are explained.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Switching a Collection to MongoDB
|
|
134
|
+
|
|
135
|
+
Edit the collection's `schema.json` and add a `storage` block:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"slug": "products",
|
|
140
|
+
"title": "Products",
|
|
141
|
+
"fields": [...],
|
|
142
|
+
"storage": {
|
|
143
|
+
"adapter": "mongodb",
|
|
144
|
+
"connection": "default"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
| Field | Required | Default | Description |
|
|
150
|
+
|----------------------|----------|-------------|------------------------------------------|
|
|
151
|
+
| `storage.adapter` | Yes | `"file"` | Set to `"mongodb"` to use MongoDB |
|
|
152
|
+
| `storage.connection` | No | `"default"` | Named connection from `connections.json` |
|
|
153
|
+
|
|
154
|
+
The easier way is the collection editor's **Storage** tab (shown once a connection exists): choose the adapter and
|
|
155
|
+
connection and it moves the existing entries across for you (`POST /api/collections/:slug/migrate-storage`), with no
|
|
156
|
+
restart. Moved entries are created afresh in the new store, so they get **new ids and dates** - references to them
|
|
157
|
+
from other collections do not follow. When moving off file storage, the old `data.json` is kept as `data.json.bak`.
|
|
158
|
+
|
|
159
|
+
If you edit `schema.json` by hand instead, **restart the server**: the adapter registry caches each collection's
|
|
160
|
+
adapter, and only a save through the CMS (or a restart) clears it. A hand edit moves no entries.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Switching Back to File-Based
|
|
165
|
+
|
|
166
|
+
Remove the `storage` block from `schema.json`:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"slug": "products",
|
|
171
|
+
"title": "Products",
|
|
172
|
+
"fields": [...]
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
> **Important:** a hand edit does not move entries back to files. Use the Storage tab, which moves them (with new ids,
|
|
177
|
+
> as above), or export and re-import them.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Mixed Mode
|
|
182
|
+
|
|
183
|
+
Collections can use different adapters independently:
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
┌─────────────────────────────────────────────┐
|
|
187
|
+
│ Domma CMS Collections │
|
|
188
|
+
├──────────────────┬──────────────────────────┤
|
|
189
|
+
│ products │ → MongoAdapter (default) │
|
|
190
|
+
│ blog-posts │ → MongoAdapter (atlas) │
|
|
191
|
+
│ testimonials │ → FileAdapter │
|
|
192
|
+
│ roles │ → FileAdapter (always) │
|
|
193
|
+
└──────────────────┴──────────────────────────┘
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Preset collections - `roles`, `user-profiles`, `projects` and the rest defined in `server/services/presetCollections.js`
|
|
197
|
+
(notes, todo items, contacts and others) - always use the file adapter, whatever their `storage` block says
|
|
198
|
+
(`server/services/adapterRegistry.js`).
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## How It Works Internally
|
|
203
|
+
|
|
204
|
+
| Component | File | Role |
|
|
205
|
+
|---------------------|--------------------------------------------|--------------------------------------------------------------------------|
|
|
206
|
+
| Connection Manager | `server/services/connectionManager.js` | Creates and caches `MongoClient` instances at startup |
|
|
207
|
+
| Adapter Registry | `server/services/adapterRegistry.js` | Reads `schema.json` and resolves the correct adapter per collection |
|
|
208
|
+
| File Adapter | `server/services/adapters/FileAdapter.js` | Default; reads/writes JSON files in `content/collections/` |
|
|
209
|
+
| Mongo Adapter | `server/services/adapters/MongoAdapter.js` | Reads/writes documents in MongoDB; prefixes collection names with `cms_` |
|
|
210
|
+
| Collections Service | `server/services/collections.js` | Orchestrates CRUD, delegates I/O to the resolved adapter |
|
|
211
|
+
|
|
212
|
+
### Startup flow
|
|
213
|
+
|
|
214
|
+
1. Server reads `config/connections.json` (if present)
|
|
215
|
+
2. `connectionManager.initialise()` connects to all named MongoDB servers
|
|
216
|
+
3. Each collection schema is read lazily on first request
|
|
217
|
+
4. `adapterRegistry.getAdapter(slug)` resolves and caches the adapter
|
|
218
|
+
|
|
219
|
+
### Request flow (entry read/write)
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
API route → collections.js → adapterRegistry.getAdapter(slug)
|
|
223
|
+
│
|
|
224
|
+
┌────────────────┴─────────────────┐
|
|
225
|
+
│ │
|
|
226
|
+
FileAdapter MongoAdapter
|
|
227
|
+
(content/collections/) (MongoDB via getDb())
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Checking Status
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm run pro status
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Example output (Pro enabled):
|
|
239
|
+
|
|
240
|
+
```
|
|
241
|
+
Pro Mode Status
|
|
242
|
+
───────────────
|
|
243
|
+
Mode : Pro (MongoDB)
|
|
244
|
+
mongodb : installed ✓
|
|
245
|
+
|
|
246
|
+
Connections (1):
|
|
247
|
+
• default
|
|
248
|
+
URI : mongodb://localhost:27017
|
|
249
|
+
Database : domma_cms
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
MongoDB URIs with passwords are automatically masked (`****`).
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Disabling Pro Mode
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
npm run pro disable
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
This backs up `config/connections.json` to `config/connections.json.bak` and optionally uninstalls the `mongodb`
|
|
263
|
+
package. The server falls back to file-based storage on next restart.
|
|
264
|
+
|
|
265
|
+
To re-enable, run `npm run pro enable` or rename the backup:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
mv config/connections.json.bak config/connections.json
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Troubleshooting
|
|
274
|
+
|
|
275
|
+
| Symptom | Cause | Fix |
|
|
276
|
+
|-----------------------------------------------------------|--------------------------------------------------------------------|-----------------------------------------------------------------|
|
|
277
|
+
| No `[connectionManager] Connected` log line | `config/connections.json` missing or mongodb not installed | Run `npm run pro enable` |
|
|
278
|
+
| `Failed to connect "default"` in logs | Wrong URI, MongoDB not running, or network issue | Check URI in `connections.json` and ensure MongoDB is reachable |
|
|
279
|
+
| `[adapterRegistry] Failed to load MongoAdapter` | `mongodb` package not installed or connection failed | Run `npm install mongodb`, check connection logs |
|
|
280
|
+
| Collection entries appear empty after switching | `schema.json` was edited by hand, which moves no entries | Switch with the editor's Storage tab, or export and re-import |
|
|
281
|
+
| `Unknown connection: "name"` error | Connection name in `schema.json` not defined in `connections.json` | Add the named connection to `connections.json` and restart |
|
|
282
|
+
| A preset collection (`roles`, …) ignores `storage` config | By design - system collections always use file storage | No fix needed; this is intentional |
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Multi-Page Forms (Wizards)
|
|
2
|
+
|
|
3
|
+
Any form in the Form Builder becomes a wizard by adding a **Page Break**. Fields before the
|
|
4
|
+
break are page one, fields after it are page two, and so on. The visitor moves through with
|
|
5
|
+
Previous / Next and submits from the last page.
|
|
6
|
+
|
|
7
|
+
There is no separate "wizard mode" to switch on - the page breaks are the switch.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Building one
|
|
12
|
+
|
|
13
|
+
In **Forms → edit a form**, use **Add Page Break** between the fields you want to separate.
|
|
14
|
+
Each break carries two fields of its own:
|
|
15
|
+
|
|
16
|
+
| Field | Effect |
|
|
17
|
+
|-----------------|---------------------------------------------------------------|
|
|
18
|
+
| **Step Title** | Heading shown above that page |
|
|
19
|
+
| **Description** | Smaller line under the heading; leave blank to omit it |
|
|
20
|
+
|
|
21
|
+
The first page has no break before it, so it takes its heading from the form's own title.
|
|
22
|
+
Give it a different one by putting a page break at the very top - a break with nothing before
|
|
23
|
+
it re-titles the page that follows rather than creating an empty page of its own.
|
|
24
|
+
|
|
25
|
+
A break at the very end is ignored for the same reason: it would produce a final page holding
|
|
26
|
+
nothing but the button.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Layout
|
|
31
|
+
|
|
32
|
+
Forms are laid out as a **grid** unless you choose otherwise, two columns by
|
|
33
|
+
default and three if you set Columns to 3 - those are the only two the renderer
|
|
34
|
+
produces. A field can be widened with its **Column Span**, or set to **Full
|
|
35
|
+
Width** to take the whole row.
|
|
36
|
+
|
|
37
|
+
Stacked and Inline are still there under **Settings → Layout** if a form reads
|
|
38
|
+
better one field per line.
|
|
39
|
+
|
|
40
|
+
**Settings → Submit Button Position** does not move a wizard's buttons: Previous
|
|
41
|
+
and Next / Finish stay at the two ends of the footer on every page, so the button
|
|
42
|
+
never jumps under the visitor's pointer between steps.
|
|
43
|
+
|
|
44
|
+
The rest of the **Submit Button** card does reach the footer: **Style** and
|
|
45
|
+
**Size** apply to Next and Finish, the icons to Finish only, and Previous takes
|
|
46
|
+
the size. A **second button** (Clear form or a Cancel link) is not shown on a
|
|
47
|
+
multi-step form - Clear on a later page could not clear the pages already
|
|
48
|
+
answered, and the footer already has Previous.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## What carries across pages
|
|
53
|
+
|
|
54
|
+
Everything the single-page form does is applied to each page as the visitor reaches it.
|
|
55
|
+
|
|
56
|
+
| Feature | Behaviour across pages |
|
|
57
|
+
|------------------------|-----------------------------------------------------------------------|
|
|
58
|
+
| **Layout / columns** | The form's Layout and Columns settings apply to every page |
|
|
59
|
+
| **Field spans** | A field set to span the full width does so on whichever page it is on |
|
|
60
|
+
| **Date fields** | Render as native date pickers on every page |
|
|
61
|
+
| **Icon / image fields**| Keep their Browse buttons and previews on every page |
|
|
62
|
+
| **Spacers** | Rendered in place on the page they belong to |
|
|
63
|
+
| **File uploads** | A file chosen on page one is still attached when page three submits |
|
|
64
|
+
| **Conditional logic** | A rule on page two can test an answer given on page one |
|
|
65
|
+
| **Spam protection** | The honeypot and timing check cover the submission, not just page one |
|
|
66
|
+
|
|
67
|
+
Answers are accumulated as the visitor advances, so going **Previous** and changing an answer
|
|
68
|
+
re-evaluates any rule that depends on it.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Validation
|
|
73
|
+
|
|
74
|
+
Each page validates before it will let the visitor move on - required fields must be filled
|
|
75
|
+
and format rules must pass. The server re-checks everything on submit regardless of what the
|
|
76
|
+
browser allowed, including conditional requirements that depend on answers from other pages.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Preview
|
|
81
|
+
|
|
82
|
+
The builder's live preview renders the wizard exactly as the public page does: same layout,
|
|
83
|
+
same page splitting, same titles. Stepping through the preview is a fair test of the real
|
|
84
|
+
thing. The preview submits to the real endpoint once the form has been saved, so test
|
|
85
|
+
submissions are stored like any other.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Notes and limits
|
|
90
|
+
|
|
91
|
+
- **Don't name a field `website`.** It is the name used by the spam honeypot. The CMS steps
|
|
92
|
+
the honeypot aside if you do, but a clearer field name (`your_website`, `company_url`)
|
|
93
|
+
avoids the question entirely.
|
|
94
|
+
- **Field names must be unique across the whole form**, not just within a page. Two pages
|
|
95
|
+
using the same name will overwrite one another.
|
|
96
|
+
- A form made only of page breaks renders as a single empty page.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Where a form is rendered from
|
|
101
|
+
|
|
102
|
+
Three different pieces of code render a form, depending on how it reaches the
|
|
103
|
+
page. They behave identically, but knowing which one is in play saves time when
|
|
104
|
+
something looks wrong:
|
|
105
|
+
|
|
106
|
+
| How the form got there | Rendered by |
|
|
107
|
+
|----------------------------------------|---------------------------------|
|
|
108
|
+
| `[form slug="…" /]` in page content | `public/js/site.js` |
|
|
109
|
+
| A hand-written `<div data-form="…">` | `public/js/forms.js` |
|
|
110
|
+
| The builder's live preview | `admin/js/views/form-editor.js` |
|
|
111
|
+
|
|
112
|
+
All three share `public/js/form-steps.mjs` for splitting a form into pages.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Related
|
|
117
|
+
|
|
118
|
+
- [Form Triggers](form-triggers.md)
|
|
119
|
+
|
|
120
|
+
- `docs/configuration.md` - form settings schema
|
|
121
|
+
- Admin → Forms → Settings tab - layout, columns, honeypot, rate limit, and the Submit Button card (text, position, style, size, icons, second button)
|
|
Binary file
|