multisite-cms-mcp 1.2.3 → 1.3.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/dist/index.js +6 -6
- package/dist/tools/get-conversion-guide.d.ts.map +1 -1
- package/dist/tools/get-conversion-guide.js +134 -295
- package/dist/tools/get-example.d.ts +1 -1
- package/dist/tools/get-example.d.ts.map +1 -1
- package/dist/tools/get-example.js +222 -374
- package/dist/tools/get-schema.d.ts +1 -1
- package/dist/tools/get-schema.d.ts.map +1 -1
- package/dist/tools/get-schema.js +130 -450
- package/dist/tools/get-tenant-schema.d.ts +9 -3
- package/dist/tools/get-tenant-schema.d.ts.map +1 -1
- package/dist/tools/get-tenant-schema.js +16 -4
- package/dist/tools/sync-schema.d.ts +1 -1
- package/dist/tools/sync-schema.d.ts.map +1 -1
- package/dist/tools/sync-schema.js +51 -97
- package/dist/tools/validate-manifest.d.ts.map +1 -1
- package/dist/tools/validate-manifest.js +26 -83
- package/dist/tools/validate-package.d.ts.map +1 -1
- package/dist/tools/validate-package.js +46 -41
- package/dist/tools/validate-template.d.ts +2 -2
- package/dist/tools/validate-template.d.ts.map +1 -1
- package/dist/tools/validate-template.js +84 -196
- package/package.json +1 -1
|
@@ -25,21 +25,17 @@ Visit every page and document the exact URL structure:
|
|
|
25
25
|
- **List** - Shows multiple items (/blog, /team)
|
|
26
26
|
- **Detail** - Single item from a list (/blog/my-post)
|
|
27
27
|
|
|
28
|
-
## 1.3
|
|
28
|
+
## 1.3 Identify Content Types
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Identify repeating content that should be CMS collections:
|
|
31
31
|
|
|
32
|
-
- Time-stamped articles
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
(even if called "Resources", "Library", "Documents")
|
|
40
|
-
|
|
41
|
-
- Content writers → **Authors**
|
|
42
|
-
(people credited on articles)
|
|
32
|
+
- Time-stamped articles → **Blog/Posts collection**
|
|
33
|
+
- Staff/employee profiles → **Team collection**
|
|
34
|
+
- Downloadable files → **Downloads collection**
|
|
35
|
+
- Product listings → **Products collection**
|
|
36
|
+
- Testimonials → **Testimonials collection**
|
|
37
|
+
|
|
38
|
+
**Note:** Create custom collections in the CMS dashboard. You can use collection templates (Blog, Team, Downloads, etc.) to quickly set up common patterns.
|
|
43
39
|
|
|
44
40
|
## 1.4 Document Assets
|
|
45
41
|
|
|
@@ -78,10 +74,10 @@ website-package/ # Can be at root or in a subfolder
|
|
|
78
74
|
│ ├── about.html
|
|
79
75
|
│ └── contact.html
|
|
80
76
|
└── templates/ # CMS templates (dynamic content)
|
|
81
|
-
├──
|
|
82
|
-
├──
|
|
83
|
-
├──
|
|
84
|
-
└──
|
|
77
|
+
├── posts_index.html
|
|
78
|
+
├── posts_detail.html
|
|
79
|
+
├── team_index.html
|
|
80
|
+
└── services_index.html
|
|
85
81
|
\`\`\`
|
|
86
82
|
|
|
87
83
|
**SUPPORTED REPO STRUCTURES:**
|
|
@@ -119,7 +115,7 @@ repo/
|
|
|
119
115
|
### templates/
|
|
120
116
|
- CMS-powered pages
|
|
121
117
|
- Use {{tokens}} for dynamic content
|
|
122
|
-
- Named by collection
|
|
118
|
+
- Named by collection slug (e.g., posts_index.html, posts_detail.html)`,
|
|
123
119
|
seo: `# SEO Tags (CRITICAL - Do NOT Include)
|
|
124
120
|
|
|
125
121
|
Fast Mode automatically manages all SEO meta tags. Do NOT include these in your HTML templates:
|
|
@@ -187,37 +183,50 @@ Fast Mode automatically manages all SEO meta tags. Do NOT include these in your
|
|
|
187
183
|
}
|
|
188
184
|
],
|
|
189
185
|
"cmsTemplates": {
|
|
190
|
-
"
|
|
191
|
-
"
|
|
192
|
-
"
|
|
193
|
-
"
|
|
194
|
-
"
|
|
195
|
-
"
|
|
196
|
-
"downloads": "templates/downloads.html",
|
|
197
|
-
"downloadsPath": "/downloads",
|
|
198
|
-
"authorsIndex": "templates/authors_index.html",
|
|
199
|
-
"authorDetail": "templates/author_detail.html",
|
|
200
|
-
"authorsIndexPath": "/authors"
|
|
186
|
+
"postsIndex": "templates/posts_index.html",
|
|
187
|
+
"postsIndexPath": "/blog",
|
|
188
|
+
"postsDetail": "templates/posts_detail.html",
|
|
189
|
+
"postsDetailPath": "/blog",
|
|
190
|
+
"teamIndex": "templates/team_index.html",
|
|
191
|
+
"teamIndexPath": "/team"
|
|
201
192
|
},
|
|
202
193
|
"defaultHeadHtml": "<!-- fonts, meta tags -->"
|
|
203
194
|
}
|
|
204
195
|
\`\`\`
|
|
205
196
|
|
|
206
|
-
##
|
|
197
|
+
## CMS Template Configuration
|
|
207
198
|
|
|
208
|
-
|
|
209
|
-
Configure \`cmsTemplates\` section as shown above when building the package.
|
|
199
|
+
All CMS collections use the **flat format** with four properties per collection:
|
|
210
200
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
201
|
+
\`\`\`json
|
|
202
|
+
{
|
|
203
|
+
"cmsTemplates": {
|
|
204
|
+
// Collection: posts
|
|
205
|
+
"postsIndex": "templates/posts_index.html",
|
|
206
|
+
"postsIndexPath": "/blog",
|
|
207
|
+
"postsDetail": "templates/posts_detail.html",
|
|
208
|
+
"postsDetailPath": "/blog",
|
|
209
|
+
|
|
210
|
+
// Collection: team (no detail pages)
|
|
211
|
+
"teamIndex": "templates/team_index.html",
|
|
212
|
+
"teamIndexPath": "/team",
|
|
213
|
+
|
|
214
|
+
// Collection: services
|
|
215
|
+
"servicesIndex": "pages/services.html",
|
|
216
|
+
"servicesIndexPath": "/services",
|
|
217
|
+
"servicesDetail": "templates/service-detail.html",
|
|
218
|
+
"servicesDetailPath": "/services"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
\`\`\`
|
|
222
|
+
|
|
223
|
+
**Path Configuration Pattern:**
|
|
224
|
+
- \`{collectionSlug}Index\` - Template file for the index/listing page
|
|
225
|
+
- \`{collectionSlug}IndexPath\` - URL for the collection list page
|
|
226
|
+
- \`{collectionSlug}Detail\` - Template file for the detail page
|
|
227
|
+
- \`{collectionSlug}DetailPath\` - Base URL for detail pages (item slug appended)
|
|
216
228
|
|
|
217
|
-
**
|
|
218
|
-
1. Include template HTML files in your package (in pages/ or templates/)
|
|
219
|
-
2. Upload the package
|
|
220
|
-
3. Configure CMS template mappings in Settings if not already in manifest.json
|
|
229
|
+
**IMPORTANT:** The collection slug in the CMS is for the database. URL paths come EXCLUSIVELY from the manifest.
|
|
221
230
|
|
|
222
231
|
## Page Configuration
|
|
223
232
|
|
|
@@ -227,59 +236,19 @@ Each page needs:
|
|
|
227
236
|
- \`title\` - Page title for CMS
|
|
228
237
|
- \`editable\` - Enable inline editing (optional)
|
|
229
238
|
|
|
230
|
-
## CMS
|
|
231
|
-
|
|
232
|
-
**Path properties control URL routing:**
|
|
233
|
-
|
|
234
|
-
- \`blogIndexPath: "/resources"\` → Blog listing at /resources
|
|
235
|
-
- \`blogPostPath: "/resources"\` → Posts at /resources/post-slug
|
|
236
|
-
- \`teamPath: "/about/team"\` → Team at /about/team
|
|
237
|
-
- \`downloadsPath: "/library"\` → Downloads at /library
|
|
238
|
-
- \`authorsIndexPath: "/contributors"\` → Authors at /contributors, detail at /contributors/slug
|
|
239
|
-
|
|
240
|
-
**IMPORTANT:** Match paths to the original site's URLs!
|
|
241
|
-
|
|
242
|
-
## Editor Warnings
|
|
243
|
-
|
|
244
|
-
The editor automatically detects when you're viewing a CMS path (like /blog or /team) that doesn't have a template configured. A warning banner will appear prompting you to configure the template in Settings.
|
|
245
|
-
|
|
246
|
-
## Custom Collection Templates
|
|
247
|
-
|
|
248
|
-
For custom collections (beyond the built-in blog, team, downloads, authors), use the **flat format**:
|
|
249
|
-
|
|
250
|
-
\`\`\`json
|
|
251
|
-
{
|
|
252
|
-
"cmsTemplates": {
|
|
253
|
-
// Custom collection: video
|
|
254
|
-
"videoIndex": "pages/videos.html",
|
|
255
|
-
"videoIndexPath": "/videos",
|
|
256
|
-
"videoDetail": "templates/video-detail.html",
|
|
257
|
-
"videoDetailPath": "/videos",
|
|
258
|
-
|
|
259
|
-
// Custom collection: product
|
|
260
|
-
"productIndex": "pages/shop.html",
|
|
261
|
-
"productIndexPath": "/shop",
|
|
262
|
-
"productDetail": "templates/product-detail.html",
|
|
263
|
-
"productDetailPath": "/product"
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
\`\`\`
|
|
267
|
-
|
|
268
|
-
**Path Configuration (flat format):**
|
|
269
|
-
- \`{slug}Index\` - Template file for the index/listing page
|
|
270
|
-
- \`{slug}IndexPath\` - URL for the collection list page (e.g., /videos)
|
|
271
|
-
- \`{slug}Detail\` - Template file for the detail page
|
|
272
|
-
- \`{slug}DetailPath\` - Base URL for individual item pages (e.g., /videos → /videos/item-slug)
|
|
239
|
+
## Two Ways to Configure CMS Templates
|
|
273
240
|
|
|
274
|
-
|
|
241
|
+
### Option 1: In manifest.json (during package creation)
|
|
242
|
+
Configure \`cmsTemplates\` section as shown above when building the package.
|
|
275
243
|
|
|
276
|
-
|
|
244
|
+
### Option 2: Via Settings UI (after upload)
|
|
245
|
+
After uploading a package, go to **Dashboard → Settings → CMS Templates** to configure template mappings.`,
|
|
277
246
|
templates: `# Template Creation Guide
|
|
278
247
|
|
|
279
248
|
## Template Types
|
|
280
249
|
|
|
281
|
-
1. **Index Templates** - List pages (
|
|
282
|
-
2. **Detail Templates** - Single item pages (
|
|
250
|
+
1. **Index Templates** - List pages (posts_index.html)
|
|
251
|
+
2. **Detail Templates** - Single item pages (posts_detail.html)
|
|
283
252
|
3. **Static Pages** - Fixed content with data-edit-key
|
|
284
253
|
|
|
285
254
|
## Static UI vs Dynamic Content
|
|
@@ -299,63 +268,59 @@ Blog posts, team members, products - replace example content with \`{{#each}}\`
|
|
|
299
268
|
|
|
300
269
|
\`\`\`html
|
|
301
270
|
<!-- WRONG: Hardcoded example content -->
|
|
302
|
-
<article class="
|
|
303
|
-
<img src="/images/example-
|
|
304
|
-
<h2>My Example
|
|
271
|
+
<article class="post-card">
|
|
272
|
+
<img src="/images/example-post.jpg" alt="Example Post">
|
|
273
|
+
<h2>My Example Post Title</h2>
|
|
305
274
|
<p>This is a sample description...</p>
|
|
306
275
|
</article>
|
|
307
276
|
|
|
308
277
|
<!-- CORRECT: CMS tokens with loop -->
|
|
309
|
-
{{#each
|
|
310
|
-
<article class="
|
|
311
|
-
{{#if
|
|
312
|
-
<img src="{{
|
|
278
|
+
{{#each posts sort="publishedAt" order="desc"}}
|
|
279
|
+
<article class="post-card">
|
|
280
|
+
{{#if image}}
|
|
281
|
+
<img src="{{image}}" alt="{{name}}">
|
|
313
282
|
{{/if}}
|
|
314
283
|
<h2><a href="{{url}}">{{name}}</a></h2>
|
|
315
|
-
<p>{{
|
|
284
|
+
<p>{{summary}}</p>
|
|
316
285
|
</article>
|
|
317
286
|
{{/each}}
|
|
318
287
|
\`\`\`
|
|
319
288
|
|
|
320
289
|
**Rule of thumb:** If it's site branding/design → keep static. If it's content that changes per item → use CMS tokens.
|
|
321
290
|
|
|
322
|
-
## Index Template Pattern
|
|
291
|
+
## Index Template Pattern
|
|
323
292
|
|
|
324
293
|
\`\`\`html
|
|
325
|
-
<main class="
|
|
326
|
-
<h1 data-edit-key="
|
|
294
|
+
<main class="posts-page">
|
|
295
|
+
<h1 data-edit-key="posts-title">Blog</h1>
|
|
327
296
|
|
|
328
297
|
<div class="posts-grid">
|
|
329
|
-
{{#each
|
|
298
|
+
{{#each posts limit=12 sort="publishedAt" order="desc"}}
|
|
330
299
|
<article class="post-card">
|
|
331
|
-
{{#if
|
|
332
|
-
<img src="{{
|
|
300
|
+
{{#if image}}
|
|
301
|
+
<img src="{{image}}" alt="{{name}}">
|
|
333
302
|
{{/if}}
|
|
334
303
|
<h2><a href="{{url}}">{{name}}</a></h2>
|
|
335
|
-
<p>{{
|
|
304
|
+
<p>{{summary}}</p>
|
|
336
305
|
{{#if author}}
|
|
337
306
|
<span>By {{author.name}}</span>
|
|
338
307
|
{{/if}}
|
|
339
308
|
</article>
|
|
340
309
|
{{/each}}
|
|
341
310
|
</div>
|
|
311
|
+
|
|
312
|
+
{{#unless posts}}
|
|
313
|
+
<p>No posts yet. Check back soon!</p>
|
|
314
|
+
{{/unless}}
|
|
342
315
|
</main>
|
|
343
316
|
\`\`\`
|
|
344
317
|
|
|
345
|
-
|
|
346
|
-
- \`{{name}}\` = Post title (NOT {{title}})
|
|
347
|
-
- \`{{mainImage}}\` = Hero image (NOT {{coverImageUrl}})
|
|
348
|
-
- \`{{thumbnailImage}}\` = Preview image
|
|
349
|
-
- \`{{postSummary}}\` = Excerpt (NOT {{excerpt}})
|
|
350
|
-
- \`{{{postBody}}}\` = Content (NOT {{bodyHtml}}, uses TRIPLE braces)
|
|
351
|
-
- \`{{url}}\` = Generated link to detail page
|
|
352
|
-
|
|
353
|
-
## Detail Template Pattern (Blog Post)
|
|
318
|
+
## Detail Template Pattern
|
|
354
319
|
|
|
355
320
|
\`\`\`html
|
|
356
|
-
<article class="
|
|
357
|
-
{{#if
|
|
358
|
-
<img src="{{
|
|
321
|
+
<article class="post-detail">
|
|
322
|
+
{{#if image}}
|
|
323
|
+
<img src="{{image}}" alt="{{name}}">
|
|
359
324
|
{{/if}}
|
|
360
325
|
|
|
361
326
|
<h1>{{name}}</h1>
|
|
@@ -371,7 +336,7 @@ Blog posts, team members, products - replace example content with \`{{#each}}\`
|
|
|
371
336
|
{{/if}}
|
|
372
337
|
|
|
373
338
|
<div class="content">
|
|
374
|
-
{{{
|
|
339
|
+
{{{body}}}
|
|
375
340
|
</div>
|
|
376
341
|
</article>
|
|
377
342
|
\`\`\`
|
|
@@ -397,70 +362,6 @@ Blog posts, team members, products - replace example content with \`{{#each}}\`
|
|
|
397
362
|
</div>
|
|
398
363
|
\`\`\`
|
|
399
364
|
|
|
400
|
-
**CRITICAL FIELD NAMES for team:**
|
|
401
|
-
- \`{{name}}\` = Team member name
|
|
402
|
-
- \`{{role}}\` = Job title
|
|
403
|
-
- \`{{photo}}\` = Headshot (NOT {{picture}})
|
|
404
|
-
- \`{{{bio}}}\` = Biography (TRIPLE braces for HTML)
|
|
405
|
-
- \`{{order}}\` = Display order
|
|
406
|
-
|
|
407
|
-
## Author Index Template Pattern
|
|
408
|
-
|
|
409
|
-
\`\`\`html
|
|
410
|
-
<div class="authors-grid">
|
|
411
|
-
{{#each authors}}
|
|
412
|
-
<div class="author-card">
|
|
413
|
-
{{#if picture}}
|
|
414
|
-
<img src="{{picture}}" alt="{{name}}">
|
|
415
|
-
{{/if}}
|
|
416
|
-
<h3><a href="{{url}}">{{name}}</a></h3>
|
|
417
|
-
{{#if bio}}
|
|
418
|
-
<div class="bio-excerpt">{{{bio}}}</div>
|
|
419
|
-
{{/if}}
|
|
420
|
-
</div>
|
|
421
|
-
{{/each}}
|
|
422
|
-
</div>
|
|
423
|
-
\`\`\`
|
|
424
|
-
|
|
425
|
-
## Author Detail Template Pattern
|
|
426
|
-
|
|
427
|
-
\`\`\`html
|
|
428
|
-
<article class="author-profile">
|
|
429
|
-
{{#if picture}}
|
|
430
|
-
<img src="{{picture}}" alt="{{name}}" class="author-photo">
|
|
431
|
-
{{/if}}
|
|
432
|
-
|
|
433
|
-
<h1>{{name}}</h1>
|
|
434
|
-
|
|
435
|
-
{{#if bio}}
|
|
436
|
-
<div class="bio">{{{bio}}}</div>
|
|
437
|
-
{{/if}}
|
|
438
|
-
|
|
439
|
-
{{#if email}}
|
|
440
|
-
<a href="mailto:{{email}}">{{email}}</a>
|
|
441
|
-
{{/if}}
|
|
442
|
-
|
|
443
|
-
<!-- Posts by this author -->
|
|
444
|
-
<h2>Posts by {{name}}</h2>
|
|
445
|
-
{{#each blogs}}
|
|
446
|
-
{{#if (eq author.name ../name)}}
|
|
447
|
-
<article>
|
|
448
|
-
<h3><a href="{{url}}">{{name}}</a></h3>
|
|
449
|
-
<p>{{postSummary}}</p>
|
|
450
|
-
</article>
|
|
451
|
-
{{/if}}
|
|
452
|
-
{{/each}}
|
|
453
|
-
</article>
|
|
454
|
-
\`\`\`
|
|
455
|
-
|
|
456
|
-
**CRITICAL FIELD NAMES for authors:**
|
|
457
|
-
- \`{{name}}\` = Author name
|
|
458
|
-
- \`{{picture}}\` = Author photo (NOT {{photo}})
|
|
459
|
-
- \`{{{bio}}}\` = Biography (TRIPLE braces for HTML)
|
|
460
|
-
- \`{{email}}\` = Email address
|
|
461
|
-
- \`{{url}}\` = Link to author detail page
|
|
462
|
-
- Use \`{{#if (eq author.name ../name)}}\` to filter posts by current author
|
|
463
|
-
|
|
464
365
|
## Static Page Pattern
|
|
465
366
|
|
|
466
367
|
\`\`\`html
|
|
@@ -477,17 +378,17 @@ Blog posts, team members, products - replace example content with \`{{#each}}\`
|
|
|
477
378
|
|
|
478
379
|
## Template Must-Haves
|
|
479
380
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
381
|
+
- Include complete header (copy from source)
|
|
382
|
+
- Include complete footer (copy from source)
|
|
383
|
+
- All asset paths use /public/
|
|
384
|
+
- Rich text fields use {{{triple braces}}}`,
|
|
484
385
|
tokens: `# Token Reference
|
|
485
386
|
|
|
486
387
|
## Double Braces {{...}} - Escaped Output
|
|
487
388
|
Use for text, URLs, images:
|
|
488
389
|
\`\`\`html
|
|
489
390
|
{{name}}
|
|
490
|
-
{{
|
|
391
|
+
{{image}}
|
|
491
392
|
{{url}}
|
|
492
393
|
{{author.name}}
|
|
493
394
|
\`\`\`
|
|
@@ -495,23 +396,23 @@ Use for text, URLs, images:
|
|
|
495
396
|
## Triple Braces {{{...}}} - Raw HTML
|
|
496
397
|
Use for rich text content:
|
|
497
398
|
\`\`\`html
|
|
498
|
-
{{{
|
|
399
|
+
{{{body}}}
|
|
499
400
|
{{{bio}}}
|
|
500
|
-
{{{
|
|
401
|
+
{{{description}}}
|
|
501
402
|
\`\`\`
|
|
502
403
|
|
|
503
|
-
**CRITICAL:** If a field contains HTML, you MUST use triple braces!
|
|
404
|
+
**CRITICAL:** If a field contains HTML (richText type), you MUST use triple braces!
|
|
504
405
|
|
|
505
406
|
## Loop Syntax
|
|
506
407
|
\`\`\`html
|
|
507
|
-
{{#each
|
|
408
|
+
{{#each collectionSlug}}
|
|
508
409
|
...content for each item...
|
|
509
410
|
{{/each}}
|
|
510
411
|
\`\`\`
|
|
511
412
|
|
|
512
413
|
**Modifiers:**
|
|
513
414
|
- \`limit=N\` - Maximum items
|
|
514
|
-
- \`featured=true\` - Only featured
|
|
415
|
+
- \`featured=true\` - Only featured (if collection has boolean "featured" field)
|
|
515
416
|
- \`sort="field"\` - Sort by field
|
|
516
417
|
- \`order="asc|desc"\` - Sort direction
|
|
517
418
|
|
|
@@ -552,14 +453,14 @@ Inside {{#each}}:
|
|
|
552
453
|
Inside loops, access the parent scope:
|
|
553
454
|
\`\`\`html
|
|
554
455
|
<!-- Filter posts by current author -->
|
|
555
|
-
{{#each
|
|
456
|
+
{{#each posts}}
|
|
556
457
|
{{#if (eq author.name ../name)}}
|
|
557
458
|
<h3>{{name}}</h3>
|
|
558
459
|
{{/if}}
|
|
559
460
|
{{/each}}
|
|
560
461
|
|
|
561
462
|
<!-- Related Posts (exclude current) -->
|
|
562
|
-
{{#each
|
|
463
|
+
{{#each posts limit=3}}
|
|
563
464
|
{{#unless (eq slug ../slug)}}
|
|
564
465
|
<a href="{{url}}">{{name}}</a>
|
|
565
466
|
{{/unless}}
|
|
@@ -575,74 +476,40 @@ Inside loops, access the parent scope:
|
|
|
575
476
|
- Category pages: filter items by current category
|
|
576
477
|
- Related items: match based on current page
|
|
577
478
|
|
|
578
|
-
##
|
|
579
|
-
Compare two values:
|
|
580
|
-
\`\`\`html
|
|
581
|
-
{{#if (eq author.name ../name)}}
|
|
582
|
-
<!-- True when fields match -->
|
|
583
|
-
{{/if}}
|
|
584
|
-
|
|
585
|
-
{{#eq status "published"}}
|
|
586
|
-
<!-- Compare to literal string -->
|
|
587
|
-
{{/eq}}
|
|
588
|
-
\`\`\`
|
|
589
|
-
|
|
590
|
-
## Collection Fields
|
|
591
|
-
|
|
592
|
-
**Blog Posts:**
|
|
593
|
-
- {{name}}, {{slug}}, {{url}}
|
|
594
|
-
- {{mainImage}}, {{thumbnailImage}}
|
|
595
|
-
- {{postSummary}}, {{{postBody}}}
|
|
596
|
-
- {{featured}}, {{publishedAt}}
|
|
597
|
-
- {{author.name}}, {{author.picture}}, {{{author.bio}}}
|
|
598
|
-
|
|
599
|
-
**Authors:**
|
|
600
|
-
- {{name}}, {{slug}}, {{url}}
|
|
601
|
-
- {{picture}}, {{{bio}}}
|
|
602
|
-
- {{email}}, {{twitterProfileLink}}, {{linkedinProfileLink}}
|
|
479
|
+
## Built-in Fields (Available on ALL items)
|
|
603
480
|
|
|
604
|
-
|
|
605
|
-
- {{name}}
|
|
606
|
-
- {{
|
|
607
|
-
- {{
|
|
481
|
+
Every collection item automatically has:
|
|
482
|
+
- \`{{name}}\` - Item name/title (REQUIRED)
|
|
483
|
+
- \`{{slug}}\` - Item URL slug
|
|
484
|
+
- \`{{url}}\` - Full URL to detail page
|
|
485
|
+
- \`{{publishedAt}}\` - Publish date
|
|
486
|
+
- \`{{createdAt}}\` - Creation date
|
|
487
|
+
- \`{{updatedAt}}\` - Last modified date
|
|
608
488
|
|
|
609
|
-
|
|
610
|
-
- {{title}}, {{slug}}, {{description}}
|
|
611
|
-
- {{fileUrl}}, {{category}}, {{order}}
|
|
612
|
-
|
|
613
|
-
## Custom Collections
|
|
614
|
-
|
|
615
|
-
Tenants can create custom collections (e.g., "services", "testimonials", "products").
|
|
616
|
-
All custom collections have mandatory \`name\` and \`publishedAt\` fields, just like blogs.
|
|
489
|
+
## Custom Fields
|
|
617
490
|
|
|
491
|
+
Custom fields are defined when creating collections. The token matches the field slug:
|
|
618
492
|
\`\`\`html
|
|
619
493
|
{{#each services sort="publishedAt" order="desc"}}
|
|
620
494
|
<h2><a href="{{url}}">{{name}}</a></h2>
|
|
621
495
|
{{{description}}}
|
|
622
496
|
<img src="{{image}}" alt="{{name}}">
|
|
623
|
-
<
|
|
497
|
+
<span class="price">\${{price}}</span>
|
|
624
498
|
{{/each}}
|
|
625
499
|
\`\`\`
|
|
626
500
|
|
|
627
|
-
|
|
628
|
-
- \`{{name}}\` - Item name/title (REQUIRED for every item)
|
|
629
|
-
- \`{{slug}}\` - Item URL slug (for detail pages)
|
|
630
|
-
- \`{{url}}\` - Generated full URL to detail page
|
|
631
|
-
- \`{{publishedAt}}\` - Publish date (REQUIRED for every item)
|
|
632
|
-
|
|
633
|
-
## Custom Fields on Built-in Collections
|
|
634
|
-
|
|
635
|
-
Tenants can add custom fields to Blog Posts, Authors, Team, and Downloads.
|
|
636
|
-
Use the same token syntax:
|
|
501
|
+
## Relation Fields
|
|
637
502
|
|
|
503
|
+
Access related item data with dot notation:
|
|
638
504
|
\`\`\`html
|
|
639
|
-
|
|
640
|
-
{{#
|
|
641
|
-
|
|
505
|
+
{{#each posts}}
|
|
506
|
+
{{#if category}}
|
|
507
|
+
<span class="category">{{category.name}}</span>
|
|
508
|
+
{{/if}}
|
|
642
509
|
{{/each}}
|
|
643
510
|
\`\`\`
|
|
644
511
|
|
|
645
|
-
**Use \`get_tenant_schema\` tool to see exact
|
|
512
|
+
**Use \`get_tenant_schema\` tool to see exact fields for a specific project.**`,
|
|
646
513
|
forms: `# Form Handling
|
|
647
514
|
|
|
648
515
|
Forms are automatically captured by the CMS.
|
|
@@ -763,39 +630,26 @@ background-image: url('images/hero.jpg');
|
|
|
763
630
|
|
|
764
631
|
\`\`\`html
|
|
765
632
|
<!-- CORRECT: CMS token for dynamic content -->
|
|
766
|
-
{{#if
|
|
767
|
-
<img src="{{
|
|
633
|
+
{{#if image}}
|
|
634
|
+
<img src="{{image}}" alt="{{name}}">
|
|
768
635
|
{{/if}}
|
|
769
636
|
|
|
770
637
|
<!-- WRONG: Hardcoded example content -->
|
|
771
638
|
<img src="/images/example-post.jpg" alt="Example Post">
|
|
772
639
|
\`\`\`
|
|
773
640
|
|
|
774
|
-
### CMS Image URL Format
|
|
775
|
-
|
|
776
|
-
When users upload images through the CMS dashboard, they are stored and served from:
|
|
777
|
-
\`\`\`
|
|
778
|
-
https://api.fastmode.ai/media/{tenantId}/{filename}
|
|
779
|
-
\`\`\`
|
|
780
|
-
|
|
781
|
-
**Templates should NEVER reference this URL directly** - the CMS automatically provides the correct URL through the token.
|
|
782
|
-
|
|
783
641
|
### Image Field Examples
|
|
784
642
|
|
|
785
643
|
\`\`\`html
|
|
786
|
-
<!--
|
|
787
|
-
<img src="{{
|
|
788
|
-
<img src="{{
|
|
644
|
+
<!-- Post images -->
|
|
645
|
+
<img src="{{image}}" alt="{{name}}">
|
|
646
|
+
<img src="{{thumbnail}}" alt="{{name}}">
|
|
789
647
|
|
|
790
648
|
<!-- Team member photos -->
|
|
791
649
|
<img src="{{photo}}" alt="{{name}}">
|
|
792
650
|
|
|
793
|
-
<!-- Author photos -->
|
|
794
|
-
<img src="{{picture}}" alt="{{name}}">
|
|
795
|
-
|
|
796
651
|
<!-- Custom collection images (field slug becomes token) -->
|
|
797
|
-
<img src="{{
|
|
798
|
-
<img src="{{ogimage}}" alt="{{name}}">
|
|
652
|
+
<img src="{{heroImage}}" alt="{{name}}">
|
|
799
653
|
<img src="{{productImage}}" alt="{{name}}">
|
|
800
654
|
\`\`\`
|
|
801
655
|
|
|
@@ -803,15 +657,15 @@ https://api.fastmode.ai/media/{tenantId}/{filename}
|
|
|
803
657
|
|
|
804
658
|
\`\`\`html
|
|
805
659
|
<!-- WRONG: Don't mix hardcoded images with CMS content -->
|
|
806
|
-
{{#each
|
|
807
|
-
<img src="/images/
|
|
660
|
+
{{#each products}}
|
|
661
|
+
<img src="/images/product-placeholder.jpg" alt="Product"> <!-- BAD -->
|
|
808
662
|
<h2>{{name}}</h2>
|
|
809
663
|
{{/each}}
|
|
810
664
|
|
|
811
665
|
<!-- CORRECT: All content comes from CMS -->
|
|
812
|
-
{{#each
|
|
813
|
-
{{#if
|
|
814
|
-
<img src="{{
|
|
666
|
+
{{#each products}}
|
|
667
|
+
{{#if image}}
|
|
668
|
+
<img src="{{image}}" alt="{{name}}">
|
|
815
669
|
{{/if}}
|
|
816
670
|
<h2>{{name}}</h2>
|
|
817
671
|
{{/each}}
|
|
@@ -829,13 +683,13 @@ Keep external URLs unchanged:
|
|
|
829
683
|
\`\`\``,
|
|
830
684
|
checklist: `# Pre-Submission Checklist
|
|
831
685
|
|
|
832
|
-
##
|
|
686
|
+
## Structure
|
|
833
687
|
- [ ] manifest.json at package root
|
|
834
688
|
- [ ] Static pages in pages/ folder
|
|
835
689
|
- [ ] Assets in public/ folder
|
|
836
|
-
- [ ] Templates in templates/ (or pages/
|
|
690
|
+
- [ ] Templates in templates/ (or pages/)
|
|
837
691
|
|
|
838
|
-
##
|
|
692
|
+
## SEO (CRITICAL)
|
|
839
693
|
- [ ] NO \`<title>\` tags in HTML
|
|
840
694
|
- [ ] NO \`<meta name="description">\` tags
|
|
841
695
|
- [ ] NO \`<meta property="og:*">\` tags
|
|
@@ -843,20 +697,20 @@ Keep external URLs unchanged:
|
|
|
843
697
|
- [ ] NO \`<link rel="icon">\` tags
|
|
844
698
|
- [ ] Include \`<!-- SEO managed by Fast Mode -->\` comment in head
|
|
845
699
|
|
|
846
|
-
##
|
|
700
|
+
## manifest.json
|
|
847
701
|
- [ ] All static pages listed in pages array
|
|
848
702
|
- [ ] Each page has path, file, title
|
|
849
|
-
- [ ] CMS templates configured
|
|
703
|
+
- [ ] CMS templates configured with {slug}Index, {slug}IndexPath, {slug}Detail, {slug}DetailPath
|
|
850
704
|
- [ ] Paths match original site URLs
|
|
851
705
|
|
|
852
|
-
##
|
|
706
|
+
## Assets
|
|
853
707
|
- [ ] ALL CSS uses /public/ paths
|
|
854
708
|
- [ ] ALL JS uses /public/ paths
|
|
855
709
|
- [ ] ALL images use /public/ paths
|
|
856
710
|
- [ ] CSS background-image urls updated
|
|
857
711
|
- [ ] Font paths in CSS updated
|
|
858
712
|
|
|
859
|
-
##
|
|
713
|
+
## Templates
|
|
860
714
|
- [ ] Templates include header/footer
|
|
861
715
|
- [ ] {{#each}} loops have {{/each}}
|
|
862
716
|
- [ ] {{#if}} conditions have {{/if}}
|
|
@@ -865,32 +719,16 @@ Keep external URLs unchanged:
|
|
|
865
719
|
- [ ] Parent refs (../) only inside loops
|
|
866
720
|
- [ ] Correct field names used
|
|
867
721
|
- [ ] **Static UI images** (logos, icons) use \`/public/\` paths
|
|
868
|
-
- [ ] **Content images**
|
|
722
|
+
- [ ] **Content images** use CMS tokens
|
|
869
723
|
- [ ] **No hardcoded example content** - dynamic items use \`{{#each}}\` loops
|
|
870
724
|
- [ ] Index pages iterate over collections, not static example cards
|
|
871
725
|
|
|
872
|
-
##
|
|
873
|
-
|
|
874
|
-
**Blog Posts:**
|
|
875
|
-
- ✓ {{name}} NOT {{title}}
|
|
876
|
-
- ✓ {{mainImage}} NOT {{coverImage}}
|
|
877
|
-
- ✓ {{postSummary}} NOT {{excerpt}}
|
|
878
|
-
- ✓ {{{postBody}}} with triple braces
|
|
879
|
-
|
|
880
|
-
**Team:**
|
|
881
|
-
- ✓ {{photo}} NOT {{picture}}
|
|
882
|
-
- ✓ {{{bio}}} with triple braces
|
|
883
|
-
|
|
884
|
-
**Authors:**
|
|
885
|
-
- ✓ {{picture}} NOT {{photo}}
|
|
886
|
-
- ✓ {{{bio}}} with triple braces
|
|
887
|
-
|
|
888
|
-
## ✓ Static Pages
|
|
726
|
+
## Static Pages
|
|
889
727
|
- [ ] data-edit-key on editable text
|
|
890
728
|
- [ ] Keys are unique and descriptive
|
|
891
729
|
- [ ] Forms have data-form-name
|
|
892
730
|
|
|
893
|
-
##
|
|
731
|
+
## Final Validation
|
|
894
732
|
- [ ] Run validate_manifest with manifest.json
|
|
895
733
|
- [ ] Run validate_template on each template
|
|
896
734
|
- [ ] Run validate_package for full check`,
|
|
@@ -943,7 +781,8 @@ ${SECTIONS.checklist}
|
|
|
943
781
|
|
|
944
782
|
Use these MCP tools during conversion:
|
|
945
783
|
|
|
946
|
-
- \`get_schema\` - Get
|
|
784
|
+
- \`get_schema\` - Get collection field reference and token syntax
|
|
785
|
+
- \`get_tenant_schema\` - Get exact collections and fields for a specific project
|
|
947
786
|
- \`get_example\` - Get code examples for specific patterns
|
|
948
787
|
- \`validate_manifest\` - Check your manifest.json
|
|
949
788
|
- \`validate_template\` - Check template token usage
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type ExampleType = 'manifest_basic' | 'manifest_custom_paths' | 'manifest_minimal_with_ui' | 'blog_index_template' | 'blog_post_template' | 'team_template' | 'downloads_template' | 'authors_template' | 'author_detail_template' | 'custom_collection_template' | 'form_handling' | 'asset_paths' | 'image_handling' | 'relation_fields' | 'data_edit_keys' | 'each_loop' | 'conditional_if' | 'nested_fields' | 'featured_posts' | 'parent_context' | 'equality_comparison';
|
|
1
|
+
type ExampleType = 'manifest_basic' | 'manifest_custom_paths' | 'manifest_minimal_with_ui' | 'blog_index_template' | 'blog_post_template' | 'team_template' | 'downloads_template' | 'authors_template' | 'author_detail_template' | 'custom_collection_template' | 'form_handling' | 'asset_paths' | 'image_handling' | 'relation_fields' | 'data_edit_keys' | 'each_loop' | 'conditional_if' | 'nested_fields' | 'featured_posts' | 'parent_context' | 'equality_comparison' | 'youtube_embed';
|
|
2
2
|
/**
|
|
3
3
|
* Returns example code for a specific pattern
|
|
4
4
|
*/
|