domma-cms 0.25.15 → 0.25.16

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.
Files changed (42) hide show
  1. package/admin/js/app.js +2 -2
  2. package/admin/js/templates/api-reference.html +68 -1233
  3. package/admin/js/templates/docs/api-actions.html +146 -0
  4. package/admin/js/templates/docs/api-authentication.html +202 -0
  5. package/admin/js/templates/docs/api-collections.html +347 -0
  6. package/admin/js/templates/docs/api-layouts.html +123 -0
  7. package/admin/js/templates/docs/api-media.html +158 -0
  8. package/admin/js/templates/docs/api-navigation.html +99 -0
  9. package/admin/js/templates/docs/api-pages.html +214 -0
  10. package/admin/js/templates/docs/api-plugins.html +136 -0
  11. package/admin/js/templates/docs/api-settings.html +148 -0
  12. package/admin/js/templates/docs/api-users.html +189 -0
  13. package/admin/js/templates/docs/api-views.html +142 -0
  14. package/admin/js/templates/docs/components-howto.html +175 -0
  15. package/admin/js/templates/docs/components-reference.html +259 -0
  16. package/admin/js/templates/docs/components-rules.html +167 -0
  17. package/admin/js/templates/docs/components-walkthrough.html +167 -0
  18. package/admin/js/templates/docs/tutorial-crud.html +344 -0
  19. package/admin/js/templates/docs/tutorial-forms.html +93 -0
  20. package/admin/js/templates/docs/tutorial-plugin.html +234 -0
  21. package/admin/js/templates/docs/usage-actions.html +122 -0
  22. package/admin/js/templates/docs/usage-cta-shortcode.html +124 -0
  23. package/admin/js/templates/docs/usage-dconfig.html +148 -0
  24. package/admin/js/templates/docs/usage-media.html +25 -0
  25. package/admin/js/templates/docs/usage-navigation.html +31 -0
  26. package/admin/js/templates/docs/usage-pages.html +68 -0
  27. package/admin/js/templates/docs/usage-plugins.html +36 -0
  28. package/admin/js/templates/docs/usage-shortcodes.html +810 -0
  29. package/admin/js/templates/docs/usage-site-settings.html +52 -0
  30. package/admin/js/templates/docs/usage-users-roles.html +84 -0
  31. package/admin/js/templates/docs/usage-views.html +105 -0
  32. package/admin/js/templates/documentation.html +60 -1522
  33. package/admin/js/templates/tutorials.html +46 -659
  34. package/admin/js/views/api-reference.js +1 -1
  35. package/admin/js/views/doc-pages.js +1 -0
  36. package/admin/js/views/documentation.js +1 -1
  37. package/admin/js/views/index.js +1 -1
  38. package/admin/js/views/tutorials.js +1 -1
  39. package/config/menus/admin-sidebar.json +76 -6
  40. package/package.json +1 -1
  41. package/server/server.js +3 -1
  42. package/server/services/sidebar-migration.js +145 -3
@@ -4,1531 +4,69 @@
4
4
 
5
5
  <div class="row">
6
6
  <div class="col-12">
7
+ <div class="docs-body">
8
+
9
+ <p class="lead">
10
+ Task-by-task reference for running a Domma CMS site. Pick a topic below — each opens as its own
11
+ page, and every topic is also listed under <strong>Documentation → Usage</strong> in the sidebar.
12
+ </p>
13
+
14
+ <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:1rem;margin-top:1.5rem;">
15
+
16
+ <a href="#/docs/usage/pages" class="card" style="text-decoration:none;display:block;">
17
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="file-text"></span> Pages</h3>
18
+ <p class="text-muted" style="margin-bottom:0;">Markdown pages, YAML frontmatter, and how files map to URLs.</p></div>
19
+ </a>
20
+ <a href="#/docs/usage/media" class="card" style="text-decoration:none;display:block;">
21
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="image"></span> Media</h3>
22
+ <p class="text-muted" style="margin-bottom:0;">Uploading files and using the media library.</p></div>
23
+ </a>
24
+ <a href="#/docs/usage/navigation" class="card" style="text-decoration:none;display:block;">
25
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="menu"></span> Navigation</h3>
26
+ <p class="text-muted" style="margin-bottom:0;">Menus, locations, and the multi-menu system.</p></div>
27
+ </a>
28
+ <a href="#/docs/usage/dconfig" class="card" style="text-decoration:none;display:block;">
29
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="settings"></span> DConfig</h3>
30
+ <p class="text-muted" style="margin-bottom:0;">Declarative, per-page configuration blocks.</p></div>
31
+ </a>
32
+ <a href="#/docs/usage/shortcodes" class="card" style="text-decoration:none;display:block;">
33
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="code"></span> Shortcodes</h3>
34
+ <p class="text-muted" style="margin-bottom:0;">The full catalogue of in-page shortcodes.</p></div>
35
+ </a>
36
+ <a href="#/docs/usage/site-settings" class="card" style="text-decoration:none;display:block;">
37
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="settings"></span> Site Settings</h3>
38
+ <p class="text-muted" style="margin-bottom:0;">Title, theme, brand, footer and SMTP.</p></div>
39
+ </a>
40
+ <a href="#/docs/usage/plugins" class="card" style="text-decoration:none;display:block;">
41
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="package"></span> Plugins</h3>
42
+ <p class="text-muted" style="margin-bottom:0;">Installing, enabling and configuring plugins.</p></div>
43
+ </a>
44
+ <a href="#/docs/usage/users-roles" class="card" style="text-decoration:none;display:block;">
45
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="users"></span> Users &amp; Roles</h3>
46
+ <p class="text-muted" style="margin-bottom:0;">Accounts, roles and the permission model.</p></div>
47
+ </a>
48
+ <a href="#/docs/usage/views" class="card" style="text-decoration:none;display:block;">
49
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="eye"></span> Views</h3>
50
+ <p class="text-muted" style="margin-bottom:0;">Saved, reusable views over your collections.</p></div>
51
+ </a>
52
+ <a href="#/docs/usage/actions" class="card" style="text-decoration:none;display:block;">
53
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="zap"></span> Actions</h3>
54
+ <p class="text-muted" style="margin-bottom:0;">Server-side workflow buttons and transitions.</p></div>
55
+ </a>
56
+ <a href="#/docs/usage/cta-shortcode" class="card" style="text-decoration:none;display:block;">
57
+ <div class="card-body"><h3 style="margin-top:0;"><span data-icon="zap"></span> CTA Shortcode</h3>
58
+ <p class="text-muted" style="margin-bottom:0;">Triggering collection actions from a page.</p></div>
59
+ </a>
7
60
 
8
- <div class="tabs" id="docs-tabs">
9
- <div class="tab-list" style="flex-wrap: wrap;">
10
- <button class="tab-item active">Pages</button>
11
- <button class="tab-item">Media</button>
12
- <button class="tab-item">Navigation</button>
13
- <button class="tab-item">DConfig</button>
14
- <button class="tab-item">Shortcodes</button>
15
- <button class="tab-item">Site Settings</button>
16
- <button class="tab-item">Plugins</button>
17
- <button class="tab-item">Users &amp; Roles</button>
18
- <button class="tab-item">Views</button>
19
- <button class="tab-item">Actions</button>
20
- <button class="tab-item">CTA Shortcode</button>
21
61
  </div>
22
- <div class="tab-content">
23
62
 
