← All changes
|
modules/mcp/static-resources/abilities/build-composition.md
+35
-8
4.3.1
→
trunk
View file →
| @@ -16,10 +16,11 @@ | ||
| 16 | 16 | # WORKFLOW |
| 17 | 17 | 1. Check/create global variables via `elementor/manage-global-variable` |
| 18 | 18 | 2. Check/create global classes via `elementor/manage-classes` |
| 19 | 19 | 3. When component capabilities permit, prefer reusable components for cohesive structures that are repeated or likely to be reused |
| 20 | -4. Build composition (THIS TOOL) - minimal inline styles; attach existing global classes via `classes` | |
| 21 | -5. Use returned element IDs for subsequent configuration changes | |
| 20 | +4. Read the schema via `elementor/get-widget-schema` for every element type you will use, including basic containers like `e-div-block` and `e-flexbox` — their `llm_guidance.default_styles` shape the layout | |
| 21 | +5. Build composition (THIS TOOL) - minimal inline styles; attach existing global classes via `classes` | |
| 22 | +6. Use returned element IDs for subsequent configuration changes | |
| 22 | 23 | |
| 23 | 24 | ## CRITICAL: Avoid write conflicts after build-composition |
| 24 | 25 | `manage-elements` is a **read → modify → write** operation on the current document. If you call it after `build-composition` using element IDs from a **prior** `get-page-structure` read, it will restore the old tree and silently overwrite what `build-composition` just saved. |
| 25 | 26 | |
| @@ -26,8 +27,35 @@ | ||
| 26 | 27 | **Rules:** |
| 27 | 28 | - Only use element IDs from the `resolved_xml` in **this tool's response** for any follow-up `manage-elements` calls — never IDs from an earlier read. |
| 28 | 29 | - Prefer adding pseudo-states (`&:hover`, `&:focus`, `&:active`) and breakpoints (`@media (--mobile)`) **inline in the `style` string** during composition, eliminating the need for a follow-up `manage-elements` call entirely. |
| 29 | 30 | |
| 31 | +# ID RULES | |
| 32 | +`build-composition` uses two different identifiers. Do not mix them. | |
| 33 | + | |
| 34 | +## configuration-id (you choose; input only) | |
| 35 | +Use the XML attribute `configuration-id` on **every** element tag in `xml_structure` (including nested elements). This is the only allowed attribute on widget tags — no `id`, `class`, or other attributes. | |
| 36 | + | |
| 37 | +| Rule | Detail | | |
| 38 | +|------|--------| | |
| 39 | +| Uniqueness | Each `configuration-id` value must appear at most once in the `xml_structure` string for this call. Duplicates fail validation (`elementor_duplicate_configuration_id`). | | |
| 40 | +| Map keys | Keys in `element_config`, `style`, `classes`, and `interactions` must match a `configuration-id` in `xml_structure` **exactly** (case-sensitive string). Extra map keys with no matching element are ignored. Elements without map entries are still created. | | |
| 41 | +| Allowed values | Any non-empty string valid as a quoted XML attribute value (letters, numbers, spaces, hyphens, etc.). | | |
| 42 | +| Navigator title | The server copies the value into the element's `editor_settings.title`, so it is visible to the user in the editor — use human-readable labels. | | |
| 43 | +| Scope | Per request only. A `configuration-id` from an earlier call does not refer to the same widget later; it is not a persisted element id. | | |
| 44 | + | |
| 45 | +## Element id (server assigns; output and follow-up) | |
| 46 | +Never put element ids in `xml_structure`. The server generates a **new** id for every inserted element (including all descendants) on each successful save. | |
| 47 | + | |
| 48 | +| Rule | Detail | | |
| 49 | +|------|--------| | |
| 50 | +| Format | Server-generated lowercase hexadecimal string (one new id per inserted element). | | |
| 51 | +| Where to read | After a non-`dry_run` call: `resolved_xml` (each tag gains an `id="..."` attribute) and `root_element_ids` (top-level inserts). `dry_run` does not assign ids. | | |
| 52 | +| Reuse vs create | **Create:** every element in this composition gets a fresh server id — do not invent or recycle ids in input. **Reuse:** `parent_id` must be an existing container element id in the document (from `elementor/get-page-structure` or from `resolved_xml` of a prior save on this document). Use `document` (or omit `parent_id`) for root-level insertion. | | |
| 53 | +| Follow-up edits | For `elementor/manage-elements`, use only element ids from **this** response's `resolved_xml` (see write-conflict rules above). Never substitute a `configuration-id` where an element id is required. | | |
| 54 | + | |
| 55 | +## component_id (inside `element_config` for `<e-component>` only) | |
| 56 | +Integer post id of a reusable component from `elementor/list-components`. This is neither a `configuration-id` nor an element id. | |
| 57 | + | |
| 30 | 58 | # COMPONENTS (only when explicitly requested) |
| 31 | 59 | Elementor components are reusable widget compositions; global classes are reusable styles. Do not substitute one for the other. |
| 32 | 60 | |
| 33 | 61 | Call `elementor/list-components` before building a repeated, named, or otherwise reusable structure. Use its `capabilities` response to decide the flow: |
| @@ -39,10 +67,11 @@ | ||
| 39 | 67 | |
| 40 | 68 | # XML STRUCTURE |
| 41 | 69 | - Use widget tags: `<e-button configuration-id="btn1"></e-button>` |
| 42 | 70 | - Containers: "e-flexbox", "e-div-block", "e-tabs" |
| 43 | -- **Every element MUST have a unique "configuration-id" attribute** | |
| 44 | -- No attributes, classes, IDs, or text nodes in XML | |
| 71 | +- Every element needs a unique `configuration-id` — see **ID RULES** | |
| 72 | +- No other attributes, classes, element ids, or text nodes in XML | |
| 73 | +- Multiple root elements are allowed. Every opening tag needs exactly one matching closing tag (or use a self-closing tag); a stray or missing closing tag fails the whole call with `invalid_xml`, even on `dry_run` | |
| 45 | 74 | - Pass the raw XML tags directly as the `xml_structure` string. Do NOT wrap the value in `<![CDATA[ ... ]]>`, code fences, quotes, or any other wrapper — JSON string escaping is the only escaping needed. Wrapping in CDATA turns the whole payload into text and the tool will reject it with `empty_composition`. |
| 46 | 75 | |
| 47 | 76 | ## NESTED ELEMENTS |
| 48 | 77 | Some elements have internal tree structures (nesting). When using these elements, you MUST build the FULL tree in XML. |
| @@ -83,9 +112,9 @@ | ||
| 83 | 112 | - **text** (`title` on `e-heading`, `paragraph` on `e-paragraph`, `text` on `e-button`): plain string (`"Welcome"`). May contain inline HTML tags for text styling. |
| 84 | 113 | - Example: `"paragraph": "<strong>Contact support</strong> for a <s>free</s> discounted quote — <em>limited time</em> only."` |
| 85 | 114 | - **dynamic** (where schema allows): `{ "name": "<tag from elementor://dynamic-tags>", "settings": { ... } }` — settings use plain values per the tag schema; omit `group` |
| 86 | 115 | - **image**: two forms, `id` and `url` are mutually exclusive — send one, not both: |
| 87 | - - Library asset (from `elementor/list-assets` tool): `{ "src": { "id": 123 }, "size": "full" }`. | |
| 116 | + - Library asset (from `elementor/list-assets` tool): `{ "src": { "id": 123 }, "size": "full" }`. Don't send `alt` with `id`; library images render the attachment's Media Library alt text, so ask the user to update it there if it's missing. | |
| 88 | 117 | - External URL: `{ "src": { "url": "https://example.com/photo.jpg" }, "size": "full" }` — works. If no library asset fits and no on-brand external image is available, tell the user which images to upload. |
| 89 | 118 | - **svg** (the `svg` prop on `e-svg`): `{ "id": <attachment id from elementor/list-assets with type: "svg"> }`. An external URL on `e-svg` renders an empty div. If no uploaded SVG exists, ask the user to upload one, otherwise omit the icon or use a text label — never fabricate an id. |
| 90 | 119 | - **video** (the `source` prop on `e-self-hosted-video` and `e-background-video`): two forms, `id` and `url` are mutually exclusive — send one, not both: |
| 91 | 120 | - Library asset (from `elementor/list-assets` with `type: "video"`): `{ "id": 123 }` |
| @@ -117,10 +146,8 @@ | ||
| 117 | 146 | - Example (image `src`): `"image": { "src": { "name": "<image tag>", "settings": { ... } }, "size": "full" }` |
| 118 | 147 | - The tag's categories must intersect the categories declared by the field (visible in the widget schema's dynamic branch). Pick a tag from [elementor://dynamic-tags] whose category list overlaps. A category mismatch returns an error for that field and skips merging it. |
| 119 | 148 | - Do NOT send `group` (resolved automatically). Populate `settings` strictly per the tag's schema; use `{}` only when it has none. |
| 120 | 149 | |
| 121 | -Note about configuration ids: These names are visible to the end-user, make sure they make sense, related and relevant. | |
| 122 | - | |
| 123 | 150 | # DESIGN PHILOSOPHY: CONTEXT-DRIVEN CREATIVITY |
| 124 | 151 | |
| 125 | 152 | **Use the user's context aggressively.** Business type, brand personality, target audience, and purpose should drive every design decision. A law firm needs gravitas; a children's app needs playfulness. Don't default to generic. |
| 126 | 153 | |
| @@ -231,7 +258,7 @@ | ||
| 231 | 258 | ``` |
| 232 | 259 | Note: No height/width specified on any element - flexbox handles layout automatically. |
| 233 | 260 | |
| 234 | 261 | # FURTHER INSTRUCTIONS |
| 235 | -Element IDs in the returned XML represent actual widgets. Use these IDs for subsequent styling or configuration changes. | |
| 262 | +Use server-assigned element ids from `resolved_xml` for follow-up work — see **ID RULES**. | |
| 236 | 263 | |
| 237 | 264 | If components were requested or used, verify that each was created or placed successfully before reporting completion. |