multisite-cms-mcp 1.0.6 → 1.0.8
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-conversion-guide.d.ts","sourceRoot":"","sources":["../../src/tools/get-conversion-guide.ts"],"names":[],"mappings":"AAAA,KAAK,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"get-conversion-guide.d.ts","sourceRoot":"","sources":["../../src/tools/get-conversion-guide.ts"],"names":[],"mappings":"AAAA,KAAK,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAC;AAmkB1H;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAkD1E"}
|
|
@@ -61,10 +61,10 @@ Do NOT change it to \`/blog\`.
|
|
|
61
61
|
Use the manifest's path configuration to maintain original URLs.`,
|
|
62
62
|
structure: `# Package Structure
|
|
63
63
|
|
|
64
|
-
Create a
|
|
64
|
+
Create a package with this structure (can be at repo root OR in a subfolder like cms_package/):
|
|
65
65
|
|
|
66
66
|
\`\`\`
|
|
67
|
-
website-package
|
|
67
|
+
website-package/ # Can be at root or in a subfolder
|
|
68
68
|
├── manifest.json # Required: Defines pages and CMS templates
|
|
69
69
|
├── public/ # Static assets (CSS, JS, images, fonts)
|
|
70
70
|
│ ├── css/
|
|
@@ -84,6 +84,26 @@ website-package.zip
|
|
|
84
84
|
└── downloads.html
|
|
85
85
|
\`\`\`
|
|
86
86
|
|
|
87
|
+
**SUPPORTED REPO STRUCTURES:**
|
|
88
|
+
\`\`\`
|
|
89
|
+
Option 1: CMS files at root
|
|
90
|
+
repo/
|
|
91
|
+
├── manifest.json
|
|
92
|
+
├── pages/
|
|
93
|
+
├── public/
|
|
94
|
+
└── templates/
|
|
95
|
+
|
|
96
|
+
Option 2: CMS files in subfolder (e.g. for Next.js projects)
|
|
97
|
+
repo/
|
|
98
|
+
├── app/ # Next.js app (ignored)
|
|
99
|
+
├── cms_package/ # CMS files here
|
|
100
|
+
│ ├── manifest.json
|
|
101
|
+
│ ├── pages/
|
|
102
|
+
│ ├── public/
|
|
103
|
+
│ └── templates/
|
|
104
|
+
└── package.json
|
|
105
|
+
\`\`\`
|
|
106
|
+
|
|
87
107
|
## Folder Rules
|
|
88
108
|
|
|
89
109
|
### public/
|
|
@@ -169,7 +189,7 @@ For dynamic collections beyond the built-ins:
|
|
|
169
189
|
2. **Detail Templates** - Single item pages (blog_post.html)
|
|
170
190
|
3. **Static Pages** - Fixed content with data-edit-key
|
|
171
191
|
|
|
172
|
-
## Index Template Pattern
|
|
192
|
+
## Index Template Pattern (Blog List)
|
|
173
193
|
|
|
174
194
|
\`\`\`html
|
|
175
195
|
<main class="blog-page">
|
|
@@ -192,7 +212,15 @@ For dynamic collections beyond the built-ins:
|
|
|
192
212
|
</main>
|
|
193
213
|
\`\`\`
|
|
194
214
|
|
|
195
|
-
|
|
215
|
+
**CRITICAL FIELD NAMES for blogs:**
|
|
216
|
+
- \`{{name}}\` = Post title (NOT {{title}})
|
|
217
|
+
- \`{{mainImage}}\` = Hero image (NOT {{coverImageUrl}})
|
|
218
|
+
- \`{{thumbnailImage}}\` = Preview image
|
|
219
|
+
- \`{{postSummary}}\` = Excerpt (NOT {{excerpt}})
|
|
220
|
+
- \`{{{postBody}}}\` = Content (NOT {{bodyHtml}}, uses TRIPLE braces)
|
|
221
|
+
- \`{{url}}\` = Generated link to detail page
|
|
222
|
+
|
|
223
|
+
## Detail Template Pattern (Blog Post)
|
|
196
224
|
|
|
197
225
|
\`\`\`html
|
|
198
226
|
<article class="blog-post">
|
|
@@ -208,12 +236,44 @@ For dynamic collections beyond the built-ins:
|
|
|
208
236
|
</div>
|
|
209
237
|
{{/if}}
|
|
210
238
|
|
|
239
|
+
{{#if publishedAt}}
|
|
240
|
+
<time>{{publishedAt}}</time>
|
|
241
|
+
{{/if}}
|
|
242
|
+
|
|
211
243
|
<div class="content">
|
|
212
244
|
{{{postBody}}}
|
|
213
245
|
</div>
|
|
214
246
|
</article>
|
|
215
247
|
\`\`\`
|
|
216
248
|
|
|
249
|
+
## Team Template Pattern
|
|
250
|
+
|
|
251
|
+
\`\`\`html
|
|
252
|
+
<div class="team-grid">
|
|
253
|
+
{{#each team sort="order" order="asc"}}
|
|
254
|
+
<div class="team-member">
|
|
255
|
+
{{#if photo}}
|
|
256
|
+
<img src="{{photo}}" alt="{{name}}">
|
|
257
|
+
{{/if}}
|
|
258
|
+
<h3>{{name}}</h3>
|
|
259
|
+
{{#if role}}
|
|
260
|
+
<p class="role">{{role}}</p>
|
|
261
|
+
{{/if}}
|
|
262
|
+
{{#if bio}}
|
|
263
|
+
<div class="bio">{{{bio}}}</div>
|
|
264
|
+
{{/if}}
|
|
265
|
+
</div>
|
|
266
|
+
{{/each}}
|
|
267
|
+
</div>
|
|
268
|
+
\`\`\`
|
|
269
|
+
|
|
270
|
+
**CRITICAL FIELD NAMES for team:**
|
|
271
|
+
- \`{{name}}\` = Team member name
|
|
272
|
+
- \`{{role}}\` = Job title
|
|
273
|
+
- \`{{photo}}\` = Headshot (NOT {{picture}})
|
|
274
|
+
- \`{{{bio}}}\` = Biography (TRIPLE braces for HTML)
|
|
275
|
+
- \`{{order}}\` = Display order
|
|
276
|
+
|
|
217
277
|
## Static Page Pattern
|
|
218
278
|
|
|
219
279
|
\`\`\`html
|
|
@@ -363,33 +423,34 @@ Forms are automatically captured by the CMS.
|
|
|
363
423
|
|
|
364
424
|
## Form Handler Script
|
|
365
425
|
|
|
366
|
-
Add to your JavaScript:
|
|
426
|
+
Add to your JavaScript (typically /public/js/main.js):
|
|
367
427
|
|
|
368
428
|
\`\`\`javascript
|
|
369
429
|
document.querySelectorAll('form[data-form-name]').forEach(form => {
|
|
370
430
|
form.addEventListener('submit', async (e) => {
|
|
371
431
|
e.preventDefault();
|
|
372
432
|
|
|
433
|
+
const formName = form.dataset.formName || 'general';
|
|
373
434
|
const formData = new FormData(form);
|
|
374
435
|
const data = Object.fromEntries(formData);
|
|
375
436
|
|
|
376
|
-
|
|
437
|
+
// IMPORTANT: Endpoint is /_forms/{formName}
|
|
438
|
+
const response = await fetch('/_forms/' + formName, {
|
|
377
439
|
method: 'POST',
|
|
378
440
|
headers: { 'Content-Type': 'application/json' },
|
|
379
|
-
body: JSON.stringify(
|
|
380
|
-
formName: form.dataset.formName,
|
|
381
|
-
data: data
|
|
382
|
-
})
|
|
441
|
+
body: JSON.stringify(data)
|
|
383
442
|
});
|
|
384
443
|
|
|
385
444
|
if (response.ok) {
|
|
386
445
|
form.reset();
|
|
387
|
-
alert('Thank you!');
|
|
446
|
+
alert(form.dataset.successMessage || 'Thank you!');
|
|
388
447
|
}
|
|
389
448
|
});
|
|
390
449
|
});
|
|
391
450
|
\`\`\`
|
|
392
451
|
|
|
452
|
+
**CRITICAL:** The form endpoint is \`/_forms/{formName}\` - NOT \`/api/forms/submit\`
|
|
453
|
+
|
|
393
454
|
## Naming Conventions
|
|
394
455
|
|
|
395
456
|
- Contact form → \`contact\`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-schema.d.ts","sourceRoot":"","sources":["../../src/tools/get-schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"get-schema.d.ts","sourceRoot":"","sources":["../../src/tools/get-schema.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAmOjD"}
|
package/dist/tools/get-schema.js
CHANGED
|
@@ -178,5 +178,57 @@ For HTML content that should NOT be escaped:
|
|
|
178
178
|
3. **Always wrap optional fields in {{#if}}** - Check before rendering
|
|
179
179
|
4. **Use {{url}} for links** - Generates correct path based on manifest
|
|
180
180
|
5. **Match field names exactly** - \`{{name}}\` not \`{{title}}\`
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Form Handling
|
|
185
|
+
|
|
186
|
+
Forms are automatically captured and stored in the CMS.
|
|
187
|
+
|
|
188
|
+
### Form Setup
|
|
189
|
+
1. Add \`data-form-name="xxx"\` attribute to the form
|
|
190
|
+
2. Include the form handler script in your JavaScript
|
|
191
|
+
|
|
192
|
+
\`\`\`html
|
|
193
|
+
<form data-form-name="contact">
|
|
194
|
+
<input type="text" name="firstName" required>
|
|
195
|
+
<input type="email" name="email" required>
|
|
196
|
+
<textarea name="message"></textarea>
|
|
197
|
+
<button type="submit">Send</button>
|
|
198
|
+
</form>
|
|
199
|
+
\`\`\`
|
|
200
|
+
|
|
201
|
+
### Form Handler Script (add to /public/js/main.js)
|
|
202
|
+
\`\`\`javascript
|
|
203
|
+
document.querySelectorAll('form[data-form-name]').forEach(form => {
|
|
204
|
+
form.addEventListener('submit', async (e) => {
|
|
205
|
+
e.preventDefault();
|
|
206
|
+
const formName = form.dataset.formName || 'general';
|
|
207
|
+
const formData = new FormData(form);
|
|
208
|
+
const data = Object.fromEntries(formData);
|
|
209
|
+
|
|
210
|
+
const response = await fetch('/_forms/' + formName, {
|
|
211
|
+
method: 'POST',
|
|
212
|
+
headers: { 'Content-Type': 'application/json' },
|
|
213
|
+
body: JSON.stringify(data)
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
if (response.ok) {
|
|
217
|
+
form.reset();
|
|
218
|
+
alert(form.dataset.successMessage || 'Thank you!');
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
\`\`\`
|
|
223
|
+
|
|
224
|
+
**CRITICAL:** Endpoint is \`/_forms/{formName}\` - NOT \`/api/forms/submit\`
|
|
225
|
+
|
|
226
|
+
### Common Form Names
|
|
227
|
+
- \`contact\` - Contact/inquiry forms
|
|
228
|
+
- \`newsletter\` - Email signups
|
|
229
|
+
- \`quote-request\` - Quote/consultation requests
|
|
230
|
+
- \`appointment\` - Scheduling forms
|
|
231
|
+
|
|
232
|
+
Tenant context is handled automatically by the system.
|
|
181
233
|
`;
|
|
182
234
|
}
|
package/package.json
CHANGED