@port60/template-kit 0.20.4 → 1.0.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/README.md +42 -3
- package/bin/cli.mjs +10 -0
- package/package.json +4 -2
- package/src/commands/content.mjs +4 -3
- package/src/commands/create.mjs +11 -3
- package/src/commands/dev.mjs +9 -3
- package/src/commands/model.mjs +3 -3
- package/src/commands/packageCmd.mjs +1 -1
- package/src/commands/publish.mjs +1 -1
- package/src/commands/refresh.mjs +8 -3
- package/src/commands/release.mjs +22 -0
- package/src/commands/setupPreviews.mjs +19 -0
- package/src/commands/validate.mjs +1 -1
- package/src/lib/agentsMd.mjs +108 -155
- package/src/lib/designer-bridge.js +26 -0
- package/src/lib/designerPalette.mjs +62 -0
- package/src/lib/galleryPosters.mjs +105 -0
- package/src/lib/previewOptions.mjs +1 -1
- package/src/lib/releaseBundle.mjs +141 -0
- package/src/vendor/contract/v1/context.json +1 -1
- package/src/vendor/contract/v1/manifest.schema.json +6 -0
- package/src/vendor/contract/v2/behaviours.json +346 -0
- package/src/vendor/contract/v2/content-bounds.json +117 -0
- package/src/vendor/contract/v2/content-model.json +766 -0
- package/src/vendor/contract/v2/context.json +1569 -0
- package/src/vendor/contract/v2/dialect.json +105 -0
- package/src/vendor/contract/v2/fonts.json +910 -0
- package/src/vendor/contract/v2/imagery.json +32 -0
- package/src/vendor/contract/v2/islands.json +263 -0
- package/src/vendor/contract/v2/layout.json +28 -0
- package/src/vendor/contract/v2/manifest.schema.json +388 -0
- package/src/vendor/contract/v2/sections.json +947 -0
- package/src/vendor/contract/v2/site.schema.json +1353 -0
- package/src/vendor/contract/v2/tokens.json +101 -0
- package/src/vendor/contract/v2.lock.json +6931 -0
- package/src/vendor/engine/content-footprint.mjs +76 -1
- package/src/vendor/engine/majors.mjs +42 -0
- package/src/vendor/validator/gift-aid-logo.svg +6 -0
- package/src/vendor/validator/model-reference-v2.mjs +95 -0
- package/src/vendor/validator/platform-base.css +359 -2
- package/src/vendor/validator/preview-v1.mjs +691 -0
- package/src/vendor/validator/preview-v2.mjs +654 -0
- package/src/vendor/validator/preview.mjs +8 -688
- package/src/vendor/validator/site-context-v2.mjs +113 -0
- package/src/vendor/validator/validate-v1.mjs +666 -0
- package/src/vendor/validator/validate-v2.mjs +642 -0
- package/src/vendor/validator/validate.mjs +21 -621
- package/starter/assets/theme.css +3 -0
- package/starter/layout.liquid +15 -18
- package/starter/manifest.json +6 -4
- package/starter/preview/config.json +4 -0
- package/starter/preview/media/README.md +9 -0
- package/starter/sections/campaigns.liquid +5 -4
- package/starter/sections/cta.liquid +2 -2
- package/starter/sections/hero.liquid +9 -2
- package/starter/sections/homeHero.liquid +28 -24
- package/starter/sections/people.liquid +7 -6
- package/starter/sections/values.liquid +3 -3
|
@@ -0,0 +1,947 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "The closed v2 section catalogue. Stable section keys identify instances. Authored copy is distinct from resolved public records. Absent collection titles inherit; explicitly empty titles stay hidden.",
|
|
3
|
+
"sections": [
|
|
4
|
+
{
|
|
5
|
+
"type": "hero",
|
|
6
|
+
"label": "Hero banner",
|
|
7
|
+
"pages": [
|
|
8
|
+
"about"
|
|
9
|
+
],
|
|
10
|
+
"description": "The page opener: a headline with an optional kicker and sanitised rich-text intro.",
|
|
11
|
+
"fields": [
|
|
12
|
+
{
|
|
13
|
+
"name": "eyebrow",
|
|
14
|
+
"kind": "text",
|
|
15
|
+
"required": false,
|
|
16
|
+
"description": "Short kicker above the headline."
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "title",
|
|
20
|
+
"kind": "text",
|
|
21
|
+
"required": true,
|
|
22
|
+
"description": "The headline."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "bodyHtml",
|
|
26
|
+
"kind": "richtext",
|
|
27
|
+
"required": false,
|
|
28
|
+
"description": "Sanitised HTML intro, render with the raw filter."
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"minimal": {
|
|
32
|
+
"title": "Our story"
|
|
33
|
+
},
|
|
34
|
+
"sample": {
|
|
35
|
+
"eyebrow": "About us",
|
|
36
|
+
"title": "Neighbours, looked after.",
|
|
37
|
+
"bodyHtml": "<p>The Lantern Trust began in 2011 with a soup pot, a borrowed hall and a belief that nobody in Alderford should face a hard winter alone. Today we run a food bank, a youth club, an advice service and a community garden, powered by more than a hundred volunteers.</p>"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"type": "values",
|
|
42
|
+
"label": "Values / list",
|
|
43
|
+
"pages": [
|
|
44
|
+
"about"
|
|
45
|
+
],
|
|
46
|
+
"description": "A set of principles shown as cards or a numbered list, per the template.",
|
|
47
|
+
"fields": [
|
|
48
|
+
{
|
|
49
|
+
"name": "eyebrow",
|
|
50
|
+
"kind": "text",
|
|
51
|
+
"required": false,
|
|
52
|
+
"description": "Short kicker above the heading."
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "heading",
|
|
56
|
+
"kind": "text",
|
|
57
|
+
"required": false,
|
|
58
|
+
"description": "The section heading."
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "items",
|
|
62
|
+
"kind": "items",
|
|
63
|
+
"required": true,
|
|
64
|
+
"description": "The value entries.",
|
|
65
|
+
"itemFields": [
|
|
66
|
+
{
|
|
67
|
+
"name": "title",
|
|
68
|
+
"kind": "text",
|
|
69
|
+
"required": true,
|
|
70
|
+
"description": "The value's name."
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"name": "description",
|
|
74
|
+
"kind": "text",
|
|
75
|
+
"required": true,
|
|
76
|
+
"description": "One sentence describing it."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "icon",
|
|
80
|
+
"kind": "icon",
|
|
81
|
+
"required": false,
|
|
82
|
+
"description": "Optional emoji/icon."
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
"minimal": {
|
|
88
|
+
"items": [
|
|
89
|
+
{
|
|
90
|
+
"title": "Transparency",
|
|
91
|
+
"description": "Every pound is tracked and reported."
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
"sample": {
|
|
96
|
+
"eyebrow": "What we stand for",
|
|
97
|
+
"heading": "Our values",
|
|
98
|
+
"items": [
|
|
99
|
+
{
|
|
100
|
+
"title": "Openness",
|
|
101
|
+
"description": "Every pound is tracked, reported and published in our annual accounts."
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"title": "Dignity",
|
|
105
|
+
"description": "No referrals, no means tests at the door. If you say you need help, that is enough."
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"title": "Neighbourliness",
|
|
109
|
+
"description": "We work alongside people, not for them. Most of our volunteers first came to us for help."
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"type": "cta",
|
|
116
|
+
"label": "Call to action",
|
|
117
|
+
"pages": [
|
|
118
|
+
"home",
|
|
119
|
+
"about"
|
|
120
|
+
],
|
|
121
|
+
"description": "A closing band: heading, optional line, one button.",
|
|
122
|
+
"fields": [
|
|
123
|
+
{
|
|
124
|
+
"name": "heading",
|
|
125
|
+
"kind": "text",
|
|
126
|
+
"required": true,
|
|
127
|
+
"description": "The band heading."
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "text",
|
|
131
|
+
"kind": "text",
|
|
132
|
+
"required": false,
|
|
133
|
+
"description": "A supporting line."
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"name": "buttonLabel",
|
|
137
|
+
"kind": "text",
|
|
138
|
+
"required": true,
|
|
139
|
+
"description": "The button's label."
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"name": "buttonHref",
|
|
143
|
+
"kind": "url",
|
|
144
|
+
"required": true,
|
|
145
|
+
"description": "The button's destination (scheme-guarded on save). The editor's cause picker writes /donate/{slug} here and records causeId beside it (editor bookkeeping, renderers use buttonHref only and may ignore causeId)."
|
|
146
|
+
}
|
|
147
|
+
],
|
|
148
|
+
"minimal": {
|
|
149
|
+
"heading": "Ready to help?",
|
|
150
|
+
"buttonLabel": "Donate",
|
|
151
|
+
"buttonHref": "/donate"
|
|
152
|
+
},
|
|
153
|
+
"sample": {
|
|
154
|
+
"heading": "Be somebody's good news today",
|
|
155
|
+
"text": "A monthly gift keeps the shelves stocked and the hall warm.",
|
|
156
|
+
"buttonLabel": "Donate now",
|
|
157
|
+
"buttonHref": "/#donate"
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"type": "homeHero",
|
|
162
|
+
"label": "Home hero",
|
|
163
|
+
"pages": [
|
|
164
|
+
"home"
|
|
165
|
+
],
|
|
166
|
+
"description": "The home opener. EVERY field optional: eyebrow/title derive from branding when absent, the lead OMITS when absent (never a fabricated placeholder), buttons fall back to platform defaults.",
|
|
167
|
+
"fields": [
|
|
168
|
+
{
|
|
169
|
+
"name": "eyebrow",
|
|
170
|
+
"kind": "text",
|
|
171
|
+
"required": false,
|
|
172
|
+
"description": "eyebrow: use the resolved authored value. Preserve explicitly empty copy; do not insert editorial defaults in Liquid."
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"name": "title",
|
|
176
|
+
"kind": "text",
|
|
177
|
+
"required": false,
|
|
178
|
+
"description": "title: use the resolved authored value. Preserve explicitly empty copy; do not insert editorial defaults in Liquid."
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"name": "lead",
|
|
182
|
+
"kind": "text",
|
|
183
|
+
"required": false,
|
|
184
|
+
"description": "lead: use the resolved authored value. Preserve explicitly empty copy; do not insert editorial defaults in Liquid."
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"name": "primaryLabel",
|
|
188
|
+
"kind": "text",
|
|
189
|
+
"required": false,
|
|
190
|
+
"description": "primaryLabel: use the resolved authored value. Preserve explicitly empty copy; do not insert editorial defaults in Liquid."
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"name": "primaryHref",
|
|
194
|
+
"kind": "url",
|
|
195
|
+
"required": false,
|
|
196
|
+
"description": "primaryHref: use the resolved authored value. Preserve explicitly empty copy; do not insert editorial defaults in Liquid."
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"name": "secondaryLabel",
|
|
200
|
+
"kind": "text",
|
|
201
|
+
"required": false,
|
|
202
|
+
"description": "secondaryLabel: use the resolved authored value. Preserve explicitly empty copy; do not insert editorial defaults in Liquid."
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"name": "secondaryHref",
|
|
206
|
+
"kind": "url",
|
|
207
|
+
"required": false,
|
|
208
|
+
"description": "secondaryHref: use the resolved authored value. Preserve explicitly empty copy; do not insert editorial defaults in Liquid."
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"name": "imageUrl",
|
|
212
|
+
"kind": "image",
|
|
213
|
+
"required": false,
|
|
214
|
+
"description": "Background photograph for the hero (uploaded through the platform pipeline). Superseded by `images` when that carries any entry, render imageUrl only when images is absent/empty. The template must TREAT the photo (scrim/tint from its own palette variables), never place it raw, and omit for its designed no-photo state."
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"name": "photoFraming",
|
|
218
|
+
"kind": "select",
|
|
219
|
+
"required": false,
|
|
220
|
+
"options": [
|
|
221
|
+
"fill",
|
|
222
|
+
"whole"
|
|
223
|
+
],
|
|
224
|
+
"description": "How hero photographs meet the hero. 'fill' (default): the hero keeps its designed shape and photos crop to fill it (use each photo's focus to pick the surviving slice). 'whole': the hero adapts toward the photo's own shape (height-clamped) so the FULL scene stays visible, the vista treatment for wide landscape photographs; templates overlay or stack their copy accordingly."
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"name": "images",
|
|
228
|
+
"kind": "items",
|
|
229
|
+
"required": false,
|
|
230
|
+
"description": "Hero photographs (0-6, uploaded through the platform pipeline). One = a main image; several = rotation material, a template with supports.heroImagery renders at least the first and MAY place the hero_carousel island (or a CSS scroll strip) for the rest. Like every field: absent means the template's designed no-photo state, never a placeholder.",
|
|
231
|
+
"itemFields": [
|
|
232
|
+
{
|
|
233
|
+
"name": "imageUrl",
|
|
234
|
+
"kind": "image",
|
|
235
|
+
"required": true,
|
|
236
|
+
"description": "The photograph."
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"name": "alt",
|
|
240
|
+
"kind": "text",
|
|
241
|
+
"required": false,
|
|
242
|
+
"description": "Accessible description; empty renders as decorative (alt=\"\")."
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"name": "focus",
|
|
246
|
+
"kind": "select",
|
|
247
|
+
"required": false,
|
|
248
|
+
"options": [
|
|
249
|
+
"centre",
|
|
250
|
+
"top",
|
|
251
|
+
"bottom",
|
|
252
|
+
"left",
|
|
253
|
+
"right"
|
|
254
|
+
],
|
|
255
|
+
"description": "Which part of the photograph survives the fill-crop (templates render photos cover-style, so an aspect mismatch crops, this picks the slice that stays). Maps to background-position/object-position; absent means centre."
|
|
256
|
+
}
|
|
257
|
+
]
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"name": "actionStyle",
|
|
261
|
+
"kind": "select",
|
|
262
|
+
"required": false,
|
|
263
|
+
"options": [
|
|
264
|
+
"widget",
|
|
265
|
+
"button"
|
|
266
|
+
],
|
|
267
|
+
"description": "How the resolved leading action is presented. The platform supplies site.actions; the template never changes which action or widget the organisation chose."
|
|
268
|
+
}
|
|
269
|
+
],
|
|
270
|
+
"minimal": {},
|
|
271
|
+
"sample": {
|
|
272
|
+
"lead": "We turn everyday generosity into food parcels, warm rooms and open doors across Alderford.",
|
|
273
|
+
"images": [
|
|
274
|
+
{
|
|
275
|
+
"imageUrl": "p60fixture:hero/dusk",
|
|
276
|
+
"alt": "Volunteers serving supper as the light fades"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"imageUrl": "p60fixture:hero/river",
|
|
280
|
+
"alt": "The lantern walk along the River Aldern"
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"imageUrl": "p60fixture:hero/garden",
|
|
284
|
+
"alt": "Raised beds in the Foundry Lane community garden"
|
|
285
|
+
}
|
|
286
|
+
],
|
|
287
|
+
"actionStyle": "button"
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"type": "impact",
|
|
292
|
+
"label": "Impact cards",
|
|
293
|
+
"pages": [
|
|
294
|
+
"home"
|
|
295
|
+
],
|
|
296
|
+
"description": "What gifts make possible, optional intro plus icon/title/description cards. Claims must be truthful for the tenant.",
|
|
297
|
+
"fields": [
|
|
298
|
+
{
|
|
299
|
+
"name": "eyebrow",
|
|
300
|
+
"kind": "text",
|
|
301
|
+
"required": false,
|
|
302
|
+
"description": "Short kicker."
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"name": "heading",
|
|
306
|
+
"kind": "text",
|
|
307
|
+
"required": false,
|
|
308
|
+
"description": "The section heading."
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
"name": "text",
|
|
312
|
+
"kind": "text",
|
|
313
|
+
"required": false,
|
|
314
|
+
"description": "An intro line."
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"name": "items",
|
|
318
|
+
"kind": "items",
|
|
319
|
+
"required": true,
|
|
320
|
+
"description": "The impact cards.",
|
|
321
|
+
"itemFields": [
|
|
322
|
+
{
|
|
323
|
+
"name": "imageUrl",
|
|
324
|
+
"kind": "image",
|
|
325
|
+
"required": false,
|
|
326
|
+
"description": "Card image (uploaded through the platform pipeline). Preferred over icon."
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
"name": "icon",
|
|
330
|
+
"kind": "icon",
|
|
331
|
+
"required": false,
|
|
332
|
+
"description": "Legacy emoji/icon, superseded by imageUrl; render it only when imageUrl is absent."
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
"name": "title",
|
|
336
|
+
"kind": "text",
|
|
337
|
+
"required": true,
|
|
338
|
+
"description": "The card title."
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"name": "description",
|
|
342
|
+
"kind": "text",
|
|
343
|
+
"required": true,
|
|
344
|
+
"description": "One sentence describing it."
|
|
345
|
+
}
|
|
346
|
+
]
|
|
347
|
+
}
|
|
348
|
+
],
|
|
349
|
+
"minimal": {
|
|
350
|
+
"items": [
|
|
351
|
+
{
|
|
352
|
+
"title": "Warm meals",
|
|
353
|
+
"description": "Hot meals served at a community kitchen."
|
|
354
|
+
}
|
|
355
|
+
]
|
|
356
|
+
},
|
|
357
|
+
"sample": {
|
|
358
|
+
"eyebrow": "Where your gift goes",
|
|
359
|
+
"heading": "Real help, made of small acts",
|
|
360
|
+
"items": [
|
|
361
|
+
{
|
|
362
|
+
"imageUrl": "p60fixture:impact/parcel",
|
|
363
|
+
"title": "£10 · A family food parcel",
|
|
364
|
+
"description": "Three days of meals, toiletries and a bag of fresh produce from the garden."
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"icon": "🔥",
|
|
368
|
+
"title": "£25 · A warm week",
|
|
369
|
+
"description": "Heating top-ups for a household choosing between eating and heating."
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
"title": "£50 · A month of youth club",
|
|
373
|
+
"description": "Coaching, kit and hot food for a young person, four evenings a week."
|
|
374
|
+
}
|
|
375
|
+
]
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"type": "events",
|
|
380
|
+
"label": "Events",
|
|
381
|
+
"pages": [
|
|
382
|
+
"home"
|
|
383
|
+
],
|
|
384
|
+
"kind": "widget",
|
|
385
|
+
"description": "Published events across registration modes. Render the supplied bounded site.content.events.items with this placement's authored introduction. Optional motion uses declared behaviours; ticket sales and RSVP stay on the platform-owned detail route supplied by each item.",
|
|
386
|
+
"fields": [
|
|
387
|
+
{
|
|
388
|
+
"name": "eyebrow",
|
|
389
|
+
"kind": "text",
|
|
390
|
+
"required": false,
|
|
391
|
+
"description": "Optional authored label above the section title. Empty means hidden."
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
"name": "title",
|
|
395
|
+
"kind": "text",
|
|
396
|
+
"required": false,
|
|
397
|
+
"description": "Absent inherits the public collection label. An explicit empty string hides the title. Otherwise use the authored title exactly."
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"name": "subtitle",
|
|
401
|
+
"kind": "text",
|
|
402
|
+
"required": false,
|
|
403
|
+
"description": "Optional authored introduction. Empty means hidden."
|
|
404
|
+
}
|
|
405
|
+
],
|
|
406
|
+
"minimal": {},
|
|
407
|
+
"sample": {
|
|
408
|
+
"eyebrow": "",
|
|
409
|
+
"title": "Events",
|
|
410
|
+
"subtitle": ""
|
|
411
|
+
},
|
|
412
|
+
"context": [
|
|
413
|
+
"events"
|
|
414
|
+
]
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"type": "articles",
|
|
418
|
+
"label": "Latest articles",
|
|
419
|
+
"pages": [
|
|
420
|
+
"home"
|
|
421
|
+
],
|
|
422
|
+
"kind": "widget",
|
|
423
|
+
"description": "Published articles from the supplied bounded site.content.articles.items. Render the records with this placement's authored introduction and link through the supplied item URLs. Article engagement and comments remain platform islands on the detail page.",
|
|
424
|
+
"fields": [
|
|
425
|
+
{
|
|
426
|
+
"name": "eyebrow",
|
|
427
|
+
"kind": "text",
|
|
428
|
+
"required": false,
|
|
429
|
+
"description": "Optional authored label above the section title. Empty means hidden."
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
"name": "title",
|
|
433
|
+
"kind": "text",
|
|
434
|
+
"required": false,
|
|
435
|
+
"description": "Absent inherits the public collection label. An explicit empty string hides the title. Otherwise use the authored title exactly."
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
"name": "subtitle",
|
|
439
|
+
"kind": "text",
|
|
440
|
+
"required": false,
|
|
441
|
+
"description": "Optional authored introduction. Empty means hidden."
|
|
442
|
+
}
|
|
443
|
+
],
|
|
444
|
+
"minimal": {},
|
|
445
|
+
"sample": {
|
|
446
|
+
"eyebrow": "",
|
|
447
|
+
"title": "Articles",
|
|
448
|
+
"subtitle": ""
|
|
449
|
+
},
|
|
450
|
+
"context": [
|
|
451
|
+
"latestArticles"
|
|
452
|
+
]
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
"type": "campaigns",
|
|
456
|
+
"label": "Campaigns",
|
|
457
|
+
"pages": [
|
|
458
|
+
"home"
|
|
459
|
+
],
|
|
460
|
+
"description": "The tenant's LIVE campaigns (appeals, petitions, surveys) as cards linking to each campaign's page. Render the `campaigns` context your way; render nothing when no campaign is live.",
|
|
461
|
+
"context": [
|
|
462
|
+
"campaigns",
|
|
463
|
+
"campaignsLabel"
|
|
464
|
+
],
|
|
465
|
+
"fields": [
|
|
466
|
+
{
|
|
467
|
+
"name": "eyebrow",
|
|
468
|
+
"kind": "text",
|
|
469
|
+
"required": false,
|
|
470
|
+
"description": "Optional authored label above the section title. Empty means hidden."
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
"name": "title",
|
|
474
|
+
"kind": "text",
|
|
475
|
+
"required": false,
|
|
476
|
+
"description": "Absent inherits the public collection label. An explicit empty string hides the title. Otherwise use the authored title exactly."
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
"name": "subtitle",
|
|
480
|
+
"kind": "text",
|
|
481
|
+
"required": false,
|
|
482
|
+
"description": "Optional authored introduction. Empty means hidden."
|
|
483
|
+
}
|
|
484
|
+
],
|
|
485
|
+
"minimal": {},
|
|
486
|
+
"sample": {
|
|
487
|
+
"eyebrow": "Get involved",
|
|
488
|
+
"title": "What we are campaigning for",
|
|
489
|
+
"subtitle": "The changes Alderford is asking for right now, and how to add your voice."
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
"type": "emergency",
|
|
494
|
+
"label": "Emergency appeal strip",
|
|
495
|
+
"pages": [
|
|
496
|
+
"home"
|
|
497
|
+
],
|
|
498
|
+
"description": "A high-urgency full-width strip, one headline, an optional line, one action. For live emergencies and time-critical appeals.",
|
|
499
|
+
"context": [
|
|
500
|
+
"causes"
|
|
501
|
+
],
|
|
502
|
+
"fields": [
|
|
503
|
+
{
|
|
504
|
+
"name": "heading",
|
|
505
|
+
"kind": "text",
|
|
506
|
+
"required": true,
|
|
507
|
+
"description": "The urgent headline."
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
"name": "text",
|
|
511
|
+
"kind": "text",
|
|
512
|
+
"required": false,
|
|
513
|
+
"description": "One supporting line."
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
"name": "buttonLabel",
|
|
517
|
+
"kind": "text",
|
|
518
|
+
"required": false,
|
|
519
|
+
"description": "Action label (default: Donate now)."
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
"name": "buttonHref",
|
|
523
|
+
"kind": "url",
|
|
524
|
+
"required": false,
|
|
525
|
+
"description": "Action link (default: /donate). Scheme-guarded on save."
|
|
526
|
+
}
|
|
527
|
+
],
|
|
528
|
+
"minimal": {
|
|
529
|
+
"heading": "Emergency appeal"
|
|
530
|
+
},
|
|
531
|
+
"sample": {
|
|
532
|
+
"heading": "Flood response appeal",
|
|
533
|
+
"text": "The Aldern broke its banks on Sunday. Thirty households need dry bedding and warmth now.",
|
|
534
|
+
"buttonLabel": "Give to the flood response",
|
|
535
|
+
"buttonHref": "/donate"
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
{
|
|
539
|
+
"type": "stats",
|
|
540
|
+
"label": "Stats band",
|
|
541
|
+
"pages": [
|
|
542
|
+
"home"
|
|
543
|
+
],
|
|
544
|
+
"description": "Big headline numbers, the at-a-glance impact band. Values are author-entered text (write them exactly as they should read), or, per item, a live figure the platform counts (`source`).",
|
|
545
|
+
"fields": [
|
|
546
|
+
{
|
|
547
|
+
"name": "eyebrow",
|
|
548
|
+
"kind": "text",
|
|
549
|
+
"required": false,
|
|
550
|
+
"description": "Short kicker."
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
"name": "heading",
|
|
554
|
+
"kind": "text",
|
|
555
|
+
"required": false,
|
|
556
|
+
"description": "The band heading."
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
"name": "items",
|
|
560
|
+
"kind": "items",
|
|
561
|
+
"required": true,
|
|
562
|
+
"description": "The stat entries.",
|
|
563
|
+
"itemFields": [
|
|
564
|
+
{
|
|
565
|
+
"name": "value",
|
|
566
|
+
"kind": "text",
|
|
567
|
+
"required": true,
|
|
568
|
+
"description": "The number, as it should read (e.g. 12,000 or 98%)."
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
"name": "label",
|
|
572
|
+
"kind": "text",
|
|
573
|
+
"required": true,
|
|
574
|
+
"description": "What it counts (e.g. meals served)."
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
"name": "source",
|
|
578
|
+
"kind": "select",
|
|
579
|
+
"required": false,
|
|
580
|
+
"options": [
|
|
581
|
+
"volunteers.active",
|
|
582
|
+
"volunteers.hoursThisYear",
|
|
583
|
+
"volunteers.opportunitiesOpen",
|
|
584
|
+
"volunteers.needed"
|
|
585
|
+
],
|
|
586
|
+
"description": "A figure the platform counts rather than the author types (volunteers who helped in the last twelve months, hours logged this year, opportunities open now, volunteers still needed). When set, `value` is replaced at render with the live count, formatted for the site's locale; templates render `value` exactly as before."
|
|
587
|
+
}
|
|
588
|
+
]
|
|
589
|
+
}
|
|
590
|
+
],
|
|
591
|
+
"minimal": {
|
|
592
|
+
"items": [
|
|
593
|
+
{
|
|
594
|
+
"value": "1,200",
|
|
595
|
+
"label": "meals served"
|
|
596
|
+
}
|
|
597
|
+
]
|
|
598
|
+
},
|
|
599
|
+
"sample": {
|
|
600
|
+
"eyebrow": "Last year",
|
|
601
|
+
"heading": "What your giving did",
|
|
602
|
+
"items": [
|
|
603
|
+
{
|
|
604
|
+
"value": "9,200",
|
|
605
|
+
"label": "food parcels packed"
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
"value": "1,400",
|
|
609
|
+
"label": "warm space visits"
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
"value": "96p",
|
|
613
|
+
"label": "of every pound spent in Alderford"
|
|
614
|
+
}
|
|
615
|
+
]
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
"type": "appealGrid",
|
|
620
|
+
"label": "Appeal cards",
|
|
621
|
+
"pages": [
|
|
622
|
+
"home"
|
|
623
|
+
],
|
|
624
|
+
"description": "A grid of appeal/campaign cards, image, title, a line, and a per-card action.",
|
|
625
|
+
"context": [
|
|
626
|
+
"causes"
|
|
627
|
+
],
|
|
628
|
+
"fields": [
|
|
629
|
+
{
|
|
630
|
+
"name": "eyebrow",
|
|
631
|
+
"kind": "text",
|
|
632
|
+
"required": false,
|
|
633
|
+
"description": "Short kicker."
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
"name": "heading",
|
|
637
|
+
"kind": "text",
|
|
638
|
+
"required": false,
|
|
639
|
+
"description": "The section heading."
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
"name": "items",
|
|
643
|
+
"kind": "items",
|
|
644
|
+
"required": true,
|
|
645
|
+
"description": "The appeal cards.",
|
|
646
|
+
"itemFields": [
|
|
647
|
+
{
|
|
648
|
+
"name": "imageUrl",
|
|
649
|
+
"kind": "image",
|
|
650
|
+
"required": false,
|
|
651
|
+
"description": "Card photograph (uploaded through the platform pipeline)."
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
"name": "title",
|
|
655
|
+
"kind": "text",
|
|
656
|
+
"required": true,
|
|
657
|
+
"description": "The appeal's name."
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
"name": "text",
|
|
661
|
+
"kind": "text",
|
|
662
|
+
"required": true,
|
|
663
|
+
"description": "One sentence on what it funds."
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
"name": "buttonLabel",
|
|
667
|
+
"kind": "text",
|
|
668
|
+
"required": false,
|
|
669
|
+
"description": "Card action label (default: Donate)."
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
"name": "buttonHref",
|
|
673
|
+
"kind": "url",
|
|
674
|
+
"required": false,
|
|
675
|
+
"description": "Card action link (default: /donate). Scheme-guarded on save. The cause picker writes /donate/{slug} and records causeId beside it (editor bookkeeping; renderers use buttonHref only)."
|
|
676
|
+
}
|
|
677
|
+
]
|
|
678
|
+
}
|
|
679
|
+
],
|
|
680
|
+
"minimal": {
|
|
681
|
+
"items": [
|
|
682
|
+
{
|
|
683
|
+
"title": "Winter appeal",
|
|
684
|
+
"text": "Warm meals through the coldest months."
|
|
685
|
+
}
|
|
686
|
+
]
|
|
687
|
+
},
|
|
688
|
+
"sample": {
|
|
689
|
+
"eyebrow": "Our appeals",
|
|
690
|
+
"heading": "Where help is needed most",
|
|
691
|
+
"items": [
|
|
692
|
+
{
|
|
693
|
+
"title": "Winter Appeal",
|
|
694
|
+
"text": "Heating top-ups, warm bedding and a hot meal through the coldest months.",
|
|
695
|
+
"buttonLabel": "Support winter",
|
|
696
|
+
"buttonHref": "/donate"
|
|
697
|
+
},
|
|
698
|
+
{
|
|
699
|
+
"title": "Food Bank Fund",
|
|
700
|
+
"text": "Ten pounds fills a family parcel and keeps the depot shelves stocked.",
|
|
701
|
+
"buttonLabel": "Fill a parcel",
|
|
702
|
+
"buttonHref": "/donate"
|
|
703
|
+
}
|
|
704
|
+
]
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
"type": "services",
|
|
709
|
+
"label": "Services and programmes",
|
|
710
|
+
"pages": [
|
|
711
|
+
"home"
|
|
712
|
+
],
|
|
713
|
+
"description": "The tenant's published services and programmes as a dynamic card collection. Render the services context and omit the section when it is empty.",
|
|
714
|
+
"context": [
|
|
715
|
+
"services"
|
|
716
|
+
],
|
|
717
|
+
"fields": [
|
|
718
|
+
{
|
|
719
|
+
"name": "eyebrow",
|
|
720
|
+
"kind": "text",
|
|
721
|
+
"required": false,
|
|
722
|
+
"description": "Optional authored label above the section title. Empty means hidden."
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
"name": "title",
|
|
726
|
+
"kind": "text",
|
|
727
|
+
"required": false,
|
|
728
|
+
"description": "Absent inherits the public collection label. An explicit empty string hides the title. Otherwise use the authored title exactly."
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
"name": "subtitle",
|
|
732
|
+
"kind": "text",
|
|
733
|
+
"required": false,
|
|
734
|
+
"description": "Optional authored introduction. Empty means hidden."
|
|
735
|
+
}
|
|
736
|
+
],
|
|
737
|
+
"minimal": {},
|
|
738
|
+
"sample": {
|
|
739
|
+
"eyebrow": "What we do",
|
|
740
|
+
"title": "Support that meets you where you are",
|
|
741
|
+
"subtitle": "Food, advice, activity and company: five programmes, one front door."
|
|
742
|
+
}
|
|
743
|
+
},
|
|
744
|
+
{
|
|
745
|
+
"type": "documents",
|
|
746
|
+
"label": "Resource library",
|
|
747
|
+
"pages": [
|
|
748
|
+
"home"
|
|
749
|
+
],
|
|
750
|
+
"description": "Public documents from the tenant's media library. The resources context contains PUBLIC documents only; private files and storage metadata never reach Liquid.",
|
|
751
|
+
"context": [
|
|
752
|
+
"resources"
|
|
753
|
+
],
|
|
754
|
+
"fields": [
|
|
755
|
+
{
|
|
756
|
+
"name": "eyebrow",
|
|
757
|
+
"kind": "text",
|
|
758
|
+
"required": false,
|
|
759
|
+
"description": "Optional authored label above the section title. Empty means hidden."
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
"name": "title",
|
|
763
|
+
"kind": "text",
|
|
764
|
+
"required": false,
|
|
765
|
+
"description": "Absent inherits the public collection label. An explicit empty string hides the title. Otherwise use the authored title exactly."
|
|
766
|
+
},
|
|
767
|
+
{
|
|
768
|
+
"name": "subtitle",
|
|
769
|
+
"kind": "text",
|
|
770
|
+
"required": false,
|
|
771
|
+
"description": "Optional authored introduction. Empty means hidden."
|
|
772
|
+
}
|
|
773
|
+
],
|
|
774
|
+
"minimal": {},
|
|
775
|
+
"sample": {
|
|
776
|
+
"eyebrow": "Resources",
|
|
777
|
+
"title": "Reports and documents",
|
|
778
|
+
"subtitle": "Our accounts, policies and handbooks, all in one place."
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
"type": "people",
|
|
783
|
+
"label": "People / team",
|
|
784
|
+
"pages": [
|
|
785
|
+
"about"
|
|
786
|
+
],
|
|
787
|
+
"description": "The key people behind the charity, trustees, staff, volunteers, as simple cards: name, position, an optional photograph (uploaded through the platform pipeline) and an optional one-line statement. Templates render a card grid that collapses to a single column on small screens; a card without a photo renders cleanly (initials or plain), never a placeholder face.",
|
|
788
|
+
"fields": [
|
|
789
|
+
{
|
|
790
|
+
"name": "eyebrow",
|
|
791
|
+
"kind": "text",
|
|
792
|
+
"required": false,
|
|
793
|
+
"description": "Short kicker, e.g. Who we are."
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
"name": "heading",
|
|
797
|
+
"kind": "text",
|
|
798
|
+
"required": false,
|
|
799
|
+
"description": "The section heading, e.g. Our team."
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
"name": "text",
|
|
803
|
+
"kind": "text",
|
|
804
|
+
"required": false,
|
|
805
|
+
"description": "An optional intro line."
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
"name": "items",
|
|
809
|
+
"kind": "items",
|
|
810
|
+
"required": true,
|
|
811
|
+
"description": "The people.",
|
|
812
|
+
"itemFields": [
|
|
813
|
+
{
|
|
814
|
+
"name": "name",
|
|
815
|
+
"kind": "text",
|
|
816
|
+
"required": true,
|
|
817
|
+
"description": "The person's name."
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
"name": "role",
|
|
821
|
+
"kind": "text",
|
|
822
|
+
"required": true,
|
|
823
|
+
"description": "Their position, e.g. Chair of Trustees."
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
"name": "imageUrl",
|
|
827
|
+
"kind": "image",
|
|
828
|
+
"required": false,
|
|
829
|
+
"description": "A photograph (platform pipeline). Absent renders cleanly, never a placeholder face."
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
"name": "statement",
|
|
833
|
+
"kind": "text",
|
|
834
|
+
"required": false,
|
|
835
|
+
"description": "One line in their voice, e.g. why they serve."
|
|
836
|
+
}
|
|
837
|
+
]
|
|
838
|
+
}
|
|
839
|
+
],
|
|
840
|
+
"minimal": {
|
|
841
|
+
"items": [
|
|
842
|
+
{
|
|
843
|
+
"name": "Amina Khan",
|
|
844
|
+
"role": "Chair of Trustees"
|
|
845
|
+
}
|
|
846
|
+
]
|
|
847
|
+
},
|
|
848
|
+
"sample": {
|
|
849
|
+
"eyebrow": "Who we are",
|
|
850
|
+
"heading": "The people behind the work",
|
|
851
|
+
"text": "A small staff team, a board of local trustees, and more than a hundred volunteers, accountable to you.",
|
|
852
|
+
"items": [
|
|
853
|
+
{
|
|
854
|
+
"name": "Priya Sharma",
|
|
855
|
+
"role": "Chair of Trustees",
|
|
856
|
+
"imageUrl": "p60fixture:people/priya/portrait",
|
|
857
|
+
"statement": "Every pound is a trust. We spend it like a neighbour is watching, because one is."
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
"name": "Derek Osei",
|
|
861
|
+
"role": "Food Bank Lead",
|
|
862
|
+
"imageUrl": "p60fixture:people/derek/portrait"
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
"name": "Sara Malik",
|
|
866
|
+
"role": "Volunteer Coordinator",
|
|
867
|
+
"statement": "A hundred pairs of hands, one purpose."
|
|
868
|
+
}
|
|
869
|
+
]
|
|
870
|
+
}
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
"type": "impactMap",
|
|
874
|
+
"label": "Impact map",
|
|
875
|
+
"pages": [
|
|
876
|
+
"home"
|
|
877
|
+
],
|
|
878
|
+
"description": "The organisation's impact map: a themed map whose points link existing content (campaigns, causes, articles, events, places), each opening a card derived from the linked thing. Place the `map` island, it brings the map, the points and the cards; your template brings placement and tokens (the island theming contract).",
|
|
879
|
+
"context": [],
|
|
880
|
+
"fields": [
|
|
881
|
+
{
|
|
882
|
+
"name": "eyebrow",
|
|
883
|
+
"kind": "text",
|
|
884
|
+
"required": false,
|
|
885
|
+
"description": "Short kicker."
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
"name": "heading",
|
|
889
|
+
"kind": "text",
|
|
890
|
+
"required": false,
|
|
891
|
+
"description": "The section heading."
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
"name": "text",
|
|
895
|
+
"kind": "text",
|
|
896
|
+
"required": false,
|
|
897
|
+
"description": "Optional introduction."
|
|
898
|
+
},
|
|
899
|
+
{
|
|
900
|
+
"name": "mapSlug",
|
|
901
|
+
"kind": "text",
|
|
902
|
+
"required": false,
|
|
903
|
+
"description": "WHICH map renders here, by its address (the Pages editor's placement picker writes it; the Maps area is where maps exist). Absent = the tenant's first published map."
|
|
904
|
+
}
|
|
905
|
+
],
|
|
906
|
+
"minimal": {},
|
|
907
|
+
"sample": {
|
|
908
|
+
"eyebrow": "Where we work",
|
|
909
|
+
"heading": "Our impact, on the map",
|
|
910
|
+
"text": "Every marker is a real place: a programme, an appeal, a story. Click one to see what happens there."
|
|
911
|
+
}
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
"type": "courses",
|
|
915
|
+
"label": "Courses",
|
|
916
|
+
"pages": [
|
|
917
|
+
"home"
|
|
918
|
+
],
|
|
919
|
+
"fields": [
|
|
920
|
+
{
|
|
921
|
+
"name": "eyebrow",
|
|
922
|
+
"kind": "text",
|
|
923
|
+
"required": false,
|
|
924
|
+
"description": "Optional authored label above the section title. Empty means hidden."
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
"name": "title",
|
|
928
|
+
"kind": "text",
|
|
929
|
+
"required": false,
|
|
930
|
+
"description": "Absent inherits the public collection label. An explicit empty string hides the title. Otherwise use the authored title exactly."
|
|
931
|
+
},
|
|
932
|
+
{
|
|
933
|
+
"name": "subtitle",
|
|
934
|
+
"kind": "text",
|
|
935
|
+
"required": false,
|
|
936
|
+
"description": "Optional authored introduction. Empty means hidden."
|
|
937
|
+
}
|
|
938
|
+
],
|
|
939
|
+
"minimal": {},
|
|
940
|
+
"sample": {
|
|
941
|
+
"eyebrow": "Learn with us",
|
|
942
|
+
"title": "Courses",
|
|
943
|
+
"subtitle": "Published courses from this organisation."
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
]
|
|
947
|
+
}
|