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.
@@ -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 Map Content Semantically
28
+ ## 1.3 Identify Content Types
29
29
 
30
- Match by CONTENT TYPE, not by what the site calls it:
30
+ Identify repeating content that should be CMS collections:
31
31
 
32
- - Time-stamped articles with authors → **Blog Posts**
33
- (even if called "Insights", "News", "Resources", "Articles")
34
-
35
- - Staff/employee profiles → **Team**
36
- (even if called "Leadership", "Our People", "About Us")
37
-
38
- - Downloadable files **Downloads**
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
- ├── blog_index.html
82
- ├── blog_post.html
83
- ├── team.html
84
- └── downloads.html
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 type`,
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
- "blogIndex": "templates/blog_index.html",
191
- "blogIndexPath": "/blog",
192
- "blogPost": "templates/blog_post.html",
193
- "blogPostPath": "/blog",
194
- "team": "templates/team.html",
195
- "teamPath": "/team",
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
- ## Two Ways to Configure CMS Templates
197
+ ## CMS Template Configuration
207
198
 
208
- ### Option 1: In manifest.json (during package creation)
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
- ### Option 2: Via Settings UI (after upload)
212
- After uploading a package, go to **Dashboard → Settings → CMS Templates** to:
213
- - Map any uploaded HTML page to a template type (Blog Index, Blog Post, Team, Downloads)
214
- - Set custom URL paths for each CMS section
215
- - The UI shows all pages from your manifest for easy selection
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
- **Recommended workflow:**
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 Template Paths
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
- **IMPORTANT:** The collection's internal slug is for database only. URL paths come EXCLUSIVELY from the manifest.
241
+ ### Option 1: In manifest.json (during package creation)
242
+ Configure \`cmsTemplates\` section as shown above when building the package.
275
243
 
276
- This allows same or different paths for list vs detail pages (e.g., /videos for both, or /shop for list and /product for detail).`,
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 (blog_index.html)
282
- 2. **Detail Templates** - Single item pages (blog_post.html)
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="video-card">
303
- <img src="/images/example-video.jpg" alt="Example Video">
304
- <h2>My Example Video Title</h2>
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 video sort="publishedAt" order="desc"}}
310
- <article class="video-card">
311
- {{#if videothumbnail}}
312
- <img src="{{videothumbnail}}" alt="{{name}}">
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>{{shortdescription}}</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 (Blog List)
291
+ ## Index Template Pattern
323
292
 
324
293
  \`\`\`html
325
- <main class="blog-page">
326
- <h1 data-edit-key="blog-title">Blog</h1>
294
+ <main class="posts-page">
295
+ <h1 data-edit-key="posts-title">Blog</h1>
327
296
 
328
297
  <div class="posts-grid">
329
- {{#each blogs limit=12}}
298
+ {{#each posts limit=12 sort="publishedAt" order="desc"}}
330
299
  <article class="post-card">
331
- {{#if thumbnailImage}}
332
- <img src="{{thumbnailImage}}" alt="{{name}}">
300
+ {{#if image}}
301
+ <img src="{{image}}" alt="{{name}}">
333
302
  {{/if}}
334
303
  <h2><a href="{{url}}">{{name}}</a></h2>
335
- <p>{{postSummary}}</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
- **CRITICAL FIELD NAMES for blogs:**
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="blog-post">
357
- {{#if mainImage}}
358
- <img src="{{mainImage}}" alt="{{name}}">
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
- {{{postBody}}}
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
- Include complete header (copy from source)
481
- Include complete footer (copy from source)
482
- All asset paths use /public/
483
- Rich text fields use {{{triple braces}}}`,
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
- {{mainImage}}
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
- {{{postBody}}}
399
+ {{{body}}}
499
400
  {{{bio}}}
500
- {{{author.bio}}}
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 blogs}}
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 blogs}}
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 blogs limit=3}}
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
- ## Equality Comparisons
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
- **Team:**
605
- - {{name}}, {{slug}}, {{role}}
606
- - {{photo}}, {{{bio}}}, {{email}}
607
- - {{order}}
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
- **Downloads:**
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
- <time>{{publishedAt}}</time>
497
+ <span class="price">\${{price}}</span>
624
498
  {{/each}}
625
499
  \`\`\`
626
500
 
627
- **Required built-in tokens for ALL custom collections:**
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
- <!-- If "category" field was added to blogs -->
640
- {{#each blogs}}
641
- <span class="category">{{category}}</span>
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 custom fields for a specific tenant.**`,
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 mainImage}}
767
- <img src="{{mainImage}}" alt="{{name}}">
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
- <!-- Blog post images -->
787
- <img src="{{mainImage}}" alt="{{name}}">
788
- <img src="{{thumbnailImage}}" alt="{{name}}">
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="{{videothumbnail}}" alt="{{name}}">
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 video}}
807
- <img src="/images/video-placeholder.jpg" alt="Video"> <!-- BAD -->
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 video}}
813
- {{#if videothumbnail}}
814
- <img src="{{videothumbnail}}" alt="{{name}}">
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
- ## Structure
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/ if configuring via Settings UI)
690
+ - [ ] Templates in templates/ (or pages/)
837
691
 
838
- ## SEO (CRITICAL)
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
- ## manifest.json
700
+ ## manifest.json
847
701
  - [ ] All static pages listed in pages array
848
702
  - [ ] Each page has path, file, title
849
- - [ ] CMS templates configured (OR plan to configure via Settings → CMS Templates after upload)
703
+ - [ ] CMS templates configured with {slug}Index, {slug}IndexPath, {slug}Detail, {slug}DetailPath
850
704
  - [ ] Paths match original site URLs
851
705
 
852
- ## Assets
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
- ## Templates
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** (blog photos, team headshots) use CMS tokens
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
- ## Field Names
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
- ## Final Validation
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 all collection fields and tokens
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
  */