@bettercms-ai/mcp 0.73.2 → 0.74.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 +154 -19
- package/dist/index.js.map +1 -1
- package/dist/kit-catalog.json +1362 -0
- package/dist/skills/bettercms/SKILL.md +4 -1
- package/dist/skills/bettercms/references/content-modeling.md +5 -0
- package/dist/skills/bettercms/references/detection.md +15 -0
- package/dist/skills/bettercms/references/kit-catalog.md +3259 -0
- package/dist/skills/bettercms/references/kit-scenarios.md +712 -0
- package/dist/skills/bettercms/references/worked-examples.md +146 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Worked examples"
|
|
3
|
-
description: "
|
|
3
|
+
description: "Six conversions from source HTML to a production schema, a production value and a bound template: hero, feature grid, pricing with a comparison table, testimonials as a collection, FAQ with FAQPage markup, bento grid with per-cell sizes."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Worked examples: source HTML to schema, value and bound template
|
|
@@ -20,6 +20,7 @@ its binding attributes. Copy the shape, never the customer's words. Rules behind
|
|
|
20
20
|
- [3. Pricing plans with a comparison table](#3-pricing-plans-with-a-comparison-table)
|
|
21
21
|
- [4. Testimonials kept as a collection](#4-testimonials-kept-as-a-collection)
|
|
22
22
|
- [5. FAQ accordion with FAQPage markup](#5-faq-accordion-with-faqpage-markup)
|
|
23
|
+
- [9. Bento grid with per-cell sizes](#9-bento-grid-with-per-cell-sizes)
|
|
23
24
|
- [Checks after any example](#checks-after-any-example)
|
|
24
25
|
- Examples 6 to 8 (blog post as an entry, mega menu in the Global Layout, tabs holding columns
|
|
25
26
|
of cards): [worked-examples-advanced.md](worked-examples-advanced.md)
|
|
@@ -35,6 +36,7 @@ Production stores content in four places. Pick by what the markup is, then follo
|
|
|
35
36
|
| Records that repeat on one route | Content model and entries | `create_content_model` | `create_content_entry` | the entry's field key | 4, 6 (advanced) |
|
|
36
37
|
| Header, footer, promo bar | Global Layout Section | `update_layout` | `update_layout` | `data-bcms-layout-field` | 7 (advanced) |
|
|
37
38
|
| A one-off band built from blocks | `section` block with child blocks | `update_page` `blockJson` | the same call | `<blockId>__<prop>` | 8 (advanced) |
|
|
39
|
+
| Cells of different kinds, each with its own size | Component with a `slot` list and `slotSettings` | `create_component` | `compose_pages` | `<instanceId>__overrides.<key>` | 9 |
|
|
38
40
|
|
|
39
41
|
Rules that hold in every example:
|
|
40
42
|
|
|
@@ -728,6 +730,149 @@ Not available today: FAQPage markup that appears on its own. Without `schemaType
|
|
|
728
730
|
page gets WebPage. An "open several at once" setting has no field type of its own; if editors
|
|
729
731
|
need it, add a `boolean` field and have the template read it.
|
|
730
732
|
|
|
733
|
+
## 9. Bento grid with per-cell sizes
|
|
734
|
+
|
|
735
|
+
Source: the cookware brand's home page. The kit's `core-bento` entry is this shape, and
|
|
736
|
+
`bento-feature-showcase` is its responsive long form ([kit-scenarios.md](kit-scenarios.md)).
|
|
737
|
+
|
|
738
|
+
```html
|
|
739
|
+
<section class="bento" id="field">
|
|
740
|
+
<p class="eyebrow">In the field</p>
|
|
741
|
+
<h2>Made to be handed down.</h2>
|
|
742
|
+
<div class="bento__grid grid grid-cols-4 gap-6">
|
|
743
|
+
<figure class="cell col-span-2 row-span-2 cell--dark">
|
|
744
|
+
<img src="/img/sierra-dawn-2400.jpg" alt="Dawn over a Sierra camp, kettle steaming" width="2400" height="2400">
|
|
745
|
+
<figcaption>Three nights in the Sierra</figcaption>
|
|
746
|
+
</figure>
|
|
747
|
+
<div class="cell cell--brand"><i class="ti ti-flame" aria-hidden="true"></i>
|
|
748
|
+
<span class="stat__value">120k+</span><span class="stat__label">Fires cooked over</span></div>
|
|
749
|
+
<div class="cell"><i class="ti ti-star" aria-hidden="true"></i>
|
|
750
|
+
<span class="stat__value">4.9</span><span class="stat__label">Average review</span></div>
|
|
751
|
+
<blockquote class="cell col-span-2"><p>Our restaurant runs four Ember ovens over live fire every night.</p>
|
|
752
|
+
<cite>Chef Amara Osei, Hearth & Ash, Portland</cite></blockquote>
|
|
753
|
+
</div>
|
|
754
|
+
</section>
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
Reasoning:
|
|
758
|
+
|
|
759
|
+
1. The grid's children differ in shape (an image, two stats, a quote) and in size. Different
|
|
760
|
+
shapes chosen by the editor are slot children, not rows of one list.
|
|
761
|
+
2. Each cell's size and surface belong to its place in this grid, not to the cell. Reading
|
|
762
|
+
`col-span-2 row-span-2` and `cell--dark` into the image tile's own props would carry a
|
|
763
|
+
meaningless span to every other page that reuses the tile. They go in the slot's settings.
|
|
764
|
+
3. Size is a small set of presets (1 × 1, 2 × 1, 1 × 2, 2 × 2), so it is a select, never a free
|
|
765
|
+
column number. If the source's spans do not fit four presets, it is the per-cell grid
|
|
766
|
+
(`grid-cell-layout`), not a bento.
|
|
767
|
+
4. The four-column versus three-column layout is a variant: a second component sharing the
|
|
768
|
+
`sectionType`, with the same prop keys.
|
|
769
|
+
5. The icons and the gap between cells are design: they stay in the template's classes.
|
|
770
|
+
|
|
771
|
+
Schema: one component per tile kind (`create_component`, then `publish_component`). The stat tile:
|
|
772
|
+
|
|
773
|
+
```json
|
|
774
|
+
{
|
|
775
|
+
"name": "Stat tile",
|
|
776
|
+
"slug": "stat-tile",
|
|
777
|
+
"category": "content",
|
|
778
|
+
"description": "A big number with a short label.",
|
|
779
|
+
"blockJson": [
|
|
780
|
+
{ "type": "section", "id": "stat-root", "props": { "children": [
|
|
781
|
+
{ "type": "text", "id": "stat-value", "props": { "html": "" } },
|
|
782
|
+
{ "type": "text", "id": "stat-label", "props": { "html": "" } }
|
|
783
|
+
] } }
|
|
784
|
+
],
|
|
785
|
+
"props": [
|
|
786
|
+
{ "key": "value", "label": "Number", "type": "text", "target": { "blockId": "stat-value", "path": "props.html" } },
|
|
787
|
+
{ "key": "label", "label": "Label", "type": "text", "target": { "blockId": "stat-label", "path": "props.html" } }
|
|
788
|
+
]
|
|
789
|
+
}
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
The image tile (`image`, `caption`) and the quote tile (`quote`, `author`, `role`) are built the
|
|
793
|
+
same way. Then the grid, whose `cells` slot lists them:
|
|
794
|
+
|
|
795
|
+
```json
|
|
796
|
+
{
|
|
797
|
+
"name": "Bento grid",
|
|
798
|
+
"slug": "bento-grid",
|
|
799
|
+
"sectionType": "bento",
|
|
800
|
+
"category": "section",
|
|
801
|
+
"description": "A mosaic of image, stat and quote cells, each with its own size and surface.",
|
|
802
|
+
"blockJson": [
|
|
803
|
+
{ "type": "section", "id": "bento-root", "props": { "children": [
|
|
804
|
+
{ "type": "text", "id": "bento-eyebrow", "props": { "html": "" } },
|
|
805
|
+
{ "type": "heading", "id": "bento-title", "props": { "text": "", "level": 2 } },
|
|
806
|
+
{ "type": "section", "id": "bento-cells", "props": { "children": [] } }
|
|
807
|
+
] } }
|
|
808
|
+
],
|
|
809
|
+
"props": [
|
|
810
|
+
{ "key": "eyebrow", "label": "Eyebrow", "type": "text", "target": { "blockId": "bento-eyebrow", "path": "props.html" } },
|
|
811
|
+
{ "key": "heading", "label": "Heading", "type": "text", "target": { "blockId": "bento-title", "path": "props.text" } },
|
|
812
|
+
{ "key": "cells", "label": "Cells", "type": "slot",
|
|
813
|
+
"target": { "blockId": "bento-cells", "path": "props.children" },
|
|
814
|
+
"config": {
|
|
815
|
+
"multiple": true, "minItems": 3, "maxItems": 9,
|
|
816
|
+
"componentIds": ["<image tile id>", "<stat tile id>", "<quote tile id>"],
|
|
817
|
+
"slotSettings": [
|
|
818
|
+
{ "key": "span", "label": "Size", "type": "select", "defaultValue": "1x1",
|
|
819
|
+
"options": [
|
|
820
|
+
{ "value": "1x1", "label": "Small" }, { "value": "2x1", "label": "Wide" },
|
|
821
|
+
{ "value": "1x2", "label": "Tall" }, { "value": "2x2", "label": "Large" } ] },
|
|
822
|
+
{ "key": "tone", "label": "Surface", "type": "select", "defaultValue": "light",
|
|
823
|
+
"options": [
|
|
824
|
+
{ "value": "light", "label": "Light" }, { "value": "dark", "label": "Dark" },
|
|
825
|
+
{ "value": "brand", "label": "Brand" } ] }
|
|
826
|
+
] } }
|
|
827
|
+
]
|
|
828
|
+
}
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
Value: the instance, inside the page's whole `blockJson` (`update_page` with `ifMatch`, or
|
|
832
|
+
`compose_pages`). Each cell names its tile component in `_type`, holds that tile's props at its
|
|
833
|
+
root, and its place in the grid in `_settings`:
|
|
834
|
+
|
|
835
|
+
```json
|
|
836
|
+
{ "type": "component", "id": "home-bento", "props": { "componentId": "<bento grid id>", "overrides": {
|
|
837
|
+
"eyebrow": "In the field",
|
|
838
|
+
"heading": "Made to be handed down.",
|
|
839
|
+
"cells": [
|
|
840
|
+
{ "_key": "g1", "_type": "<image tile id>", "_settings": { "span": "2x2", "tone": "dark" },
|
|
841
|
+
"image": "/img/sierra-dawn-2400.jpg", "caption": "Three nights in the Sierra" },
|
|
842
|
+
{ "_key": "g2", "_type": "<stat tile id>", "_settings": { "span": "1x1", "tone": "brand" },
|
|
843
|
+
"value": "120k+", "label": "Fires cooked over" },
|
|
844
|
+
{ "_key": "g3", "_type": "<stat tile id>", "_settings": { "span": "1x1", "tone": "light" },
|
|
845
|
+
"value": "4.9", "label": "Average review" },
|
|
846
|
+
{ "_key": "g4", "_type": "<quote tile id>", "_settings": { "span": "2x1", "tone": "light" },
|
|
847
|
+
"quote": "Our restaurant runs four Ember ovens over live fire every night.",
|
|
848
|
+
"author": "Chef Amara Osei", "role": "Hearth & Ash, Portland" }
|
|
849
|
+
] } } }
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
Bound template: render the blocks with `BcmsBlocks`. Each cell arrives as a `component` block
|
|
853
|
+
whose `props.slotSettings` holds its `_settings`; the template turns `span` and `tone` into its own
|
|
854
|
+
grid and surface classes.
|
|
855
|
+
|
|
856
|
+
```html
|
|
857
|
+
<section data-bcms-block="home-bento">
|
|
858
|
+
<p data-bcms-field="home-bento__overrides.eyebrow" data-bcms-kind="text">In the field</p>
|
|
859
|
+
<h2 data-bcms-field="home-bento__overrides.heading" data-bcms-kind="text">Made to be handed down.</h2>
|
|
860
|
+
<div class="bento__grid grid grid-cols-4 gap-6">
|
|
861
|
+
<figure class="cell col-span-2 row-span-2 cell--dark">…</figure>
|
|
862
|
+
</div>
|
|
863
|
+
</section>
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
- A `_settings` value that does not fit the slot's `slotSettings` is refused, naming the cell's
|
|
867
|
+
`_key`; a slot with no `slotSettings` takes no `_settings` at all.
|
|
868
|
+
- `_key` is the cell's identity: keep it stable across reorders.
|
|
869
|
+
- Publish every tile component before the grid: a draft child renders nothing.
|
|
870
|
+
- A cell's copy is edited in the placement's `cells` list, not by clicking it on the canvas
|
|
871
|
+
([components.md](components.md) §1).
|
|
872
|
+
|
|
873
|
+
Not available today: spans that depend on the variant's column count (validate them yourself),
|
|
874
|
+
per-breakpoint spans, and a phone order per cell.
|
|
875
|
+
|
|
731
876
|
## Checks after any example
|
|
732
877
|
|
|
733
878
|
1. Read back what you wrote: `get_page`, `get_component` or `get_layout`. A richtext value comes
|
package/package.json
CHANGED