24
- <!-- Pages -->
25
- <div class="tab-panel active docs-body">
26
- <p>Pages are stored as Markdown files in <code>content/pages/</code>. Each file has a YAML frontmatter
27
- block at
28
- the top followed by the page body in Markdown.</p>
29
-
30
- <h3>URL mapping</h3>
31
- <table class="table table-sm">
32
- <thead>
33
- <tr>
34
- <th>File path</th>
35
- <th>Public URL</th>
36
- </tr>
37
- </thead>
38
- <tbody>
39
- <tr>
40
- <td><code>content/pages/index.md</code></td>
41
- <td><code>/</code></td>
42
- </tr>
43
- <tr>
44
- <td><code>content/pages/about.md</code></td>
45
- <td><code>/about</code></td>
46
- </tr>
47
- <tr>
48
- <td><code>content/pages/blog/index.md</code></td>
49
- <td><code>/blog</code></td>
50
- </tr>
51
- <tr>
52
- <td><code>content/pages/blog/hello-world.md</code></td>
53
- <td><code>/blog/hello-world</code></td>
54
- </tr>
55
- </tbody>
56
- </table>
57
-
58
- <h3>Frontmatter reference</h3>
59
- <pre class="code-block"><code>---
60
- title: My Page
61
- description: A short description for SEO meta tags.
62
- status: published # published | draft (draft pages return 404)
63
- layout: default # layout name from config/presets.json
64
- tags: [one, two] # optional taxonomy
65
- updatedAt: 2026-03-01 # auto-set on save
66
- ---
67
-
68
- # Page heading
69
-
70
- Your Markdown content goes here.</code></pre>
71
-
72
- <h3>Drafts</h3>
73
- <p>Pages with <code>status: draft</code> are never served on the public site — they return a 404.
74
- Toggle status
75
- in the Page Editor to publish.</p>
76
-
77
- <h3>Layouts</h3>
78
- <p>Layouts are defined in <code>config/presets.json</code> and apply CSS class wrappers around page
79
- content.
80
- Select a layout per-page in the editor, or change the default in Site Settings.</p>
81
- </div>
82
-
83
- <!-- Media -->
84
- <div class="tab-panel docs-body">
85
- <p>Media files are stored in <code>content/media/</code> and served publicly at <code>/media/{filename}</code>.
86
- </p>
87
-
88
- <h3>Using media in pages</h3>
89
- <p>Reference uploaded files by their public URL in Markdown:</p>
90
- <pre class="code-block"><code>![Alt text](/media/my-image.jpg)
91
-
92
- &lt;img src="/media/my-image.jpg" alt="Alt text"&gt;</code></pre>
93
-
94
- <h3>Upload limits</h3>
95
- <p>The maximum file size is configured in <code>config/server.json</code> under <code>uploads.maxFileSize</code>
96
- (bytes). Default is 10 MB.</p>
97
- </div>
98
-
99
- <!-- Navigation -->
100
- <div class="tab-panel docs-body">
101
- <p>The navigation tree is stored in <code>config/navigation.json</code> and injected into every public
102
- page as
103
- <code>window.__CMS_NAV__</code>.</p>
104
-
105
- <h3>Dropdowns</h3>
106
- <p>Nest items under a parent using the drag-and-drop tree in the Navigation editor. Child items are
107
- stored under
108
- the <code>items</code> key — the public navbar renders them as a dropdown.</p>
109
-
110
- <h3>External links</h3>
111
- <p>Set the URL to a full <code>https://</code> address to link outside the site. Leave blank for
112
- section
113
- headings.</p>
114
-
115
- <h3>Icons</h3>
116
- <p>Set the <code>icon</code> field to any registered icon name. Icons appear in the navbar link
117
- alongside the
118
- label.</p>
119
- </div>
120
-
121
- <!-- DConfig -->
122
- <div class="tab-panel docs-body">
123
- <p>DConfig lets you wire up declarative behaviour on any public page — no JavaScript required. Define
124
- event
125
- handlers and class toggles in JSON; the page runtime applies them automatically on load.</p>
126
-
127
- <p>DConfig can be set in two ways, and both are merged at runtime (inline shortcode wins on selector
128
- conflict):</p>
129
- <ul>
130
- <li><strong>Page editor</strong> — the <em>DConfig</em> collapsible section accepts a JSON blob
131
- stored in page
132
- frontmatter and injected as <code>window.__CMS_DCONFIG__</code>.
133
- </li>
134
- <li><strong>Inline shortcode</strong> — place one or more <code>[dconfig]…[/dconfig]</code> blocks
135
- directly in
136
- the page body Markdown.
137
- </li>
138
- </ul>
139
-
140
- <h3>Schema</h3>
141
- <pre class="code-block"><code>{
142
- "#selector": {
143
- "events": {
144
- "eventName": {
145
- "target": "#target-selector",
146
- "action": "value"
147
- }
148
- }
149
- }
150
- }</code></pre>
151
-
152
- <p>Multiple selectors and multiple event types can appear in a single config block.</p>
153
-
154
- <h3>Supported events</h3>
155
- <table class="table table-sm">
156
- <thead>
157
- <tr>
158
- <th>Event</th>
159
- <th>Description</th>
160
- </tr>
161
- </thead>
162
- <tbody>
163
- <tr>
164
- <td><code>click</code></td>
165
- <td>Fires when the selector element is clicked.</td>
166
- </tr>
167
- </tbody>
168
- </table>
169
-
170
- <h3>Supported actions</h3>
171
- <table class="table table-sm">
172
- <thead>
173
- <tr>
174
- <th>Action key</th>
175
- <th>Value type</th>
176
- <th>Description</th>
177
- </tr>
178
- </thead>
179
- <tbody>
180
- <tr>
181
- <td><code>toggleClass</code></td>
182
- <td><code>string</code></td>
183
- <td>Adds the class if absent, removes it if present, on the <code>target</code> element.
184
- Typical use:
185
- show/hide content with a <code>hidden</code> class.
186
- </td>
187
- </tr>
188
- </tbody>
189
- </table>
190
-
191
- <p><em>Additional actions (addClass, removeClass, setAttribute, scroll-to) are planned for future
192
- releases.</em></p>
193
-
194
- <h3>Targeting shortcode elements with <code>id</code></h3>
195
- <p>All shortcodes support an <code>id</code> attribute, which is written directly onto the generated
196
- element.
197
- Use this instead of raw HTML when you want DConfig to target a card, column, or grid:</p>
198
- <pre class="code-block"><code>[card id="my-panel" title="Hidden Details"]
199
- Content goes here.
200
- [/card]
201
-
202
- [dconfig]
203
- {
204
- "#my-btn": {
205
- "events": {
206
- "click": { "target": "#my-panel", "toggleClass": "hidden" }
207
- }
208
- }
209
- }
210
- [/dconfig]</code></pre>
211
- <p>Supported on: <code>[card]</code>, <code>[col]</code>, <code>[row]</code>, <code>[grid]</code>.</p>
212
-
213
- <h3>Using the <code>[dconfig]</code> shortcode</h3>
214
- <pre class="code-block"><code>[dconfig]
215
- {
216
- "#my-btn": {
217
- "events": {
218
- "click": { "target": "#my-panel", "toggleClass": "hidden" }
219
- }
220
- }
221
- }
222
- [/dconfig]
223
-
224
- &lt;button id="my-btn" class="btn btn-primary"&gt;Toggle&lt;/button&gt;
225
-
226
- &lt;div id="my-panel" class="card hidden"&gt;
227
- &lt;div class="card-body"&gt;Hidden content.&lt;/div&gt;
228
- &lt;/div&gt;</code></pre>
229
-
230
- <h3>Multiple selectors</h3>
231
- <p>Any number of selectors can appear in one block. Selectors are matched with
232
- <code>document.querySelector</code> — use IDs, classes, or attribute selectors.</p>
233
- <pre class="code-block"><code>[dconfig]
234
- {
235
- "#show-btn": {
236
- "events": {
237
- "click": { "target": "#panel", "toggleClass": "hidden" }
238
- }
239
- },
240
- "#hide-btn": {
241
- "events": {
242
- "click": { "target": "#panel", "toggleClass": "hidden" }
243
- }
244
- }
245
- }
246
- [/dconfig]</code></pre>
247
-
248
- <h3>Using the page editor DConfig section</h3>
249
- <p>The same JSON (without the shortcode tags) can be pasted directly into the <em>DConfig</em> card in
250
- the page
251
- editor. This is useful when the config should apply to the whole page without appearing in the
252
- body content.
253
- Inline <code>[dconfig]</code> shortcodes are applied last and will win on any shared selector key.
254
- </p>
255
-
256
- <p>See live demos on the <a href="/resources/interactive" target="_blank">Interactive Resources
257
- page</a>.</p>
258
- </div>
259
-
260
- <!-- Shortcodes -->
261
- <div class="tab-panel docs-body">
262
- <p>Shortcodes extend Markdown with layout components. They are processed server-side before Markdown
263
- rendering, so you can freely mix shortcodes and Markdown in the same page body.</p>
264
- <p><strong>Syntax:</strong> <code>[shortcode attribute="value"]</code> (self-closing: <code>[shortcode
265
- /]</code>) and <code>[/shortcode]</code> for paired tags.</p>
266
-
267
- <h3>Layout</h3>
268
- <table class="table table-sm">
269
- <thead>
270
- <tr>
271
- <th>Shortcode</th>
272
- <th>Description</th>
273
- </tr>
274
- </thead>
275
- <tbody>
276
- <tr>
277
- <td><code>[grid cols="N" gap="N"]...[/grid]</code></td>
278
- <td>CSS Grid container — N columns (1–12), optional gap (1–6)</td>
279
- </tr>
280
- <tr>
281
- <td><code>[row gap="N"]...[/row]</code></td>
282
- <td>Flexbox row — columns share width equally</td>
283
- </tr>
284
- <tr>
285
- <td><code>[col span="N"]...[/col]</code></td>
286
- <td>Column inside a grid or row; <code>span</code> sets column span</td>
287
- </tr>
288
- </tbody>
289
- </table>
290
-
291
- <h3>Components</h3>
292
- <table class="table table-sm">
293
- <thead>
294
- <tr>
295
- <th>Shortcode</th>
296
- <th>Description</th>
297
- </tr>
298
- </thead>
299
- <tbody>
300
- <tr>
301
- <td><code>[card title="..."]...[/card]</code></td>
302
- <td>Styled card. Supports 6 variants, ~44 gradients and 33 layouts — see the
303
- <strong>Cards</strong> subsection below.
304
- </td>
305
- </tr>
306
- <tr>
307
- <td><code>[tabs]...[/tabs]</code></td>
308
- <td>Tab group; use <code>[tab title="..."]...[/tab]</code> inside</td>
309
- </tr>
310
- <tr>
311
- <td><code>[accordion]...[/accordion]</code></td>
312
- <td>Accordion group; use <code>[item title="..."]...[/item]</code> inside</td>
313
- </tr>
314
- <tr>
315
- <td><code>[carousel]...[/carousel]</code></td>
316
- <td>Carousel; use <code>[slide]...[/slide]</code> inside</td>
317
- </tr>
318
- <tr>
319
- <td><code>[badge variant="success"]...[/badge]</code></td>
320
- <td>Inline badge; variants: primary, secondary, success, danger, warning, info</td>
321
- </tr>
322
- <tr>
323
- <td><code>[icon name="star" /]</code></td>
324
- <td>Inline Domma icon; optional <code>size</code> and <code>color</code></td>
325
- </tr>
326
- <tr>
327
- <td><code>[spacer size="16" /]</code></td>
328
- <td>Vertical whitespace block (px height)</td>
329
- </tr>
330
- <tr>
331
- <td><code>[timeline]...[/timeline]</code></td>
332
- <td>Progression timeline; use <code>[event title="..." date="..."
333
- status="..."]...[/event]</code> inside
334
- </td>
335
- </tr>
336
- <tr>
337
- <td><code>[countdown to="2026-12-31" /]</code></td>
338
- <td>Animated countdown to a date</td>
339
- </tr>
340
- </tbody>
341
- </table>
342
-
343
- <h3>Cards &mdash; variants, gradients &amp; layouts</h3>
344
- <p>The <code>[card]</code> shortcode is the most configurable component in the system. It has three
345
- layers you can mix freely: <strong>variant</strong> (the overall visual style), <strong>gradient</strong>
346
- (colour palette, used with <code>variant="gradient"</code> or any layout that accepts a gradient),
347
- and <strong>layout</strong> (the internal structure — header/body/footer, image position, sub-tags,
348
- etc.). Every layout accepts every variant, gradient and universal attribute listed below.</p>
349
- <pre><code>[card variant="gradient" gradient="ocean" layout="icon-top" icon="star" title="Fast"]
350
- Body content in **Markdown** is supported.
351
- [/card]</code></pre>
352
-
353
- <h4>Variants</h4>
354
- <table class="table table-sm">
355
- <thead>
356
- <tr>
357
- <th>Variant</th>
358
- <th>Description</th>
359
- </tr>
360
- </thead>
361
- <tbody>
362
- <tr>
363
- <td><code>clean</code></td>
364
- <td>Flat, minimal chrome &mdash; no border, subtle background</td>
365
- </tr>
366
- <tr>
367
- <td><code>gradient</code></td>
368
- <td>Coloured gradient background (see Gradients below). Pair with <code>gradient="name"</code>
369
- </td>
370
- </tr>
371
- <tr>
372
- <td><code>glass</code></td>
373
- <td>Frosted glass / backdrop-blur effect, translucent background</td>
374
- </tr>
375
- <tr>
376
- <td><code>accent</code></td>
377
- <td>Primary-colour accent border on the left edge</td>
378
- </tr>
379
- <tr>
380
- <td><code>dark</code></td>
381
- <td>Dark background with inverted text &mdash; good on light pages</td>
382
- </tr>
383
- <tr>
384
- <td><code>glow</code></td>
385
- <td>Subtle halo / outer glow effect</td>
386
- </tr>
387
- <tr>
388
- <td><code>primary</code></td>
389
- <td>Legacy alias &mdash; adds <code>card-primary</code> class for backwards compatibility</td>
390
- </tr>
391
- </tbody>
392
- </table>
393
-
394
- <h4>Built-in gradients</h4>
395
- <p>Shipped in <code>public/css/</code> &mdash; available on every install. Default when
396
- <code>gradient</code> is omitted: <code>indigo</code>.</p>
397
- <p><code>arctic</code>, <code>aurora</code>, <code>dusk</code>, <code>fire</code>, <code>forest</code>,
398
- <code>gold</code>, <code>indigo</code>, <code>lagoon</code>, <code>lime</code>,
399
- <code>midnight</code>, <code>ocean</code>, <code>rose</code>, <code>slate</code>,
400
- <code>sunset</code></p>
401
-
402
- <h4>Project-specific gradients</h4>
403
- <p>Defined in <code>content/custom.css</code> on this site only &mdash; fresh installs will not have
404
- these unless the CSS is copied over.</p>
405
- <p><strong>Single-tone:</strong> <code>purple</code>, <code>blue</code>, <code>green</code>,
406
- <code>night</code></p>
407
- <p><strong>Theme &middot; light pairs:</strong> <code>ocean-light</code>, <code>forest-light</code>,
408
- <code>sunset-light</code>, <code>royal-light</code>, <code>lemon-light</code>,
409
- <code>silver-light</code>, <code>charcoal-light</code>, <code>christmas-light</code>,
410
- <code>unicorn-light</code>, <code>dreamy-light</code>, <code>grayve-light</code>,
411
- <code>mint-light</code>, <code>wedding-light</code></p>
412
- <p><strong>Theme &middot; dark pairs:</strong> <code>ocean-dark</code>, <code>forest-dark</code>,
413
- <code>sunset-dark</code>, <code>royal-dark</code>, <code>lemon-dark</code>,
414
- <code>silver-dark</code>, <code>charcoal-dark</code>, <code>christmas-dark</code>,
415
- <code>unicorn-dark</code>, <code>dreamy-dark</code>, <code>grayve-dark</code>,
416
- <code>mint-dark</code>, <code>wedding-dark</code></p>
417
- <p class="text-muted"><small>Gradient names are not validated &mdash; a typo falls through to the
418
- default background with no warning. Use <code>/test-card-gradients</code> to preview every
419
- palette.</small></p>
420
-
421
- <h4>Universal attributes</h4>
422
- <p>These work on any layout and any variant.</p>
423
- <table class="table table-sm">
424
- <thead>
425
- <tr>
426
- <th>Attribute</th>
427
- <th>Values</th>
428
- <th>Purpose</th>
429
- </tr>
430
- </thead>
431
- <tbody>
432
- <tr>
433
- <td><code>title</code></td>
434
- <td>string</td>
435
- <td>Card heading (most layouts)</td>
436
- </tr>
437
- <tr>
438
- <td><code>subtitle</code></td>
439
- <td>string</td>
440
- <td>Secondary heading (many layouts re-use it as date / role / plan)</td>
441
- </tr>
442
- <tr>
443
- <td><code>icon</code></td>
444
- <td>icon name</td>
445
- <td>Domma icon (see Icons view)</td>
446
- </tr>
447
- <tr>
448
- <td><code>footer</code></td>
449
- <td>string</td>
450
- <td>Footer text (also used by <code>pricing</code> as the CTA label)</td>
451
- </tr>
452
- <tr>
453
- <td><code>image</code></td>
454
- <td>URL</td>
455
- <td>Background image for image / media layouts</td>
456
- </tr>
457
- <tr>
458
- <td><code>collapsible</code></td>
459
- <td><code>true</code></td>
460
- <td>Body toggles open/closed via click on the header</td>
461
- </tr>
462
- <tr>
463
- <td><code>hover</code></td>
464
- <td>boolean flag</td>
465
- <td>Raises the card on mouse-over</td>
466
- </tr>
467
- <tr>
468
- <td><code>borderless</code></td>
469
- <td>boolean flag</td>
470
- <td>Removes the card border</td>
471
- </tr>
472
- <tr>
473
- <td><code>shadow</code></td>
474
- <td><code>none</code> &middot; <code>md</code> &middot; <code>lg</code></td>
475
- <td>Drop-shadow depth</td>
476
- </tr>
477
- <tr>
478
- <td><code>rounded</code></td>
479
- <td><code>none</code> &middot; <code>sm</code> &middot; <code>lg</code> &middot;
480
- <code>full</code></td>
481
- <td>Corner radius</td>
482
- </tr>
483
- <tr>
484
- <td><code>padding</code></td>
485
- <td><code>compact</code> &middot; <code>spacious</code></td>
486
- <td>Internal spacing</td>
487
- </tr>
488
- <tr>
489
- <td><code>text-align</code></td>
490
- <td><code>center</code> &middot; <code>right</code></td>
491
- <td>Body text alignment (default left)</td>
492
- </tr>
493
- <tr>
494
- <td><code>font</code></td>
495
- <td><code>serif</code> &middot; <code>mono</code></td>
496
- <td>Override card typeface</td>
497
- </tr>
498
- <tr>
499
- <td><code>font-size</code></td>
500
- <td><code>sm</code> &middot; <code>lg</code> &middot; <code>xl</code></td>
501
- <td>Override card body text size</td>
502
- </tr>
503
- <tr>
504
- <td><code>class</code></td>
505
- <td>string</td>
506
- <td>Extra CSS classes appended to the root element</td>
507
- </tr>
508
- <tr>
509
- <td><code>id</code></td>
510
- <td>string</td>
511
- <td>DOM id (useful for anchor links / dconfig targets)</td>
512
- </tr>
513
- </tbody>
514
- </table>
515
-
516
- <h4>Layouts</h4>
517
- <p>Select a layout with <code>layout="name"</code>. If omitted, the card uses a simple body-only
518
- layout. Layouts marked <em>(needs sub-tags)</em> will render empty without their child tags.</p>
519
-
520
- <h5>Structural</h5>
521
- <table class="table table-sm">
522
- <thead>
523
- <tr>
524
- <th>Layout</th>
525
- <th>Attributes</th>
526
- <th>Purpose</th>
527
- </tr>
528
- </thead>
529
- <tbody>
530
- <tr>
531
- <td><code>basic</code></td>
532
- <td><code>footer</code></td>
533
- <td>Body-only card, optional footer</td>
534
- </tr>
535
- <tr>
536
- <td><code>header-body</code></td>
537
- <td><code>title</code></td>
538
- <td>Header with title + body</td>
539
- </tr>
540
- <tr>
541
- <td><code>header-body-footer</code></td>
542
- <td><code>title</code>, <code>footer</code></td>
543
- <td>Classic three-zone card</td>
544
- </tr>
545
- <tr>
546
- <td><code>no-header-footer</code></td>
547
- <td><code>footer</code></td>
548
- <td>Body + footer only</td>
549
- </tr>
550
- </tbody>
551
- </table>
552
-
553
- <h5>Icon headers</h5>
554
- <table class="table table-sm">
555
- <thead>
556
- <tr>
557
- <th>Layout</th>
558
- <th>Attributes</th>
559
- <th>Purpose</th>
560
- </tr>
561
- </thead>
562
- <tbody>
563
- <tr>
564
- <td><code>icon-top</code></td>
565
- <td><code>icon</code>, <code>title</code>, <code>subtitle</code></td>
566
- <td>Large centred icon above title &mdash; good for feature grids</td>
567
- </tr>
568
- <tr>
569
- <td><code>icon-inline</code></td>
570
- <td><code>icon</code>, <code>title</code>, <code>subtitle</code></td>
571
- <td>Icon sits to the left of the title in the header row</td>
572
- </tr>
573
- </tbody>
574
- </table>
575
-
576
- <h5>Image</h5>
577
- <table class="table table-sm">
578
- <thead>
579
- <tr>
580
- <th>Layout</th>
581
- <th>Attributes</th>
582
- <th>Purpose</th>
583
- </tr>
584
- </thead>
585
- <tbody>
586
- <tr>
587
- <td><code>image-top</code></td>
588
- <td><code>image</code>, <code>title</code></td>
589
- <td>Image banner above header + body</td>
590
- </tr>
591
- <tr>
592
- <td><code>image-overlay</code></td>
593
- <td><code>image</code>, <code>title</code></td>
594
- <td>Title overlaid on the image with a tint</td>
595
- </tr>
596
- <tr>
597
- <td><code>thumb-left</code></td>
598
- <td><code>image</code>, <code>title</code></td>
599
- <td>Square thumbnail on the left, body on the right</td>
600
- </tr>
601
- <tr>
602
- <td><code>thumb-right</code></td>
603
- <td><code>image</code>, <code>title</code></td>
604
- <td>Mirror of <code>thumb-left</code></td>
605
- </tr>
606
- <tr>
607
- <td><code>wide-left-image</code></td>
608
- <td><code>image</code>, <code>title</code>, <code>footer</code></td>
609
- <td>Horizontal card, wider image strip on the left</td>
610
- </tr>
611
- <tr>
612
- <td><code>full-bg</code></td>
613
- <td><code>image</code>, <code>title</code></td>
614
- <td>Full-bleed image backdrop with body text over it</td>
615
- </tr>
616
- <tr>
617
- <td><code>split-half</code></td>
618
- <td><code>image</code>, <code>gradient</code>, <code>title</code></td>
619
- <td>Half gradient (or image) on the left, content on the right</td>
620
- </tr>
621
- </tbody>
622
- </table>
623
-
624
- <h5>Media</h5>
625
- <table class="table table-sm">
626
- <thead>
627
- <tr>
628
- <th>Layout</th>
629
- <th>Attributes</th>
630
- <th>Purpose</th>
631
- </tr>
632
- </thead>
633
- <tbody>
634
- <tr>
635
- <td><code>video-media</code></td>
636
- <td><code>image</code> (poster), <code>duration</code>, <code>title</code></td>
637
- <td>Video thumbnail with a play button and duration badge</td>
638
- </tr>
639
- <tr>
640
- <td><code>location-map</code></td>
641
- <td><code>address</code>, <code>title</code></td>
642
- <td>Placeholder map panel + address block (static &mdash; no live map)</td>
643
- </tr>
644
- </tbody>
645
- </table>
646
-
647
- <h5>People &amp; social proof</h5>
648
- <table class="table table-sm">
649
- <thead>
650
- <tr>
651
- <th>Layout</th>
652
- <th>Attributes</th>
653
- <th>Purpose</th>
654
- </tr>
655
- </thead>
656
- <tbody>
657
- <tr>
658
- <td><code>avatar-profile</code></td>
659
- <td><code>icon</code>, <code>title</code>, <code>subtitle</code>,
660
- <code>tags</code> (comma-separated)
661
- </td>
662
- <td>Circular avatar + name + role + pill tags &mdash; team / author cards</td>
663
- </tr>
664
- <tr>
665
- <td><code>quote-testimonial</code></td>
666
- <td><code>title</code> (author), <code>subtitle</code> (role)</td>
667
- <td>Quotation mark + body quote + author attribution row</td>
668
- </tr>
669
- <tr>
670
- <td><code>rating-review</code></td>
671
- <td><code>rating</code> (0&ndash;5), <code>title</code>, <code>subtitle</code>,
672
- <code>verified</code> (flag)
673
- </td>
674
- <td>Star rating + review body + reviewer attribution</td>
675
- </tr>
676
- </tbody>
677
- </table>
678
-
679
- <h5>Metrics &amp; data</h5>
680
- <table class="table table-sm">
681
- <thead>
682
- <tr>
683
- <th>Layout</th>
684
- <th>Attributes</th>
685
- <th>Purpose</th>
686
- </tr>
687
- </thead>
688
- <tbody>
689
- <tr>
690
- <td><code>stat-metric</code></td>
691
- <td><code>title</code> (label), <code>value</code>, <code>delta</code>,
692
- <code>progress</code> (0&ndash;100)
693
- </td>
694
- <td>Big-number KPI tile with delta arrow and optional progress bar</td>
695
- </tr>
696
- <tr>
697
- <td><code>progress-goal</code> <em>(needs sub-tags)</em></td>
698
- <td><code>title</code>, <code>subtitle</code>, <code>progress</code>; child
699
- <code>[milestone done]...[/milestone]</code>
700
- </td>
701
- <td>Progress bar + milestone checklist</td>
702
- </tr>
703
- <tr>
704
- <td><code>activity-feed</code> <em>(needs sub-tags)</em></td>
705
- <td><code>title</code>; child
706
- <code>[activity user="..." action="..." time="..." /]</code>
707
- </td>
708
- <td>User activity list with initials avatars and timestamps</td>
709
- </tr>
710
- </tbody>
711
- </table>
712
-
713
- <h5>Markers &amp; callouts</h5>
714
- <table class="table table-sm">
715
- <thead>
716
- <tr>
717
- <th>Layout</th>
718
- <th>Attributes</th>
719
- <th>Purpose</th>
720
- </tr>
721
- </thead>
722
- <tbody>
723
- <tr>
724
- <td><code>callout</code></td>
725
- <td><code>callout-type</code> (<code>info</code>/<code>warn</code>/<code>success</code>/<code>error</code>),
726
- <code>icon</code>, <code>title</code>
727
- </td>
728
- <td>Coloured inline notice / tip box</td>
729
- </tr>
730
- <tr>
731
- <td><code>step-numbered</code></td>
732
- <td><code>step</code> (number), <code>title</code>, <code>gradient</code></td>
733
- <td>Numbered step for tutorials / walkthroughs</td>
734
- </tr>
735
- <tr>
736
- <td><code>corner-badge</code></td>
737
- <td><code>badge</code> (label), <code>icon</code>, <code>title</code></td>
738
- <td>Card with a ribbon-style badge in the top-right corner</td>
739
- </tr>
740
- <tr>
741
- <td><code>badge-band</code></td>
742
- <td><code>badge</code>, <code>icon</code>, <code>gradient</code>, <code>title</code></td>
743
- <td>Full-width coloured band across the top with a label and icon</td>
744
- </tr>
745
- <tr>
746
- <td><code>tag-cloud</code></td>
747
- <td><code>title</code>, <code>tags</code> (comma-separated)</td>
748
- <td>Coloured pill list &mdash; topic tags, skills, categories</td>
749
- </tr>
750
- <tr>
751
- <td><code>timeline-entry</code></td>
752
- <td><code>title</code>, <code>subtitle</code> (date), <code>badge</code> (tag)</td>
753
- <td>Single dot-on-line timeline entry &mdash; stack several for a history list</td>
754
- </tr>
755
- </tbody>
756
- </table>
757
-
758
- <h5>Commerce &amp; comparison</h5>
759
- <table class="table table-sm">
760
- <thead>
761
- <tr>
762
- <th>Layout</th>
763
- <th>Attributes &amp; sub-tags</th>
764
- <th>Purpose</th>
765
- </tr>
766
- </thead>
767
- <tbody>
768
- <tr>
769
- <td><code>pricing</code> <em>(needs sub-tags)</em></td>
770
- <td><code>title</code>, <code>price</code>, <code>period</code>, <code>gradient</code>,
771
- <code>footer</code> (CTA label); child <code>[feature]...[/feature]</code>
772
- </td>
773
- <td>Pricing tier card with gradient header, feature list and CTA link</td>
774
- </tr>
775
- <tr>
776
- <td><code>feature-comparison</code> <em>(needs sub-tags)</em></td>
777
- <td><code>title</code>, <code>subtitle</code> (plan), <code>gradient</code>; child
778
- <code>[feature]text[/feature]</code> or <code>[feature excluded]text[/feature]</code>
779
- </td>
780
- <td>Plan comparison rows with tick / cross marks</td>
781
- </tr>
782
- <tr>
783
- <td><code>before-after</code> <em>(needs sub-tags)</em></td>
784
- <td><code>title</code>; children
785
- <code>[before]item &middot; item[/before]</code> and
786
- <code>[after]item &middot; item[/after]</code> (items split on <code>&middot;</code> or
787
- newline)
788
- </td>
789
- <td>Two-column before/after comparison list</td>
790
- </tr>
791
- </tbody>
792
- </table>
793
-
794
- <h5>Special &amp; utility</h5>
795
- <table class="table table-sm">
796
- <thead>
797
- <tr>
798
- <th>Layout</th>
799
- <th>Attributes</th>
800
- <th>Purpose</th>
801
- </tr>
802
- </thead>
803
- <tbody>
804
- <tr>
805
- <td><code>glass-gradient-border</code></td>
806
- <td><code>title</code></td>
807
- <td>Frosted glass card with a gradient border ring. <strong>Note:</strong> this layout
808
- bypasses <code>cardVariantClasses</code>, so universal variant / gradient / shadow
809
- attributes do not apply.
810
- </td>
811
- </tr>
812
- <tr>
813
- <td><code>code-snippet</code></td>
814
- <td><code>lang</code> (label); body is rendered as escaped code</td>
815
- <td>Code block with language label header</td>
816
- </tr>
817
- <tr>
818
- <td><code>file-document</code></td>
819
- <td><code>filename</code>, <code>filesize</code>, <code>filetype</code>, <code>title</code>
820
- </td>
821
- <td>File attachment row with type icon and download link (link href is placeholder)</td>
822
- </tr>
823
- </tbody>
824
- </table>
825
-
826
- <h4>Sub-tag reference</h4>
827
- <p>These are child tags accepted by specific layouts &mdash; they are not shortcodes in their own right
828
- and only render inside a matching parent card.</p>
829
- <table class="table table-sm">
830
- <thead>
831
- <tr>
832
- <th>Sub-tag</th>
833
- <th>Parent layout</th>
834
- <th>Attributes</th>
835
- </tr>
836
- </thead>
837
- <tbody>
838
- <tr>
839
- <td><code>[feature]text[/feature]</code></td>
840
- <td><code>pricing</code>, <code>feature-comparison</code></td>
841
- <td><code>excluded</code> (flag, comparison only) &mdash; renders as a cross instead of a tick
842
- </td>
843
- </tr>
844
- <tr>
845
- <td><code>[before]a &middot; b &middot; c[/before]</code></td>
846
- <td><code>before-after</code></td>
847
- <td>Items split on <code>&middot;</code> or newline</td>
848
- </tr>
849
- <tr>
850
- <td><code>[after]a &middot; b &middot; c[/after]</code></td>
851
- <td><code>before-after</code></td>
852
- <td>Items split on <code>&middot;</code> or newline</td>
853
- </tr>
854
- <tr>
855
- <td><code>[activity user="..." action="..." time="..." /]</code></td>
856
- <td><code>activity-feed</code></td>
857
- <td>Self-closing; one row per tag</td>
858
- </tr>
859
- <tr>
860
- <td><code>[milestone done]text[/milestone]</code></td>
861
- <td><code>progress-goal</code></td>
862
- <td><code>done</code> (flag) &mdash; filled dot if present, hollow otherwise</td>
863
- </tr>
864
- </tbody>
865
- </table>
866
-
867
- <h3>Content</h3>
868
- <table class="table table-sm">
869
- <thead>
870
- <tr>
871
- <th>Shortcode</th>
872
- <th>Description</th>
873
- </tr>
874
- </thead>
875
- <tbody>
876
- <tr>
877
- <td><code>[hero variant="dark" size="sm"]...[/hero]</code></td>
878
- <td>Full-width hero section; supports <code>twinkle</code>, <code>blobs</code>,
879
- <code>image</code>, <code>overlay</code></td>
880
- </tr>
881
- <tr>
882
- <td><code>[table striped="true"]...[/table]</code></td>
883
- <td>Wraps a GFM Markdown table with Domma table CSS classes</td>
884
- </tr>
885
- <tr>
886
- <td><code>[form name="slug" /]</code></td>
887
- <td>Embeds a Form Builder form by slug</td>
888
- </tr>
889
- <tr>
890
- <td><code>[collection slug="..." display="table" /]</code></td>
891
- <td>Renders collection entries inline (table, cards, list, accordion, or block)</td>
892
- </tr>
893
- </tbody>
894
- </table>
895
-
896
- <h4>Collection attributes</h4>
897
- <table class="table table-sm">
898
- <thead>
899
- <tr>
900
- <th>Attribute</th>
901
- <th>Values</th>
902
- <th>Purpose</th>
903
- </tr>
904
- </thead>
905
- <tbody>
906
- <tr>
907
- <td><code>slug</code></td>
908
- <td>collection slug</td>
909
- <td>Required. Which collection to render.</td>
910
- </tr>
911
- <tr>
912
- <td><code>display</code></td>
913
- <td><code>table</code> &middot; <code>cards</code> &middot; <code>list</code> &middot;
914
- <code>accordion</code> &middot; <code>block</code></td>
915
- <td>How to render each entry. Default <code>table</code>.</td>
916
- </tr>
917
- <tr>
918
- <td><code>block</code></td>
919
- <td>block template name</td>
920
- <td>Required when <code>display="block"</code>. Names a template in
921
- <code>content/blocks/&lt;name&gt;.html</code> whose
922
- <code>{{field}}</code> placeholders get substituted per entry.
923
- </td>
924
- </tr>
925
- <tr>
926
- <td><code>cols</code></td>
927
- <td><code>2</code> &middot; <code>3</code> &middot; <code>4</code> &middot; <code>5</code>
928
- &middot; <code>6</code></td>
929
- <td>Grid column count when <code>display="block"</code>.</td>
930
- </tr>
931
- <tr>
932
- <td><code>where</code></td>
933
- <td><code>field=value</code> or<br><code>f1=v1,f2=v2</code></td>
934
- <td>Row filter (simple equality only, AND'd across comma-separated predicates). Example:
935
- <code>where="tab=developers"</code> or
936
- <code>where="tier=free,featured=true"</code>. No OR, no comparison operators &mdash;
937
- use a saved View for anything more complex.
938
- </td>
939
- </tr>
940
- <tr>
941
- <td><code>sort</code></td>
942
- <td>field name or <code>createdAt</code></td>
943
- <td>Sort field. Default <code>createdAt</code>.</td>
944
- </tr>
945
- <tr>
946
- <td><code>order</code></td>
947
- <td><code>asc</code> &middot; <code>desc</code></td>
948
- <td>Sort direction. Default <code>desc</code>.</td>
949
- </tr>
950
- <tr>
951
- <td><code>limit</code></td>
952
- <td>integer</td>
953
- <td>Maximum number of entries to render. 0 or omitted = all.</td>
954
- </tr>
955
- <tr>
956
- <td><code>fields</code></td>
957
- <td>comma-separated field names</td>
958
- <td>Column filter &mdash; only these fields are shown (table/cards/list displays only).
959
- </td>
960
- </tr>
961
- <tr>
962
- <td><code>title-field</code></td>
963
- <td>field name</td>
964
- <td>Which field to use as the entry title (cards/accordion displays).</td>
965
- </tr>
966
- <tr>
967
- <td><code>empty</code></td>
968
- <td>string</td>
969
- <td>Message shown when the filter matches no entries.</td>
970
- </tr>
971
- <tr>
972
- <td><code>cta</code></td>
973
- <td>action slug</td>
974
- <td>Attach a CMS Action button to each rendered entry. See CTA attributes below.</td>
975
- </tr>
976
- </tbody>
977
- </table>
978
-
979
- <h3>Form follow-up</h3>
980
- <p>Two optional settings control what happens after a submission is stored:</p>
981
- <table class="table" style="font-size:.9rem;">
982
- <thead>
983
- <tr>
984
- <th>Field</th>
985
- <th>Where</th>
986
- <th>Description</th>
987
- </tr>
988
- </thead>
989
- <tbody>
990
- <tr>
991
- <td><code>successMessage</code></td>
992
- <td>Settings tab</td>
993
- <td>Text shown inline after submission (replaces the form). Default: "Thank you for your
994
- submission."
995
- </td>
996
- </tr>
997
- <tr>
998
- <td><code>successRedirect</code></td>
999
- <td>Settings tab</td>
1000
- <td>URL to redirect the visitor on success. Takes priority over <code>successMessage</code> if
1001
- set.
1002
- </td>
1003
- </tr>
1004
- <tr>
1005
- <td><code>actionSlug</code></td>
1006
- <td>Actions tab → CMS Action</td>
1007
- <td>Slug of a CMS Action to execute after the entry is stored. Requires Pro (MongoDB).
1008
- Non-fatal on failure.
1009
- </td>
1010
- </tr>
1011
- </tbody>
1012
- </table>
1013
- <p>For the full walkthrough, see the
1014
- <a href="#/tutorials">Tutorials → Form Follow-Up: Notifications &amp; Actions</a> tutorial.</p>
1015
-
1016
- <h3>Interactive</h3>
1017
- <table class="table table-sm">
1018
- <thead>
1019
- <tr>
1020
- <th>Shortcode</th>
1021
- <th>Description</th>
1022
- </tr>
1023
- </thead>
1024
- <tbody>
1025
- <tr>
1026
- <td><code>[slideover title="..." trigger="..."]...[/slideover]</code></td>
1027
- <td>Slide-in panel opened by a trigger button</td>
1028
- </tr>
1029
- <tr>
1030
- <td><code>[dconfig]{...}[/dconfig]</code></td>
1031
- <td>Declarative click handlers and class toggles — no JavaScript needed</td>
1032
- </tr>
1033
- </tbody>
1034
- </table>
1035
-
1036
- <h3>Pro shortcodes</h3>
1037
- <table class="table table-sm">
1038
- <thead>
1039
- <tr>
1040
- <th>Shortcode</th>
1041
- <th>Description</th>
1042
- </tr>
1043
- </thead>
1044
- <tbody>
1045
- <tr>
1046
- <td><code>[view slug="..." display="table" /]</code></td>
1047
- <td>Executes a saved View and renders results. Requires MongoDB.</td>
1048
- </tr>
1049
- <tr>
1050
- <td><code>[cta action="..." entry="..."]Label[/cta]</code></td>
1051
- <td>Action-trigger button. Requires the visitor to be logged in.</td>
1052
- </tr>
1053
- </tbody>
1054
- </table>
1055
-
1056
- <p>Full attribute reference and live demos: <a href="/resources/shortcodes" target="_blank">Shortcode
1057
- Reference</a> · <a href="/resources/components" target="_blank">Components</a> · <a
1058
- href="/resources/effects" target="_blank">Effects</a></p>
1059
- </div>
1060
-
1061
- <!-- Site Settings -->
1062
- <div class="tab-panel docs-body">
1063
- <p>Site Settings are stored in <code>config/site.json</code> and editable from the Settings page in
1064
- the admin
1065
- panel.</p>
1066
-
1067
- <table class="table table-sm">
1068
- <thead>
1069
- <tr>
1070
- <th>Field</th>
1071
- <th>Description</th>
1072
- </tr>
1073
- </thead>
1074
- <tbody>
1075
- <tr>
1076
- <td><code>siteName</code></td>
1077
- <td>Site title used in the public navbar and browser tab.</td>
1078
- </tr>
1079
- <tr>
1080
- <td><code>tagline</code></td>
1081
- <td>Subtitle shown in the public site footer.</td>
1082
- </tr>
1083
- <tr>
1084
- <td><code>adminTheme</code></td>
1085
- <td>Admin panel colour theme (e.g. <code>charcoal-dark</code>, <code>ocean-light</code>).</td>
1086
- </tr>
1087
- <tr>
1088
- <td><code>publicTheme</code></td>
1089
- <td>Public site theme applied to <code>&lt;html data-theme&gt;</code>.</td>
1090
- </tr>
1091
- <tr>
1092
- <td><code>defaultLayout</code></td>
1093
- <td>Fallback layout for pages that don't specify one.</td>
1094
- </tr>
1095
- </tbody>
1096
- </table>
1097
-
1098
- <h3>Server configuration</h3>
1099
- <p>Low-level settings (port, CORS, upload size) live in <code>config/server.json</code> and require a
1100
- server
1101
- restart to take effect. These are not editable from the admin panel.</p>
1102
- </div>
1103
-
1104
- <!-- Plugins -->
1105
- <div class="tab-panel docs-body">
1106
- <p>Plugins extend the CMS with new server routes, admin views, and public-site injection snippets.
1107
- Each plugin
1108
- is a directory under <code>plugins/</code>.</p>
1109
-
1110
- <h3>Enabling and disabling</h3>
1111
- <p>Use the Plugins page in the admin to toggle plugins on or off. State is saved to
1112
- <code>config/plugins.json</code>. <strong>A server restart is required for changes to take
1113
- effect.</strong>
1114
- </p>
1115
-
1116
- <h3>Plugin settings</h3>
1117
- <p>Plugins that expose a settings page will appear as a link in the sidebar under the Plugins section.
1118
- Settings
1119
- are merged with the plugin's defaults from <code>config.js</code> and saved to
1120
- <code>config/plugins.json</code>.</p>
1121
-
1122
- <h3>Security</h3>
1123
- <p>Only files inside a plugin's <code>admin/</code> and <code>public/</code> subdirectories are served
1124
- statically. Server files (<code>plugin.js</code>, <code>config.js</code>, <code>data/</code>) are
1125
- blocked and
1126
- return 404.</p>
1127
-
1128
- <p>See the <a href="#/tutorials">Tutorials</a> section for a guide to writing your own plugin.</p>
1129
- </div>
1130
-
1131
- <!-- Users & Roles -->
1132
- <div class="tab-panel docs-body">
1133
- <p>Users are stored as individual JSON files in <code>content/users/</code>. Passwords are hashed with
1134
- bcrypt
1135
- and never returned by the API.</p>
1136
-
1137
- <h3>Roles</h3>
1138
- <table class="table table-sm">
1139
- <thead>
1140
- <tr>
1141
- <th>Role</th>
1142
- <th>Access</th>
1143
- </tr>
1144
- </thead>
1145
- <tbody>
1146
- <tr>
1147
- <td><strong>Admin</strong></td>
1148
- <td>Full access — users, plugins, settings, all content.</td>
1149
- </tr>
1150
- <tr>
1151
- <td><strong>Manager</strong></td>
1152
- <td>Content + structure (navigation, layouts). No users or plugins.</td>
1153
- </tr>
1154
- <tr>
1155
- <td><strong>Editor</strong></td>
1156
- <td>Pages and media only.</td>
1157
- </tr>
1158
- <tr>
1159
- <td><strong>Subscriber</strong></td>
1160
- <td>Read-only access to the API.</td>
1161
- </tr>
1162
- </tbody>
1163
- </table>
1164
-
1165
- <h3>Authentication</h3>
1166
- <p>The admin panel uses JWT Bearer tokens. Tokens are stored in the browser and automatically
1167
- refreshed.
1168
- Sessions expire according to <code>config/auth.json</code> — default is 24 hours.</p>
1169
-
1170
- <h3>Views &amp; Actions</h3>
1171
- <p>Views and Actions are pro-only features that require a MongoDB connection.
1172
- Both roles — Admin and Manager — can create, edit, and run Views and Actions.</p>
1173
- <table class="table table-sm">
1174
- <thead>
1175
- <tr>
1176
- <th>Role</th>
1177
- <th>Views</th>
1178
- <th>Actions</th>
1179
- </tr>
1180
- </thead>
1181
- <tbody>
1182
- <tr>
1183
- <td><strong>Admin</strong></td>
1184
- <td>Full access</td>
1185
- <td>Full access</td>
1186
- </tr>
1187
- <tr>
1188
- <td><strong>Manager</strong></td>
1189
- <td>Full access</td>
1190
- <td>Full access</td>
1191
- </tr>
1192
- <tr>
1193
- <td><strong>Editor</strong></td>
1194
- <td>No access</td>
1195
- <td>No access</td>
1196
- </tr>
1197
- <tr>
1198
- <td><strong>Subscriber</strong></td>
1199
- <td>No access</td>
1200
- <td>No access</td>
1201
- </tr>
1202
- </tbody>
1203
- </table>
1204
- </div>
1205
-
1206
- <!-- Views -->
1207
- <div class="tab-panel docs-body">
1208
- <p>Views are admin-designed display configurations that query one or more Collections via a stored
1209
- MongoDB aggregation pipeline, then render the results in the admin panel.
1210
- Views require a MongoDB connection configured under <strong>Collections → Options</strong>.</p>
1211
-
1212
- <h3>Creating a View</h3>
1213
- <ol>
1214
- <li>Navigate to <strong>Data → Views</strong> and click <strong>New View</strong>.</li>
1215
- <li><strong>Source tab</strong> — enter a title, choose the primary source collection, and select
1216
- the MongoDB connection.
1217
- </li>
1218
- <li><strong>Pipeline tab</strong> — add aggregation stages in order. Each stage has a type and a
1219
- JSON config object.
1220
- </li>
1221
- <li><strong>Display tab</strong> — choose table or list mode, set page size, and optionally define
1222
- column definitions.
1223
- </li>
1224
- <li><strong>Access tab</strong> — select which roles can access this view and whether it is
1225
- publicly accessible.
1226
- </li>
1227
- <li>Click <strong>Save View</strong>, then use <strong>Preview</strong> to execute and inspect the
1228
- results.
1229
- </li>
1230
- </ol>
1231
-
1232
- <h3>Allowed Pipeline Stage Types</h3>
1233
- <table class="table table-sm">
1234
- <thead>
1235
- <tr>
1236
- <th>Stage</th>
1237
- <th>Purpose</th>
1238
- </tr>
1239
- </thead>
1240
- <tbody>
1241
- <tr>
1242
- <td><code>$match</code></td>
1243
- <td>Filter documents by condition</td>
1244
- </tr>
1245
- <tr>
1246
- <td><code>$lookup</code></td>
1247
- <td>Left join from another collection</td>
1248
- </tr>
1249
- <tr>
1250
- <td><code>$sort</code></td>
1251
- <td>Sort documents</td>
1252
- </tr>
1253
- <tr>
1254
- <td><code>$project</code></td>
1255
- <td>Include or exclude fields</td>
1256
- </tr>
1257
- <tr>
1258
- <td><code>$unwind</code></td>
1259
- <td>Deconstruct an array field</td>
1260
- </tr>
1261
- <tr>
1262
- <td><code>$addFields</code></td>
1263
- <td>Compute and add new fields</td>
1264
- </tr>
1265
- <tr>
1266
- <td><code>$group</code></td>
1267
- <td>Group and aggregate</td>
1268
- </tr>
1269
- <tr>
1270
- <td><code>$count</code></td>
1271
- <td>Count documents</td>
1272
- </tr>
1273
- <tr>
1274
- <td><code>$skip</code></td>
1275
- <td>Skip documents (added automatically for pagination)</td>
1276
- </tr>
1277
- <tr>
1278
- <td><code>$limit</code></td>
1279
- <td>Limit documents (added automatically for pagination)</td>
1280
- </tr>
1281
- </tbody>
1282
- </table>
1283
- <p>Forbidden stages (<code>$out</code>, <code>$merge</code>, <code>$function</code>, <code>$accumulator</code>,
1284
- <code>$graphLookup</code>) are rejected at save and execution time.</p>
1285
-
1286
- <h3>Column Definitions</h3>
1287
- <p>On the Display tab, column definitions are a JSON array. Each object has a <code>key</code>
1288
- (dot-path into the result document) and a <code>label</code>.</p>
1289
- <pre class="code-block"><code>[
1290
- { "key": "data.name", "label": "Name" },
1291
- { "key": "data.email", "label": "Email" },
1292
- { "key": "orders", "label": "Orders" }
1293
- ]</code></pre>
1294
- <p>If no columns are defined, the preview auto-generates columns from the first result document.</p>
1295
-
1296
- <h3>Public Access</h3>
1297
- <p>Tick <strong>Public</strong> on the Access tab to expose the view via
1298
- <code>GET /api/views/:slug/public</code> without requiring a login.
1299
- Leave it unticked to require JWT authentication with one of the allowed roles.</p>
1300
- </div>
1301
-
1302
- <!-- Actions -->
1303
- <div class="tab-panel docs-body">
1304
- <p>Actions are admin-designed sequential workflow operations triggered against individual collection
1305
- entries. When an action is assigned to a collection, a trigger button appears per row in the
1306
- entry list. Actions require a MongoDB connection (pro mode).</p>
1307
-
1308
- <h3>Creating an Action</h3>
1309
- <ol>
1310
- <li>Navigate to <strong>Data → Actions</strong> and click <strong>New Action</strong>.</li>
1311
- <li><strong>General tab</strong> — enter a title and select the target collection.</li>
1312
- <li><strong>Trigger tab</strong> — configure the button label, icon, and optional confirmation
1313
- message.
1314
- </li>
1315
- <li><strong>Steps tab</strong> — add steps in order. Each step runs sequentially; if one fails the
1316
- action stops.
1317
- </li>
1318
- <li><strong>Access tab</strong> — select which roles can trigger this action.</li>
1319
- <li>Click <strong>Save Action</strong>. The button will appear on the collection's entry list.
1320
- </li>
1321
- </ol>
1322
-
1323
- <h3>Phase 1 Step Types</h3>
1324
- <table class="table table-sm">
1325
- <thead>
1326
- <tr>
1327
- <th>Step</th>
1328
- <th>What it does</th>
1329
- <th>Config fields</th>
1330
- </tr>
1331
- </thead>
1332
- <tbody>
1333
- <tr>
1334
- <td><code>updateField</code></td>
1335
- <td>Set a field on the entry to a new value</td>
1336
- <td><code>field</code>, <code>value</code></td>
1337
- </tr>
1338
- <tr>
1339
- <td><code>deleteEntry</code></td>
1340
- <td>Permanently delete the entry</td>
1341
- <td>None</td>
1342
- </tr>
1343
- <tr>
1344
- <td><code>moveToCollection</code></td>
1345
- <td>Create the entry in a target collection then delete it from the source</td>
1346
- <td><code>targetCollection</code></td>
1347
- </tr>
1348
- <tr>
1349
- <td><code>webhook</code></td>
1350
- <td>HTTP request to an external URL</td>
1351
- <td><code>url</code>, <code>method</code>, <code>body</code> (JSON)</td>
1352
- </tr>
1353
- <tr>
1354
- <td><code>email</code></td>
1355
- <td>Send an email via the configured SMTP transport</td>
1356
- <td><code>to</code>, <code>subject</code>, <code>template</code></td>
1357
- </tr>
1358
- </tbody>
1359
- </table>
1360
-
1361
- <h3>Template Variables</h3>
1362
- <p>Step config fields support <code>{{variable}}</code> interpolation:</p>
1363
- <table class="table table-sm">
1364
- <thead>
1365
- <tr>
1366
- <th>Variable</th>
1367
- <th>Resolves to</th>
1368
- </tr>
1369
- </thead>
1370
- <tbody>
1371
- <tr>
1372
- <td><code>{{entry.data.fieldName}}</code></td>
1373
- <td>A field value from the current entry</td>
1374
- </tr>
1375
- <tr>
1376
- <td><code>{{entry.id}}</code></td>
1377
- <td>The entry's ID</td>
1378
- </tr>
1379
- <tr>
1380
- <td><code>{{now}}</code></td>
1381
- <td>Current timestamp (ISO 8601)</td>
1382
- </tr>
1383
- <tr>
1384
- <td><code>{{user.name}}</code></td>
1385
- <td>Name of the user who triggered the action</td>
1386
- </tr>
1387
- <tr>
1388
- <td><code>{{user.email}}</code></td>
1389
- <td>Email of the triggering user</td>
1390
- </tr>
1391
- <tr>
1392
- <td><code>{{env.CMS_PUBLIC_*}}</code></td>
1393
- <td>Environment variables prefixed <code>CMS_PUBLIC_</code> only</td>
1394
- </tr>
1395
- </tbody>
1396
- </table>
1397
- <p><strong>Example</strong> — approve an application and notify by email:</p>
1398
- <pre class="code-block"><code>Step 1: updateField field=status value=approved
1399
- Step 2: updateField field=approvedAt value={{now}}
1400
- Step 3: email to={{entry.data.email}}
1401
- subject=Your application has been approved
1402
- template=Congratulations {{entry.data.name}}, your application is approved.</code></pre>
1403
-
1404
- <h3>Partial Execution</h3>
1405
- <p>Actions are <strong>not transactional</strong>. If a step fails, the action stops and returns the
1406
- number of steps completed so far (<code>stepsCompleted</code>). Steps that already ran are
1407
- <strong>not rolled back</strong>. Design step order with this in mind — put irreversible steps
1408
- (delete, email) last.</p>
1409
-
1410
- <h3>After a deleteEntry step</h3>
1411
- <p>If an action contains a <code>deleteEntry</code> step, subsequent steps will fail because the entry
1412
- no longer exists. Place <code>deleteEntry</code> as the last step.</p>
1413
- </div>
1414
-
1415
- <!-- CTA Shortcode -->
1416
- <div class="tab-panel docs-body">
1417
- <p>The <code>[cta]</code> shortcode places an action-trigger button in any public page. Clicking it
1418
- calls
1419
- <code>POST /api/actions/:slug/public</code> with the entry ID, using the logged-in user's JWT.
1420
- If the user is not logged in, a warning toast is shown instead.</p>
1421
-
1422
- <h3>Syntax &amp; Attributes</h3>
1423
- <p><strong>Wrapping form:</strong></p>
1424
- <pre class="code-block"><code>[cta action="slug" entry="entry-id" icon="check" confirm="Are you sure?"]Button label[/cta]</code></pre>
1425
- <p><strong>Self-closing form:</strong></p>
1426
- <pre class="code-block"><code>[cta action="slug" entry="entry-id" label="Button label" /]</code></pre>
1427
- <table class="table table-sm" style="margin-top:1rem;">
1428
- <thead>
1429
- <tr>
1430
- <th>Attribute</th>
1431
- <th>Required</th>
1432
- <th>Default</th>
1433
- <th>Description</th>
1434
- </tr>
1435
- </thead>
1436
- <tbody>
1437
- <tr>
1438
- <td><code>action</code></td>
1439
- <td>Yes</td>
1440
- <td>—</td>
1441
- <td>Action slug</td>
1442
- </tr>
1443
- <tr>
1444
- <td><code>entry</code></td>
1445
- <td>Yes</td>
1446
- <td>—</td>
1447
- <td>Entry UUID to act on</td>
1448
- </tr>
1449
- <tr>
1450
- <td><code>label</code></td>
1451
- <td>No</td>
1452
- <td><code>"Run"</code></td>
1453
- <td>Button text (self-closing only)</td>
1454
- </tr>
1455
- <tr>
1456
- <td><code>style</code></td>
1457
- <td>No</td>
1458
- <td><code>"primary"</code></td>
1459
- <td>primary · secondary · ghost · danger</td>
1460
- </tr>
1461
- <tr>
1462
- <td><code>icon</code></td>
1463
- <td>No</td>
1464
- <td>—</td>
1465
- <td>Domma icon name</td>
1466
- </tr>
1467
- <tr>
1468
- <td><code>size</code></td>
1469
- <td>No</td>
1470
- <td>—</td>
1471
- <td>sm · md · lg</td>
1472
- </tr>
1473
- <tr>
1474
- <td><code>confirm</code></td>
1475
- <td>No</td>
1476
- <td>—</td>
1477
- <td>Confirmation prompt before executing</td>
1478
- </tr>
1479
- </tbody>
1480
- </table>
1481
-
1482
- <h3>Collection Integration</h3>
1483
- <p>Add per-entry buttons to any <code>[collection]</code> shortcode:</p>
1484
- <pre class="code-block"><code>[collection slug="applications" display="cards" title-field="name"
1485
- cta="approve-application"
1486
- cta-label="Approve"
1487
- cta-icon="check"
1488
- cta-style="primary"
1489
- cta-confirm="Approve this application?" /]</code></pre>
1490
- <table class="table table-sm" style="margin-top:1rem;">
1491
- <thead>
1492
- <tr>
1493
- <th>Attribute</th>
1494
- <th>Default</th>
1495
- <th>Description</th>
1496
- </tr>
1497
- </thead>
1498
- <tbody>
1499
- <tr>
1500
- <td><code>cta</code></td>
1501
- <td>—</td>
1502
- <td>Action slug — enables per-entry buttons</td>
1503
- </tr>
1504
- <tr>
1505
- <td><code>cta-label</code></td>
1506
- <td><code>"Run"</code></td>
1507
- <td>Button label</td>
1508
- </tr>
1509
- <tr>
1510
- <td><code>cta-icon</code></td>
1511
- <td>—</td>
1512
- <td>Domma icon name</td>
1513
- </tr>
1514
- <tr>
1515
- <td><code>cta-style</code></td>
1516
- <td><code>"primary"</code></td>
1517
- <td>Button variant</td>
1518
- </tr>
1519
- <tr>
1520
- <td><code>cta-confirm</code></td>
1521
- <td>—</td>
1522
- <td>Confirmation prompt</td>
1523
- </tr>
1524
- </tbody>
1525
- </table>
1526
- <p>All three display modes support CTA buttons: <strong>cards</strong> (card footer),
1527
- <strong>list</strong> (inline), <strong>table</strong> (dedicated column).</p>
1528
- </div>
1529
-
1530
- </div>
1531
- </div>
63
+ <hr style="margin-top:2rem;">
64
+ <p class="text-muted" style="font-size:.9rem;">
65
+ New to the CMS? Start with the <a href="#/tutorials">Tutorials</a>. Building reusable elements?
66
+ See <a href="#/docs/components">Components</a>. Integrating externally? See the
67
+ <a href="#/api-reference">API Reference</a>.
68
+ </p>
1532
69
 
70
+ </div>
1533
71
  </div>
1534
72
  </div>