@ebitex/content-mcp 1.1.264 → 1.1.268
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/README.md +3 -1
- package/dist/resources/helpCorpus.generated.d.ts.map +1 -1
- package/dist/resources/helpCorpus.generated.js +8 -3
- package/dist/resources/helpCorpus.generated.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +4 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,7 +95,9 @@ field it names, call again.
|
|
|
95
95
|
|
|
96
96
|
Alongside the tools, the server offers the Content documentation as MCP resources — start with
|
|
97
97
|
`ebitex-content://help/agent-authoring`, which explains what Contracts, Templates, Presentations,
|
|
98
|
-
Adapters and the Experience tree are for, and the order to create them in.
|
|
98
|
+
Adapters and the Experience tree are for, and the order to create them in. Then read
|
|
99
|
+
`ebitex-content://help/content-modelling` before you decide what the model looks like: it says what belongs in a Contract and what in a Template,
|
|
100
|
+
which field to use, how to name things, how to build containers such as tabs and accordions, and how to ship a model to others.
|
|
99
101
|
|
|
100
102
|
## Embedding it
|
|
101
103
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpCorpus.generated.d.ts","sourceRoot":"","sources":["../../src/resources/helpCorpus.generated.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAErE,eAAO,MAAM,WAAW,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"helpCorpus.generated.d.ts","sourceRoot":"","sources":["../../src/resources/helpCorpus.generated.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAErE,eAAO,MAAM,WAAW,EAAE,SAAS,EA4JlC,CAAA"}
|
|
@@ -6,7 +6,7 @@ export const HELP_TOPICS = [
|
|
|
6
6
|
{
|
|
7
7
|
"slug": "agent-authoring",
|
|
8
8
|
"title": "Building a content model through the API",
|
|
9
|
-
"body": "# Building a content model through the API\n\nThe rest of this help corpus describes Content as you drive it in Composer — tabs, panels, buttons.\nThe concepts all transfer; the steps do not. This page is the same model described in terms of the\nAPI, for a script or an agent working through the Content Management API rather than the interface.\n\nRead this first if you are about to create anything. Everything here is about *what the pieces are*;\nthe exact shape of each request is answered live by the API itself, and you should never guess it.\n\n## The one rule that saves the most time\n\n**Ask the server what things look like; do not assume.**\n\n`GET /field-types` returns every field type this platform has, each with its **own JSON Schema for\nits settings**. That schema is generated from the field type's own definition, so it is never out of\ndate — Composer's Contract builder renders its settings form from exactly this, rather than\nhard-coding a form per type. Use it the same way.\n\n`GET /contracts` and `GET /templates` tell you what this environment already has. Check before\ncreating: a duplicate is much harder to undo than it is to avoid.\n\nWhen a write is refused, the refusal names the failing field and says what is wrong with it. That\nmessage is the fastest route to a correct request. Read it and correct the one thing it names,\nrather than rewriting the payload.\n\n## The pieces, and what each one is for\n\nContent separates four concerns that many systems collapse into one. The separation is the reason\nthe same content can be rendered several ways, and reused in places its author never anticipated.\n\n### Contract — what content *is*\n\nA Contract is a type. It has a name, an external id, and a list of **fields**. Each field names a\nfield type (short text, rich text, number, date, blob, reference, component, presentation, category,\nlink, and so on) and carries that type's own settings.\n\nContracts support **inheritance**. A Contract may name a parent, and it then has the parent's fields\nplus its own. A Contract may be **abstract**, meaning nothing is ever an instance of it directly —\nit exists to be inherited from, and to be named where several concrete types should be accepted.\n\nContracts describe content and nothing about how it looks. No colours, no layout, no \"variant\".\n\n### Component — an instance of a Contract\n\nA Component is a piece of content: a Contract, plus a **document** holding a value for each field.\nIt has its own name and external id and lives in a folder.\n\nThe document's shape follows the Contract's fields exactly. What a field's value looks like depends\non its type *and* on its modifiers, below.\n\n### Template — how content is *rendered*\n\nA Template names which Contracts it can render, and has its own **settings Contract**: an ordinary\nContract describing the presentational choices that template offers — a variant, an alignment, how\nmany columns.\n\nThis is why Contracts stay free of presentation. \"A statement, centred, with a ghost button\" is one\nTemplate's settings over a plain statement Contract, not three fields on the Contract itself.\n\n### Presentation — a Template bound to content\n\nA **presentation value** is where the two meet: it names a Template, binds a Component (or holds an\ninline document), and carries settings and contextual values for this one use.\n\nA page is usually a Component whose fields hold presentation values — a hero, then some sections —\nand each of those points at content that may be used elsewhere, rendered differently.\n\n### Adapter — a reusable mapping between Contracts\n\nSometimes a Template needs a `card` and what you have is a `blog-page`. An Adapter is a named,\nreusable mapping from one Contract to another: one rule per output field, plus a small set of logic\nnodes for lists, conditions and type dispatch.\n\nAn Adapter is applied by the server — at preview, at publish, and at delivery — so the mapping is\ndefined once and behaves identically everywhere.\n\n### Experience — where content lives on the web\n\nThe Experience tree is the site's address space. A **site** is a root; **nodes** under it are pages,\neach with a slug. A node's path is its ancestors' slugs plus its own.\n\nA node's **payload** says what it renders — usually a presentation value, sometimes a redirect,\nsometimes nothing at all (a node with no payload is pure structure, giving its children a path\nsegment without being a page itself).\n\nCreating a node and setting its payload are **two separate calls**. That is not an oversight: a\nnode's identity and location change for different reasons than its content does.\n\n## The five modifiers\n\nAny field can carry any combination of these. They compose, and each one changes the shape of the\nvalue stored in the document — which is the part worth understanding before writing one.\n\n| Modifier | What it means | Effect on the value |\n|---|---|---|\n| Mandatory | A value is required | Validation refuses an empty one |\n| Enumerable | Many rather than one | The value becomes a list |\n| Localizable | Translatable per locale | The value becomes `{ default, translations }` |\n| Personalizable | Varies by audience | The value becomes `{ default, variants }` |\n| Contextual | Overridable per use | The value may be supplied where the Component is *used*, not only where it is defined |\n\nCardinality is Enumerable's job, never the field type's. There is no \"list of text\" field type;\nthere is a text field that is enumerable.\n\n**Contextual** is the one worth dwelling on, because it has no counterpart in most systems. A\ncontextual field's value can be set on the Component (a default) *and* overridden by whoever binds\nthat Component somewhere — a heading that reads one way on the home page and another on a listing,\nfrom one Component with one document. Those overrides are the `contextualValues` that travel with a\nreference or a presentation value.\n\n## An order of operations that works\n\nDependencies run one way, so build in this order and nothing is ever waiting on something that does\nnot exist yet.\n\n1. **Describe.** `GET /field-types`, `/contracts`, `/templates`. Learn what exists before adding to\n it.\n2. **Contracts.** Parents before children, since a child names its parent.\n3. **Templates.** After the Contracts they render, since a Template names them.\n4. **Components.** After their Contract, and after any Contract they reference.\n5. **A site**, if the environment has none. Then **nodes** under it, parents before children.\n6. **Node payloads.** After both the node and the Component it binds.\n7. **Publish.** Plan first, read the blockers, then publish.\n\nTwo ordering facts that are easy to get wrong: a Component referencing another Component needs that\none to exist first, and publishing follows the dependency closure automatically — so publishing a\npage will normally publish the content it binds, and the plan is where you see exactly what that\nmeans before it happens.\n\n## Publishing\n\nPublishing is two calls, and collapsing them would hide the thing that matters.\n\n**Plan** resolves the full dependency closure of what you asked to publish and reports every\n**blocker** — an unresolvable reference, a workflow state that forbids publishing, a document that\nfails validation. **Execute** publishes what the plan named.\n\nBoth are jobs: each returns an operation id, and you poll it. A real closure is too large to finish\ninside an HTTP request, which is why.\n\nRead the plan. It is the only place the system tells you what is about to change beyond what you\nexplicitly named.\n\n## Where writes land\n\nA management key is bound to exactly one organization and one **authoring environment**, and it acts\nas one **role**. It cannot reach another environment, and it is subject to the same branch access\nrules and workflow gating a person with that role is.\n\nThat binding is the real safety boundary, so it is worth confirming rather than assuming: ask the\nAPI who the key is before writing anything. If the answer is not the environment you expected, stop\n— nothing else about the request will tell you.\n\nThen ask where the environment sits (`GET /topology`, or the `content_topology` tool). It names this\nenvironment's direct neighbours, and each one tells you something about your own work:\n\n- **Publishes to.** Where a publish from here lands. If one of these is a live website, a publish\n changes that website. With two or more, a publish has to say which one.\n- **Inherited content.** A refusal saying content is inherited means another realm owns it and the\n change has to be made there instead (a person can edit it from the app, and the edit is written in\n the realm that owns it; a connection never writes through to another realm).\n- **Promoted from.** Someone promoting from one of these can overwrite what you write here.\n- **Promotes to.** Where this content goes when someone promotes it. You cannot promote yourself.\n\nNothing in the answer says which environment is production. Judge that from the names, and ask the\nperson you are working for when it is not obvious.\n\n## What an empty answer means\n\nThe binding governs **reads** exactly as it governs writes, and that changes how an empty result\nshould be read. `GET /contracts` returning nothing means *this environment has no Contracts*. It does\nnot mean the organization has none, and it certainly does not mean the account has no content.\n\nThe difference matters because acting on the wrong reading is expensive in one direction: concluding\n\"nothing exists\" and creating a model that already exists elsewhere produces duplicates, which are\nmuch harder to undo than to avoid. The safe habit is to confirm the scope before concluding anything\nfrom an empty list — `GET /whoami`, or the `content_whoami` tool, which needs no permissions at all\nprecisely so that a key holding almost nothing can still ask.\n\nA `404` on a single-entity read is the same fact in another shape: not found *here*. The entity may\nexist in another environment, and this key cannot see it.\n\n## When a write is refused for a permission\n\nA key has two limits, and they are different. Its **scopes** say which kinds of call it may make at\nall (`read`, `authoring`, `publish`). The **role it runs as** says what that role may do, and a few\nkinds need a permission on top of the `authoring` scope:\n\n| To write or delete | The role needs |\n|---|---|\n| a Contract | `content.contracts.manage` |\n| a Template | `content.templates.manage` |\n\nThe Member role does not hold either. The `ContentSchemaAdmin` role holds both, as does Owner, but\nOwner grants far more than an agent needs; prefer `ContentSchemaAdmin` or a custom role with just\nthese. Any role in the organization can be chosen as a key's \"run as\" role.\n\nA refusal for this reason is `403 permission_denied`, and it names the permission. The MCP server\nsays so plainly and, when it already knows the role lacks the permission, declines the call without\nsending it. `content_whoami` lists the kinds withheld for this role, each with the permission it\nneeds. When you see this, tell the person which permission is missing; changing the role is theirs\nto do, in the key's settings, and not something to work around.\n\n## Things that commonly go wrong\n\n- **Guessing a field type's settings** instead of reading its schema. Every field type declares its\n own; there is nothing to guess.\n- **Creating a duplicate** because an external id was not checked first. External ids are how a\n model refers to itself across environments; a duplicate is a lasting problem.\n- **Putting presentation on a Contract.** If you are adding a field called `variant`, `align`,\n `theme` or `columns` to a Contract, it almost certainly belongs in a Template's settings.\n- **Forgetting a node's payload.** A node created and never given one is a real, published,\n completely blank page.\n- **Treating a publish plan as a formality.** It is where blockers appear, and they do not appear\n anywhere else until something is already wrong.\n\n## Rendering the site is a separate job\n\nEverything above builds the content. The site that shows it reads the published result from the\nContent Delivery API, and for that there is a client: **`@ebitex/content-sdk`** (npm), or\n`Ebitex.Content.Delivery` on a .NET server. Read [Rendering your site](rendering-your-site.md)\nbefore you write any code that fetches published content, and do not write a Delivery client by\nhand without a reason.\n\n## Related\n\n- [Contracts](contracts.md) — the type system in depth\n- [Templates](templates.md) — presentation\n- [Components](components.md) — authoring content\n- [Content Adapters](content-adapters.md) — mappings\n- [Composer](content-composer.md) — the Experience tree\n- [Publishing](publishing.md) — the publish pipeline\n- [Management keys](management-keys.md) — minting and scoping a key\n- [Rendering your site](rendering-your-site.md) — the SDK that reads what you publish\n"
|
|
9
|
+
"body": "# Building a content model through the API\n\nThe rest of this help corpus describes Content as you drive it in Composer — tabs, panels, buttons.\nThe concepts all transfer; the steps do not. This page is the same model described in terms of the\nAPI, for a script or an agent working through the Content Management API rather than the interface.\n\nRead this first if you are about to create anything. Everything here is about *what the pieces are*;\nthe exact shape of each request is answered live by the API itself, and you should never guess it.\n\nThen read [Modelling your content: best practices](content-modelling.md) before you decide what the model looks like: it covers what belongs in a Contract and what belongs in a Template, which field to use, naming, allow-lists, containers and shipping a model to others. A model built without it tends to put presentation in the content, which is the hardest mistake to undo.\n\n## The one rule that saves the most time\n\n**Ask the server what things look like; do not assume.**\n\n`GET /field-types` returns every field type this platform has, each with its **own JSON Schema for\nits settings**. That schema is generated from the field type's own definition, so it is never out of\ndate — Composer's Contract builder renders its settings form from exactly this, rather than\nhard-coding a form per type. Use it the same way.\n\n`GET /contracts` and `GET /templates` tell you what this environment already has. Check before\ncreating: a duplicate is much harder to undo than it is to avoid.\n\nWhen a write is refused, the refusal names the failing field and says what is wrong with it. That\nmessage is the fastest route to a correct request. Read it and correct the one thing it names,\nrather than rewriting the payload.\n\n## The pieces, and what each one is for\n\nContent separates four concerns that many systems collapse into one. The separation is the reason\nthe same content can be rendered several ways, and reused in places its author never anticipated.\n\n### Contract — what content *is*\n\nA Contract is a type. It has a name, an external id, and a list of **fields**. Each field names a\nfield type (short text, rich text, number, date, blob, reference, component, presentation, category,\nlink, and so on) and carries that type's own settings.\n\nContracts support **inheritance**. A Contract may name a parent, and it then has the parent's fields\nplus its own. A Contract may be **abstract**, meaning nothing is ever an instance of it directly —\nit exists to be inherited from, and to be named where several concrete types should be accepted.\n\nContracts describe content and nothing about how it looks. No colours, no layout, no \"variant\".\n\n### Component — an instance of a Contract\n\nA Component is a piece of content: a Contract, plus a **document** holding a value for each field.\nIt has its own name and external id and lives in a folder.\n\nThe document's shape follows the Contract's fields exactly. What a field's value looks like depends\non its type *and* on its modifiers, below.\n\n### Template — how content is *rendered*\n\nA Template names which Contracts it can render, and has its own **settings Contract**: an ordinary\nContract describing the presentational choices that template offers — a variant, an alignment, how\nmany columns.\n\nThis is why Contracts stay free of presentation. \"A statement, centred, with a ghost button\" is one\nTemplate's settings over a plain statement Contract, not three fields on the Contract itself.\n\n### Presentation — a Template bound to content\n\nA **presentation value** is where the two meet: it names a Template, binds a Component (or holds an\ninline document), and carries settings and contextual values for this one use.\n\nA page is usually a Component whose fields hold presentation values — a hero, then some sections —\nand each of those points at content that may be used elsewhere, rendered differently.\n\n### Adapter — a reusable mapping between Contracts\n\nSometimes a Template needs a `card` and what you have is a `blog-page`. An Adapter is a named,\nreusable mapping from one Contract to another: one rule per output field, plus a small set of logic\nnodes for lists, conditions and type dispatch.\n\nAn Adapter is applied by the server — at preview, at publish, and at delivery — so the mapping is\ndefined once and behaves identically everywhere.\n\n### Experience — where content lives on the web\n\nThe Experience tree is the site's address space. A **site** is a root; **nodes** under it are pages,\neach with a slug. A node's path is its ancestors' slugs plus its own.\n\nA node's **payload** says what it renders — usually a presentation value, sometimes a redirect,\nsometimes nothing at all (a node with no payload is pure structure, giving its children a path\nsegment without being a page itself).\n\nCreating a node and setting its payload are **two separate calls**. That is not an oversight: a\nnode's identity and location change for different reasons than its content does.\n\n## The five modifiers\n\nAny field can carry any combination of these. They compose, and each one changes the shape of the\nvalue stored in the document — which is the part worth understanding before writing one.\n\n| Modifier | What it means | Effect on the value |\n|---|---|---|\n| Mandatory | A value is required | Validation refuses an empty one |\n| Enumerable | Many rather than one | The value becomes a list |\n| Localizable | Translatable per locale | The value becomes `{ default, translations }` |\n| Personalizable | Varies by audience | The value becomes `{ default, variants }` |\n| Contextual | Overridable per use | The value may be supplied where the Component is *used*, not only where it is defined |\n\nCardinality is Enumerable's job, never the field type's. There is no \"list of text\" field type;\nthere is a text field that is enumerable.\n\n**Contextual** is the one worth dwelling on, because it has no counterpart in most systems. A\ncontextual field's value can be set on the Component (a default) *and* overridden by whoever binds\nthat Component somewhere — a heading that reads one way on the home page and another on a listing,\nfrom one Component with one document. Those overrides are the `contextualValues` that travel with a\nreference or a presentation value.\n\n## An order of operations that works\n\nDependencies run one way, so build in this order and nothing is ever waiting on something that does\nnot exist yet.\n\n1. **Describe.** `GET /field-types`, `/contracts`, `/templates`. Learn what exists before adding to\n it.\n2. **Contracts.** Parents before children, since a child names its parent.\n3. **Templates.** After the Contracts they render, since a Template names them.\n4. **Components.** After their Contract, and after any Contract they reference.\n5. **A site**, if the environment has none. Then **nodes** under it, parents before children.\n6. **Node payloads.** After both the node and the Component it binds.\n7. **Publish.** Plan first, read the blockers, then publish.\n\nTwo ordering facts that are easy to get wrong: a Component referencing another Component needs that\none to exist first, and publishing follows the dependency closure automatically — so publishing a\npage will normally publish the content it binds, and the plan is where you see exactly what that\nmeans before it happens.\n\n## Publishing\n\nPublishing is two calls, and collapsing them would hide the thing that matters.\n\n**Plan** resolves the full dependency closure of what you asked to publish and reports every\n**blocker** — an unresolvable reference, a workflow state that forbids publishing, a document that\nfails validation. **Execute** publishes what the plan named.\n\nBoth are jobs: each returns an operation id, and you poll it. A real closure is too large to finish\ninside an HTTP request, which is why.\n\nRead the plan. It is the only place the system tells you what is about to change beyond what you\nexplicitly named.\n\n## Where writes land\n\nA management key is bound to exactly one organization and one **authoring environment**, and it acts\nas one **role**. It cannot reach another environment, and it is subject to the same branch access\nrules and workflow gating a person with that role is.\n\nThat binding is the real safety boundary, so it is worth confirming rather than assuming: ask the\nAPI who the key is before writing anything. If the answer is not the environment you expected, stop\n— nothing else about the request will tell you.\n\nThen ask where the environment sits (`GET /topology`, or the `content_topology` tool). It names this\nenvironment's direct neighbours, and each one tells you something about your own work:\n\n- **Publishes to.** Where a publish from here lands. If one of these is a live website, a publish\n changes that website. With two or more, a publish has to say which one.\n- **Inherited content.** A refusal saying content is inherited means another realm owns it and the\n change has to be made there instead (a person can edit it from the app, and the edit is written in\n the realm that owns it; a connection never writes through to another realm).\n- **Promoted from.** Someone promoting from one of these can overwrite what you write here.\n- **Promotes to.** Where this content goes when someone promotes it. You cannot promote yourself.\n\nNothing in the answer says which environment is production. Judge that from the names, and ask the\nperson you are working for when it is not obvious.\n\n## What an empty answer means\n\nThe binding governs **reads** exactly as it governs writes, and that changes how an empty result\nshould be read. `GET /contracts` returning nothing means *this environment has no Contracts*. It does\nnot mean the organization has none, and it certainly does not mean the account has no content.\n\nThe difference matters because acting on the wrong reading is expensive in one direction: concluding\n\"nothing exists\" and creating a model that already exists elsewhere produces duplicates, which are\nmuch harder to undo than to avoid. The safe habit is to confirm the scope before concluding anything\nfrom an empty list — `GET /whoami`, or the `content_whoami` tool, which needs no permissions at all\nprecisely so that a key holding almost nothing can still ask.\n\nA `404` on a single-entity read is the same fact in another shape: not found *here*. The entity may\nexist in another environment, and this key cannot see it.\n\n## When a write is refused for a permission\n\nA key has two limits, and they are different. Its **scopes** say which kinds of call it may make at\nall (`read`, `authoring`, `publish`). The **role it runs as** says what that role may do, and a few\nkinds need a permission on top of the `authoring` scope:\n\n| To write or delete | The role needs |\n|---|---|\n| a Contract | `content.contracts.manage` |\n| a Template | `content.templates.manage` |\n\nThe Member role does not hold either. The `ContentSchemaAdmin` role holds both, as does Owner, but\nOwner grants far more than an agent needs; prefer `ContentSchemaAdmin` or a custom role with just\nthese. Any role in the organization can be chosen as a key's \"run as\" role.\n\nA refusal for this reason is `403 permission_denied`, and it names the permission. The MCP server\nsays so plainly and, when it already knows the role lacks the permission, declines the call without\nsending it. `content_whoami` lists the kinds withheld for this role, each with the permission it\nneeds. When you see this, tell the person which permission is missing; changing the role is theirs\nto do, in the key's settings, and not something to work around.\n\n## Things that commonly go wrong\n\n- **Guessing a field type's settings** instead of reading its schema. Every field type declares its\n own; there is nothing to guess.\n- **Creating a duplicate** because an external id was not checked first. External ids are how a\n model refers to itself across environments; a duplicate is a lasting problem.\n- **Putting presentation on a Contract.** If you are adding a field called `variant`, `align`,\n `theme` or `columns` to a Contract, it almost certainly belongs in a Template's settings.\n- **Forgetting a node's payload.** A node created and never given one is a real, published,\n completely blank page.\n- **Treating a publish plan as a formality.** It is where blockers appear, and they do not appear\n anywhere else until something is already wrong.\n\n## Rendering the site is a separate job\n\nEverything above builds the content. The site that shows it reads the published result from the\nContent Delivery API, and for that there is a client: **`@ebitex/content-sdk`** (npm), or\n`Ebitex.Content.Delivery` on a .NET server. Read [Rendering your site](rendering-your-site.md)\nbefore you write any code that fetches published content, and do not write a Delivery client by\nhand without a reason.\n\n## Related\n\n- [Contracts](contracts.md) — the type system in depth\n- [Templates](templates.md) — presentation\n- [Components](components.md) — authoring content\n- [Content Adapters](content-adapters.md) — mappings\n- [Composer](content-composer.md) — the Experience tree\n- [Publishing](publishing.md) — the publish pipeline\n- [Management keys](management-keys.md) — minting and scoping a key\n- [Rendering your site](rendering-your-site.md) — the SDK that reads what you publish\n"
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"slug": "blog-series",
|
|
@@ -16,7 +16,7 @@ export const HELP_TOPICS = [
|
|
|
16
16
|
{
|
|
17
17
|
"slug": "components",
|
|
18
18
|
"title": "Authoring Components",
|
|
19
|
-
"body": "# Authoring Components\n\nA Component is one piece of content built from a Contract — for example,\na specific article. This guide covers creating and editing Components,\norganizing them in folders, and the friction the app shows you when a\nContract changes underneath a Component you've already created. See\n[Modeling content with Contracts](contracts.md) first if you haven't\ncreated a Contract yet.\n\n## Creating a Component\n\n1. From the Content page, select **New Component** (optionally after\n opening the folder you want it created in).\n2. Enter a **Name** — the **Id** fills in from it automatically and can\n still be edited by hand.\n3. Choose a **Contract**. If you started from a specific folder that\n restricts which Contracts are allowed there, only those (and their\n descendants) are offered.\n4. Fill in the form that appears — every field from the Contract, laid\n out in order. Fields marked with a red **\\*** are required.\n5. Select **Create**. If a required field is missing or a value doesn't\n match the Contract's rules, the field is highlighted with an\n explanation — fix it and select **Create** again.\n\n## Filling in fields\n\nMost fields are a straightforward text box, number box, or checkbox.\nA few work differently:\n\n- **Reference** and **Nested** are older field types kept working for\n existing Contracts, but no longer offered when adding a new field — new\n Contracts should use **Component** instead (below), which offers the\n same two behaviors plus a third, chosen per value instead of committed\n to for the whole field.\n- **Component** fields ask you to choose, each time you fill one in:\n **Choose existing…** to link to an existing Component (same search box as\n Reference); or the **Create** menu, whose **Create new…** creates a\n brand-new Component and links to it in one step (fill in its name,\n Contract, and any required fields right there), and whose **Write\n inline…** embeds a value that only ever exists inside this one — pick a\n Contract and an **Edit** panel slides in, exactly like Nested below. If\n the Contract only allows one of these choices, only that one is offered,\n and the field says so. Once filled, the value is a card with a **Component** header (and the **✕**\n that removes it) over its name and\n kind, one main button (**Edit**, which opens a linked Component in a layer\n over the page, or the inline value itself), a **⋯** menu holding **Change…** and\n **Contextual values**, and a **✕** that removes the value. If a linked Component can't be found — most often because it\n was skipped during a promotion into this environment (see\n [content-environments.md](content-environments.md)'s \"Unresolved\n references\" section) — you'll see a distinct **Unresolved** badge\n instead of the usual resolved name, with a link to Component Sync to\n see the full picture and fix it. **Choose another** and the **✕**\n still work normally on an unresolved value.\n- **Blob** fields (images and other files) show an **Upload** button.\n Once uploaded, you'll see a preview (for images) and a link to download\n the file, plus a **Replace** button.\n- **Nested** fields show a small **Edit** panel once a Contract is chosen\n for them (automatically, if only one is allowed for that field, or via a\n picker if more than one is allowed) — selecting **Edit** opens the\n nested content in its own panel, sliding in over the current one. Any\n unsaved changes you've made — at every level — are kept even if you\n drill several levels deep and back out again; nothing is lost until you\n actually leave the page without saving. A Component field's own **Create\n inline…** choice opens the identical panel.\n- Fields marked **Localizable** always show a small translations icon next\n to their label — select it to add per-locale overrides alongside the\n default value. It's disabled (with an explanation on hover) until your\n organization has a language configured under **Localization** settings\n with at least one language added under it to translate into; once one\n exists, the icon becomes selectable. This works the same way for every\n field type, including Blob, Reference, Nested, Component, and\n Presentation fields: each locale gets its own independent\n **Upload**/**Edit**/**Choose…** affordance, so a Nested value's translated\n content — or a different linked Component or uploaded file per locale —\n is fully separate from the default. The default-locale row in the\n translations panel is always read-only (a reflection of the default\n value, not a second copy of it); translate from the other locale rows.\n- **Presentation** fields let you instantiate a Template inline — pick a\n Template, bind it to a Component, and set contextual values and settings\n for this specific placement. See\n [Presenting content with Templates](templates.md) for the full flow.\n\n## Links to the live page\n\nIf the Contract has **External links**, they appear as buttons under the\nComponent's name, and at the top of the quick-edit panel. A button opens that\nComponent's page on your site in a new tab. If it is greyed out, the reason is\nwritten beside it, usually that the Component has not been published yet. The\nlink always shows what is *published*, not the changes you are typing. See\n[Links to your site](contracts.md) to set them up.\n\n## Noting which channels a Component is made for\n\nOn a Component's **Settings** tab, **Made for** lets you note that it suits **Email**, **Web**, or\nboth. It is optional and only advises: it never stops you saving or publishing, and a Component with\nno note is \"unknown\". Pages that are noted for a channel warn about Components that say they are not\nmade for it. The **Made for** column in the Components list shows the note. See\n[Building your site in Composer](content-composer.md#made-for).\n\n## Status, and what to do next\n\nUnder the Component's name, one **status strip** says whether it can be published and, if not, why. It also\nholds the next step, so you do not have to hunt for it:\n\n- **Draft**, **Published** or **Modified since it was published**, with one line about the live site\n (\"The live site shows an older version\").\n- If your organization uses an [editorial workflow](content-workflow.md) for this folder, the strip shows the\n workflow's state beside the headline. While that state does not allow publishing it reads **Can't be\n published yet**, and the workflow's next step (for example **Approve**) sits beside it. Choose it, add an\n optional comment and confirm, all without leaving the Content tab. **Republish…** stays available, but it is\n no longer the highlighted button; its tooltip gives the reason, and the publish panel explains the block.\n- Once the state allows publishing it reads **Ready to publish** and **Publish…** is highlighted instead.\n- If you have edited since a review was started, the strip says so, and that publishing will use the version\n that was reviewed.\n- A Component that no longer fits its folder's rules gets a **Move it…** row.\n- If the Component has translations in progress, they are listed here too, with **Review…** for one that is\n waiting for you.\n\nThe full workflow panel, with its comment box and **Cancel run**, and the complete translations list stay on the\n**Settings** tab. Where the Component is used (**Used in N places**) and whether it is **Inherited** are in the line\nunder the name.\n\n## Version history\n\nEvery time a Component's content is saved, ebitex keeps a copy, so you can\nsee what changed, who changed it, and undo an unwanted edit.\n\nOpen the **More actions** menu near the top of a Component and choose\n**Version history…**. Each entry shows a version number, who saved it and\nwhen. Select an entry to see what changed compared to the version before\nit: the fields that were added, removed or changed, named as you see them\nin the editor. The very first version has nothing to compare against.\n\nSaving the exact same content twice in a row doesn't add an entry: only a\nsave that actually changes something does. Entries can show **Unknown**\ninstead of a name when none was recorded, which is the case for changes\nmade by promotion, import or inheritance rather than by a person typing in\nthe editor. It doesn't mean the person has left your organization.\n\n**Restoring** a version puts that version's name and document back as the\nComponent's current content. Its folder stays where it is. Nothing is\ndeleted: restoring adds a *new* entry to the history, marked **restored**,\nso you can undo a restore by restoring again. Any unsaved edits on the page\nare discarded when you restore, and the confirmation says so. A restore\ndoes not publish anything. If the restored content differs from what is live\nthe Component reads **Modified** until you publish it; if it matches what is\nlive, it reads Published again.\n\nRestoring needs a permission beyond the one for viewing history (today,\nOwners hold it), and the same edit access on the folder that saving does.\nWithout them the option is shown but disabled, with the reason on hover.\nIt is also unavailable on an inherited Component: its history belongs to the\nenvironment that owns it, so restore it there. Viewing history needs the version-history permission, which Members\nhold; a role you manage that should see history needs it added on the\nRoles page.\n\nTwo things worth knowing before you restore:\n\n- **Referenced items aren't included.** A version remembers this Component's\n own name and document, not what an item it references looked like at that\n time. A restored version shows those items as they are today.\n- **A version can become unrestorable.** If it was written against a version\n of its Contract that no longer exists, or points at content that has since\n been deleted, restoring explains why and leaves the Component unchanged.\n\nIf someone else saves the Component while you have its history open, a\nrestore is rejected like an ordinary save would be. Reload to see the latest\ncontent, then try again.\n\nPages in the Composer have the same **Version history…** action. Their history\nis read-only for now: you can see what changed and who changed it, but not\nrestore a page.\n\n## Jumping to a field\n\nWhen a Contract has eight or more fields, a **Jump to field** menu appears beside the **Content** and **Settings**\ntabs. Choosing a field scrolls to it and puts the cursor there. A red dot marks a field that needs attention after\na failed save.\n\n## Editing a tree of Components\n\nWhen a Contract is set up to be edited as a tree (see\n[Editing fields as a tree](contracts.md)), its Component editor shows one\nsection, such as **Pedigree**, in place of the separate pickers. The Component\nyou are editing is the root, and each slot is a Component of its own.\n\n- **Chart or outline.** A slot-based tree such as a pedigree is drawn as a chart,\n one column per generation, or as an outline. Choose with the buttons above it;\n the outline is used on narrow screens. **Generations** shows fewer levels\n without changing anything. A list, such as the parts of a product, is always\n an outline you can collapse and expand.\n- **Fill a slot.** Select an empty slot to search for an existing Component, or\n **Create new** to make one on the spot. A slot only lists Components it can\n hold, such as dogs for a sire.\n- **Options you can't choose are greyed out, with the reason.** *Would become its\n own ancestor* or *Would contain itself* means choosing it would make something\n its own ancestor. *Already used elsewhere in this tree* appears when the\n Contract doesn't allow repeats. *Already in this list* means it is there\n already. If the server still refuses a change, the reason is shown above the\n tree.\n- **Edit without leaving.** **Edit** on a filled slot opens that Component in a\n panel over the page. Change it, save it and close the panel, and you are back\n in the tree.\n- **Change or remove.** Point at a filled slot for **Change** and the remove\n button. Removing only empties the slot; the Component itself is kept.\n- **A slot under an empty parent is greyed out**, because there is nothing to\n attach it to yet. Fill the parent first.\n- **A name with ×2 or \"in 2\"** is one Component that appears in more than one\n place. Editing it changes it everywhere.\n\n**Records from another app.** A field can take records that another app owns, such as dogs held in\nData, instead of Components. The tree draws them the same way, and the first level (the slots of the\nComponent you are editing) is changed like any other. What is beneath it belongs to the other app, and\nwhat you can do to it is decided by that app, record by record. Where it lets you edit a record, **Edit**\nopens that record in a panel and **Save** saves it **there**, under its own rules (a refusal is shown on the\nfield it names); slots beneath it can be added, changed and removed, and are saved there too. Where it does\nnot, the record is shown but cannot be changed: a slot it has not filled reads *not set*, and **Edit**\nbecomes **Open in** the other app, which opens its own screen for that record in a new tab. If the other app has no screen for a\nrecord, no link is offered. When a slot takes only that app's records, the picker also offers **Create a {record kind} in {app}** (only for a kind you are allowed to create there): it opens that app's own form, starts with the name you typed in the search box, and **Save** makes the record **there** and puts it in the slot. Cancelling makes nothing. A record it cannot return, because it was deleted or because you may not see it, is shown as *Unavailable* and does not stop the page.\n\n**A slot can be described inline.** Some fields accept a description written\nin place instead of an existing Component, for example a dam who is not in your\narchive and never will be. Where a field allows it, the picker has an\n**Enter … inline instead** button. An inline slot is drawn with a dashed\noutline and an **Inline** chip, and its own slots (her sire and dam, say) are\ndrawn under it and filled in the same way as any other.\n\n- **Edit** on an inline slot opens its own fields in a panel at the side. The\n slots the tree draws are not repeated there. Choose **Done** to keep your\n changes.\n- **Change** or the remove button on an inline slot replaces or removes it\n *together with everything under it*. The picker says how many entries that\n is before you choose, and a notice with **Undo** appears for a few seconds\n afterwards. Undo puts the whole description back.\n- A field that only accepts an existing Component has no inline button.\n- Nothing else can point at an inline description, so it shows no ×2 count.\n\n**What saves when.** The first level, the slots of the Component you have open,\nis part of that Component: it is saved with **Save**, like any other field.\nSlots deeper down belong to the Components above them, so filling one saves that\nComponent straight away, and a **Saved as you go** note under the tree says so.\nA slot under an inline description belongs to the Component that holds the\ndescription, so it follows the same rule: with **Save** when that Component is\nthe one you have open, at once otherwise.\n\n## Contextual defaults\n\nFields marked Contextual on the Contract appear in a separate\n**\"Defaults for usage sites\"** section, clearly labeled optional — even if\nthe Contract also marks them Mandatory. That's intentional: a Contextual\nfield's real value is supplied wherever the content is *used*, not here;\nwhat you set in this section is only a fallback for places that don't\nsupply their own value.\n\n### Setting per-usage values on a Reference\n\nWhen you link to another Component via a Reference field (or a Component\nfield's **Choose existing…**/**Create new…** path — both link the same way),\nopen the card's **⋯** menu and select **Contextual values** to open a panel listing that target's own Contextual\nfields, each with three distinct states you can switch between:\n\n- **Inheriting the Component's default** — nothing set here; the linked\n Component's own default value is used.\n- **Overridden** — set a value here to use instead of the default, just\n for this one link. This works for every field type the target Contract\n declares as Contextual, not just simple text/number/checkbox fields — a\n Contextual Reference field gets the same **Choose…** picker, a Contextual\n Blob field the same **Upload** button, and a Contextual Nested field the\n same drill-in **Edit** panel you'd see editing that field directly on a\n Component.\n- **Explicitly cleared** — select **Clear** to force \"no value\" at this\n usage, ignoring the default entirely (only available when the field\n isn't required).\n\nSelect **Reset to default** at any time to go back to inheriting. The same\nthree states and the same per-type widgets apply to a Presentation field's\nown contextual-values panel (see\n[Presenting content with Templates](templates.md)).\n\n### Editing the linked Component itself\n\nA linked Component's main button is **Edit** (the layer is titled Quick edit), which opens that Component in a layer over the page you're on —\nits own fields, its own **Save**, and a note of everywhere else it's used,\nsince saving changes it there too. How layers stack, and the difference\nbetween a layer that saves on its own and one that's part of your page, is\nexplained in\n[Editing something from where it's used](content-authoring.md#editing-something-from-where-its-used).\n\n## Organizing with folders\n\nThe **Authoring** page shows your folder tree on the left. At the top are **All components** (everything in\nthis environment, across every folder) and **Top level** (Components that aren't in any folder). Below them\nare your folders, each with a count; a folder's count includes everything beneath it. A long folder name wraps\nrather than being cut off.\n\nPoint at a folder to see its actions: the **+** icon creates a subfolder inside it, the pencil renames it or\nmoves it (choose where it goes under **Inside**), the trash icon deletes it (only possible once it's empty,\nand it asks first), and the handle drags it. Selecting a folder shows two tabs: **Contents** (the Components\ninside it) and, if you have the right permissions, **Settings** (that folder's **Access rules**, **Allowed\nContracts**, and editorial workflow assignment). The double-arrow at the top of the panel collapses the whole\ntree to a narrow rail of icons with count badges; select one to open that folder, or the arrow to bring the\npanel back.\n\nEach Component is a row with its title (its id underneath), Contract, publish status (**Draft**, **Published**,\n**Changed** or **Unpublished**), and who last updated it and when. Select the **Title** or **Updated** heading\nto sort by it. Above the list, a search box matches a title, id or Contract, and the **Contract**,\n**Category** and **Status** chips narrow further; **Clear filters** resets them. **Status** lets you tick\none or more of Draft, Published, Changed and Unpublished, for example to find everything that has changed since\nit was published. The count under the list follows the filter, so it is the number that match, not the number\non the page. **Import**, beside **New Component**, opens the [bundle import](export-import.md) for bringing\nComponents in from another environment. Beneath the list, **Rows per page** and\n**Previous / Next** page through long folders, and a line says how many of the total you are looking at.\n\n### Moving Components by dragging, or with the menu\n\nDrag a Component by the handle at the start of its row onto a folder in the tree — or onto **Top level** to take\nit out of its folder — to move it. If you've ticked several rows, dragging one drags them all. A message\nconfirms what moved and offers **Undo**, which puts each Component back where it came from.\n\nTo move without dragging, open the row's **⋯** menu and choose **Move to folder…**, then pick the folder. When\nthe row is part of a selection, the menu says \"Move 3 selected to folder…\" and moves all of them. A folder you\ncan't edit is shown but not choosable. A move is not all-or-nothing: if a Component can't go there (the folder\ndoesn't allow its Contract, say, or you can't edit it), the message names it and why, and the rest still move.\nDragging a folder onto another moves the whole folder inside it; a folder can't be dropped into itself or one\nof its own subfolders. Folders are always listed alphabetically, so there is no manual order to drag into.\n\n### Working on several Components at once\n\nTick rows (the box in the heading ticks every row on the page) and a bar replaces the search tools, showing how\nmany are selected and in which publish states:\n\n- **Publish** applies to everything selected, and reads **Republish** when none of the selection is a draft.\n It opens the usual publish dialog, which lists what else would be published with them.\n- **Unpublish** applies only to what is published or changed. It shows \"2 of 5\" when some of the selection\n can't be unpublished, is switched off with the reason when none can, and asks you to confirm, with a breakdown\n of what comes off the live site.\n- **Move to folder…** moves what you can edit and says how many of the selection that is.\n\nUnder **Settings**:\n\n- **Access rules** restrict which roles can view, edit, delete, or publish\n content in that folder and everything below it (until a subfolder sets\n its own, narrower rules). No rules anywhere on a branch means it's open\n to every member. Select **Add Rule** to grant a role access: pick the\n role from the list and check whichever of View/Edit/Delete/Publish it\n should have. Editing, deleting, or publishing all imply viewing, so you\n don't need to check View separately for those.\n- **Allowed Contracts** restrict which Contracts new Components in that\n folder (and its subfolders, unless they set their own) can use — useful\n for keeping a folder focused on one kind of content. Select **Add\n Contract** and search for the Contract to allow; select **Remove** next\n to an already-allowed Contract to take it off the list. This only\n affects *new* or *moved* Components; it never breaks ones already there,\n though they'll show a **Non-conforming** badge as a reminder.\n\nIf you don't have permission to manage a folder's access rules or allowed\nContracts, you can still see what you're allowed to do there — the panel\njust won't let you change it.\n\n### Moving a Component from its own page\n\nOpen the Component, select the **Settings** tab, and select **Move…**\nnext to the **Folder** label. A picker lists every folder (and **Root**);\npick one to move the Component there once you save. A folder you don't\nhave edit access to is shown but disabled, with an explanation. A folder\nwhose **Allowed Contracts** don't include this Component's Contract is\ndisabled too — unlike an *existing* Component whose folder's rules later\nchange (the **Non-conforming** badge case above), a move that would\nviolate the target folder's rules is rejected outright, so the picker\nwon't offer it as an option in the first place.\n\n### Making copies of a Component\n\nWhen you need several near-identical records (a litter, a series of events,\nproduct variants), build one and **duplicate** it. Open the Component and\nselect **Duplicate…** next to **Preview…**. The button is there whenever you\ncould create a Component in the same folder, and absent when you couldn't.\n\nChoose a **number of copies** (1 to 25) and a **name**. Each copy is named\nwith a number after it (`Puppy A 1`, `Puppy A 2`, …), and the dialog previews\nthe first three, with their external ids, before you start.\n\n- **Values are copied, references are shared.** A copy gets its own\n copy of every value in the document. A Component it *references* is not\n copied: every copy points at the same one, so changing that referenced\n Component changes it in all of them.\n- **Copies are drafts.** They are not published, and carry none of the\n original's published state, history, workflow state, or where it is used.\n They sit in the same folder and use the same Contract as the original.\n- **Copies are made from the saved version.** If you have unsaved edits, the\n dialog says so; save first if you want them included.\n- **External ids** follow the original's (`puppy-a-copy-1`) and move to the\n next free number if one is taken, so a batch never fails over a clash.\n\nCopies are created one at a time. If your plan only has room for some of them,\nthe dialog says how many fit and won't start until the number is lowered. If\nsomething goes wrong part-way, it lists which copies exist, which failed and\nwhich were never attempted, and offers **Create the remaining N**, which\ncarries on from where it stopped instead of making extras. If the original no\nlonger matches the latest version of its Contract, nothing is created and the\ndialog names the field to fix first.\n\n### Finding your way back to a folder\n\nThe Component editor shows a breadcrumb above its title (**Content** /\nthe folder it's in / the Component's name) — select the folder name to\nreturn straight to that folder's Contents tab, rather than using your\nbrowser's back button.\n\n## The upgrade badge\n\nIf a Contract changes after a Component was created from it, that\nComponent keeps working exactly as it did — nothing breaks automatically.\nInstead:\n\n- If the Component still satisfies the Contract's latest version, you'll\n see a badge offering **Upgrade to v_N_** — select it to move the\n Component onto the latest version immediately.\n- If it no longer satisfies the latest version, you'll see a\n **Not valid against latest** badge listing exactly what's wrong. Select\n **Start guided upgrade** to switch into editing against the latest\n version, fix the listed issues, and save — the Component moves onto the\n new version as part of that save.\n\nYou're never forced to upgrade; an older Component keeps validating against\nthe version it was created with until you choose to move it forward.\n\n## Asking the assistant to edit this Component\n\nThe assistant (open it from the magenta ebitex-mark icon in the header, beside **?**) can see and edit the\nComponent you have open, not only answer questions about it — see **The assistant** in\n[Getting help](../general/getting-help.md). A field edit it makes saves immediately with the same\nversion history a manual edit gets; anything bigger, like deleting the Component, is proposed for\nyou to review first.\n"
|
|
19
|
+
"body": "# Authoring Components\n\nA Component is one piece of content built from a Contract — for example,\na specific article. This guide covers creating and editing Components,\norganizing them in folders, and the friction the app shows you when a\nContract changes underneath a Component you've already created. See\n[Modeling content with Contracts](contracts.md) first if you haven't\ncreated a Contract yet.\n\n## Creating a Component\n\n1. From the Content page, select **New Component** (optionally after\n opening the folder you want it created in).\n2. Enter a **Name** — the **Id** fills in from it automatically and can\n still be edited by hand.\n3. Choose a **Contract**. If you started from a specific folder that\n restricts which Contracts are allowed there, only those (and their\n descendants) are offered.\n4. Fill in the form that appears — every field from the Contract, laid\n out in order. Fields marked with a red **\\*** are required.\n5. Select **Create**. If a required field is missing or a value doesn't\n match the Contract's rules, the field is highlighted with an\n explanation — fix it and select **Create** again.\n\n## Filling in fields\n\nMost fields are a straightforward text box, number box, or checkbox.\nA few work differently:\n\n- **Reference** and **Nested** are older field types kept working for\n existing Contracts, but no longer offered when adding a new field — new\n Contracts should use **Component** instead (below), which offers the\n same two behaviors plus a third, chosen per value instead of committed\n to for the whole field.\n- **Component** fields ask you to choose, each time you fill one in:\n **Choose existing…** to link to an existing Component (same search box as\n Reference); or the **Create** menu, whose **Create new…** creates a\n brand-new Component and links to it in one step (fill in its name,\n Contract, and any required fields right there), and whose **Write\n inline…** embeds a value that only ever exists inside this one — pick a\n Contract and an **Edit** panel slides in, exactly like Nested below. A\n step with only one possible outcome is skipped: if the Create menu would hold\n one item, that item is the button; if only one Contract is allowed there is no\n Contract to pick; and a new inline value opens for editing straight away. If\n the Contract only allows one of these choices, only that one is offered,\n and the field says so. Once filled, the value is a card with a **Component** header (and the **✕**\n that removes it) over its name and\n kind, one main button (**Edit**, which opens a linked Component in a layer\n over the page, or the inline value itself), a **⋯** menu holding **Change…** and\n **Contextual values**, and a **✕** that removes the value. If a linked Component can't be found — most often because it\n was skipped during a promotion into this environment (see\n [content-environments.md](content-environments.md)'s \"Unresolved\n references\" section) — you'll see a distinct **Unresolved** badge\n instead of the usual resolved name, with a link to Component Sync to\n see the full picture and fix it. **Choose another** and the **✕**\n still work normally on an unresolved value.\n- **Blob** fields (images and other files) show an **Upload** button.\n Once uploaded, you'll see a preview (for images) and a link to download\n the file, plus a **Replace** button.\n- **Nested** fields show a small **Edit** panel once a Contract is chosen\n for them (automatically, if only one is allowed for that field, or via a\n picker if more than one is allowed) — selecting **Edit** opens the\n nested content in its own panel, sliding in over the current one. Any\n unsaved changes you've made — at every level — are kept even if you\n drill several levels deep and back out again; nothing is lost until you\n actually leave the page without saving. A Component field's own **Create\n inline…** choice opens the identical panel.\n- Fields marked **Localizable** always show a small translations icon next\n to their label — select it to add per-locale overrides alongside the\n default value. It's disabled (with an explanation on hover) until your\n organization has a language configured under **Localization** settings\n with at least one language added under it to translate into; once one\n exists, the icon becomes selectable. This works the same way for every\n field type, including Blob, Reference, Nested, Component, and\n Presentation fields: each locale gets its own independent\n **Upload**/**Edit**/**Choose…** affordance, so a Nested value's translated\n content — or a different linked Component or uploaded file per locale —\n is fully separate from the default. The default-locale row in the\n translations panel is always read-only (a reflection of the default\n value, not a second copy of it); translate from the other locale rows.\n- **Presentation** fields let you instantiate a Template inline — pick a\n Template, bind it to a Component, and set contextual values and settings\n for this specific placement. See\n [Presenting content with Templates](templates.md) for the full flow.\n\n## Links to the live page\n\nIf the Contract has **External links**, they appear as buttons under the\nComponent's name, and at the top of the quick-edit panel. A button opens that\nComponent's page on your site in a new tab. If it is greyed out, the reason is\nwritten beside it, usually that the Component has not been published yet. The\nlink always shows what is *published*, not the changes you are typing. See\n[Links to your site](contracts.md) to set them up.\n\n## Noting which channels a Component is made for\n\nOn a Component's **Settings** tab, **Made for** lets you note that it suits **Email**, **Web**, or\nboth. It is optional and only advises: it never stops you saving or publishing, and a Component with\nno note is \"unknown\". Pages that are noted for a channel warn about Components that say they are not\nmade for it. The **Made for** column in the Components list shows the note. See\n[Building your site in Composer](content-composer.md#made-for).\n\n## Status, and what to do next\n\nUnder the Component's name, one **status strip** says whether it can be published and, if not, why. It also\nholds the next step, so you do not have to hunt for it:\n\n- **Draft**, **Published** or **Modified since it was published**, with one line about the live site\n (\"The live site shows an older version\").\n- If your organization uses an [editorial workflow](content-workflow.md) for this folder, the strip shows the\n workflow's state beside the headline. While that state does not allow publishing it reads **Can't be\n published yet**, and the workflow's next step (for example **Approve**) sits beside it. Choose it, add an\n optional comment and confirm, all without leaving the Content tab. **Republish…** stays available, but it is\n no longer the highlighted button; its tooltip gives the reason, and the publish panel explains the block.\n- Once the state allows publishing it reads **Ready to publish** and **Publish…** is highlighted instead.\n- If you have edited since a review was started, the strip says so, and that publishing will use the version\n that was reviewed.\n- A Component that no longer fits its folder's rules gets a **Move it…** row.\n- If the Component has translations in progress, they are listed here too, with **Review…** for one that is\n waiting for you.\n\nThe full workflow panel, with its comment box and **Cancel run**, and the complete translations list stay on the\n**Settings** tab. Where the Component is used (**Used in N places**) and whether it is **Inherited** are in the line\nunder the name.\n\n## Version history\n\nEvery time a Component's content is saved, ebitex keeps a copy, so you can\nsee what changed, who changed it, and undo an unwanted edit.\n\nOpen the **More actions** menu near the top of a Component and choose\n**Version history…**. Each entry shows a version number, who saved it and\nwhen. Select an entry to see what changed compared to the version before\nit: the fields that were added, removed or changed, named as you see them\nin the editor. The very first version has nothing to compare against.\n\nSaving the exact same content twice in a row doesn't add an entry: only a\nsave that actually changes something does. Entries can show **Unknown**\ninstead of a name when none was recorded, which is the case for changes\nmade by promotion, import or inheritance rather than by a person typing in\nthe editor. It doesn't mean the person has left your organization.\n\n**Restoring** a version puts that version's name and document back as the\nComponent's current content. Its folder stays where it is. Nothing is\ndeleted: restoring adds a *new* entry to the history, marked **restored**,\nso you can undo a restore by restoring again. Any unsaved edits on the page\nare discarded when you restore, and the confirmation says so. A restore\ndoes not publish anything. If the restored content differs from what is live\nthe Component reads **Modified** until you publish it; if it matches what is\nlive, it reads Published again.\n\nRestoring needs a permission beyond the one for viewing history (today,\nOwners hold it), and the same edit access on the folder that saving does.\nWithout them the option is shown but disabled, with the reason on hover.\nIt is also unavailable on an inherited Component: its history belongs to the\nenvironment that owns it, so restore it there. Viewing history needs the version-history permission, which Members\nhold; a role you manage that should see history needs it added on the\nRoles page.\n\nTwo things worth knowing before you restore:\n\n- **Referenced items aren't included.** A version remembers this Component's\n own name and document, not what an item it references looked like at that\n time. A restored version shows those items as they are today.\n- **A version can become unrestorable.** If it was written against a version\n of its Contract that no longer exists, or points at content that has since\n been deleted, restoring explains why and leaves the Component unchanged.\n\nIf someone else saves the Component while you have its history open, a\nrestore is rejected like an ordinary save would be. Reload to see the latest\ncontent, then try again.\n\nPages in the Composer have the same **Version history…** action. Their history\nis read-only for now: you can see what changed and who changed it, but not\nrestore a page.\n\n## Jumping to a field\n\nWhen a Contract has eight or more fields, a **Jump to field** menu appears beside the **Content** and **Settings**\ntabs. Choosing a field scrolls to it and puts the cursor there. A red dot marks a field that needs attention after\na failed save.\n\n## Editing a tree of Components\n\nWhen a Contract is set up to be edited as a tree (see\n[Editing fields as a tree](contracts.md)), its Component editor shows one\nsection, such as **Pedigree**, in place of the separate pickers. The Component\nyou are editing is the root, and each slot is a Component of its own.\n\n- **Chart or outline.** A slot-based tree such as a pedigree is drawn as a chart,\n one column per generation, or as an outline. Choose with the buttons above it;\n the outline is used on narrow screens. **Generations** shows fewer levels\n without changing anything. A list, such as the parts of a product, is always\n an outline you can collapse and expand.\n- **Fill a slot.** Select an empty slot to search for an existing Component, or\n **Create new** to make one on the spot. A slot only lists Components it can\n hold, such as dogs for a sire.\n- **Options you can't choose are greyed out, with the reason.** *Would become its\n own ancestor* or *Would contain itself* means choosing it would make something\n its own ancestor. *Already used elsewhere in this tree* appears when the\n Contract doesn't allow repeats. *Already in this list* means it is there\n already. If the server still refuses a change, the reason is shown above the\n tree.\n- **Edit without leaving.** **Edit** on a filled slot opens that Component in a\n panel over the page. Change it, save it and close the panel, and you are back\n in the tree.\n- **Change or remove.** Point at a filled slot for **Change** and the remove\n button. Removing only empties the slot; the Component itself is kept.\n- **A slot under an empty parent is greyed out**, because there is nothing to\n attach it to yet. Fill the parent first.\n- **A name with ×2 or \"in 2\"** is one Component that appears in more than one\n place. Editing it changes it everywhere.\n\n**Records from another app.** A field can take records that another app owns, such as dogs held in\nData, instead of Components. The tree draws them the same way, and the first level (the slots of the\nComponent you are editing) is changed like any other. What is beneath it belongs to the other app, and\nwhat you can do to it is decided by that app, record by record. Where it lets you edit a record, **Edit**\nopens that record in a panel and **Save** saves it **there**, under its own rules (a refusal is shown on the\nfield it names); slots beneath it can be added, changed and removed, and are saved there too. Where it does\nnot, the record is shown but cannot be changed: a slot it has not filled reads *not set*, and **Edit**\nbecomes **Open in** the other app, which opens its own screen for that record in a new tab. If the other app has no screen for a\nrecord, no link is offered. When a slot takes only that app's records, the picker also offers **Create a {record kind} in {app}** (only for a kind you are allowed to create there): it opens that app's own form, starts with the name you typed in the search box, and **Save** makes the record **there** and puts it in the slot. Cancelling makes nothing. A record it cannot return, because it was deleted or because you may not see it, is shown as *Unavailable* and does not stop the page.\n\n**A slot can be described inline.** Some fields accept a description written\nin place instead of an existing Component, for example a dam who is not in your\narchive and never will be. Where a field allows it, the picker has an\n**Enter … inline instead** button. An inline slot is drawn with a dashed\noutline and an **Inline** chip, and its own slots (her sire and dam, say) are\ndrawn under it and filled in the same way as any other.\n\n- **Edit** on an inline slot opens its own fields in a panel at the side. The\n slots the tree draws are not repeated there. Choose **Done** to keep your\n changes.\n- **Change** or the remove button on an inline slot replaces or removes it\n *together with everything under it*. The picker says how many entries that\n is before you choose, and a notice with **Undo** appears for a few seconds\n afterwards. Undo puts the whole description back.\n- A field that only accepts an existing Component has no inline button.\n- Nothing else can point at an inline description, so it shows no ×2 count.\n\n**What saves when.** The first level, the slots of the Component you have open,\nis part of that Component: it is saved with **Save**, like any other field.\nSlots deeper down belong to the Components above them, so filling one saves that\nComponent straight away, and a **Saved as you go** note under the tree says so.\nA slot under an inline description belongs to the Component that holds the\ndescription, so it follows the same rule: with **Save** when that Component is\nthe one you have open, at once otherwise.\n\n## Contextual defaults\n\nFields marked Contextual on the Contract appear in a separate\n**\"Defaults for usage sites\"** section, clearly labeled optional — even if\nthe Contract also marks them Mandatory. That's intentional: a Contextual\nfield's real value is supplied wherever the content is *used*, not here;\nwhat you set in this section is only a fallback for places that don't\nsupply their own value.\n\n### Setting per-usage values on a Reference\n\nWhen you link to another Component via a Reference field (or a Component\nfield's **Choose existing…**/**Create new…** path — both link the same way),\nopen the card's **⋯** menu and select **Contextual values** to open a panel listing that target's own Contextual\nfields, each with three distinct states you can switch between:\n\n- **Inheriting the Component's default** — nothing set here; the linked\n Component's own default value is used.\n- **Overridden** — set a value here to use instead of the default, just\n for this one link. This works for every field type the target Contract\n declares as Contextual, not just simple text/number/checkbox fields — a\n Contextual Reference field gets the same **Choose…** picker, a Contextual\n Blob field the same **Upload** button, and a Contextual Nested field the\n same drill-in **Edit** panel you'd see editing that field directly on a\n Component.\n- **Explicitly cleared** — select **Clear** to force \"no value\" at this\n usage, ignoring the default entirely (only available when the field\n isn't required).\n\nSelect **Reset to default** at any time to go back to inheriting. The same\nthree states and the same per-type widgets apply to a Presentation field's\nown contextual-values panel (see\n[Presenting content with Templates](templates.md)).\n\n### Editing the linked Component itself\n\nA linked Component's main button is **Edit** (the layer is titled Quick edit), which opens that Component in a layer over the page you're on —\nits own fields, its own **Save**, and a note of everywhere else it's used,\nsince saving changes it there too. How layers stack, and the difference\nbetween a layer that saves on its own and one that's part of your page, is\nexplained in\n[Editing something from where it's used](content-authoring.md#editing-something-from-where-its-used).\n\n## Organizing with folders\n\nThe **Authoring** page shows your folder tree on the left. At the top are **All components** (everything in\nthis environment, across every folder) and **Top level** (Components that aren't in any folder). Below them\nare your folders, each with a count; a folder's count includes everything beneath it. A long folder name wraps\nrather than being cut off.\n\nPoint at a folder to see its actions: the **+** icon creates a subfolder inside it, the pencil renames it or\nmoves it (choose where it goes under **Inside**), the trash icon deletes it (only possible once it's empty,\nand it asks first), and the handle drags it. Selecting a folder shows two tabs: **Contents** (the Components\ninside it) and, if you have the right permissions, **Settings** (that folder's **Access rules**, **Allowed\nContracts**, and editorial workflow assignment). The double-arrow at the top of the panel collapses the whole\ntree to a narrow rail of icons with count badges; select one to open that folder, or the arrow to bring the\npanel back.\n\nEach Component is a row with its title (its id underneath), Contract, publish status (**Draft**, **Published**,\n**Changed** or **Unpublished**), and who last updated it and when. Select the **Title** or **Updated** heading\nto sort by it. Above the list, a search box matches a title, id or Contract, and the **Contract**,\n**Category** and **Status** chips narrow further; **Clear filters** resets them. **Status** lets you tick\none or more of Draft, Published, Changed and Unpublished, for example to find everything that has changed since\nit was published. The count under the list follows the filter, so it is the number that match, not the number\non the page. **Import**, beside **New Component**, opens the [bundle import](export-import.md) for bringing\nComponents in from another environment. Beneath the list, **Rows per page** and\n**Previous / Next** page through long folders, and a line says how many of the total you are looking at.\n\n### Moving Components by dragging, or with the menu\n\nDrag a Component by the handle at the start of its row onto a folder in the tree — or onto **Top level** to take\nit out of its folder — to move it. If you've ticked several rows, dragging one drags them all. A message\nconfirms what moved and offers **Undo**, which puts each Component back where it came from.\n\nTo move without dragging, open the row's **⋯** menu and choose **Move to folder…**, then pick the folder. When\nthe row is part of a selection, the menu says \"Move 3 selected to folder…\" and moves all of them. A folder you\ncan't edit is shown but not choosable. A move is not all-or-nothing: if a Component can't go there (the folder\ndoesn't allow its Contract, say, or you can't edit it), the message names it and why, and the rest still move.\nDragging a folder onto another moves the whole folder inside it; a folder can't be dropped into itself or one\nof its own subfolders. Folders are always listed alphabetically, so there is no manual order to drag into.\n\n### Working on several Components at once\n\nTick rows (the box in the heading ticks every row on the page) and a bar replaces the search tools, showing how\nmany are selected and in which publish states:\n\n- **Publish** applies to everything selected, and reads **Republish** when none of the selection is a draft.\n It opens the usual publish dialog, which lists what else would be published with them.\n- **Unpublish** applies only to what is published or changed. It shows \"2 of 5\" when some of the selection\n can't be unpublished, is switched off with the reason when none can, and asks you to confirm, with a breakdown\n of what comes off the live site.\n- **Move to folder…** moves what you can edit and says how many of the selection that is.\n\nUnder **Settings**:\n\n- **Access rules** restrict which roles can view, edit, delete, or publish\n content in that folder and everything below it (until a subfolder sets\n its own, narrower rules). No rules anywhere on a branch means it's open\n to every member. Select **Add Rule** to grant a role access: pick the\n role from the list and check whichever of View/Edit/Delete/Publish it\n should have. Editing, deleting, or publishing all imply viewing, so you\n don't need to check View separately for those.\n- **Allowed Contracts** restrict which Contracts new Components in that\n folder (and its subfolders, unless they set their own) can use — useful\n for keeping a folder focused on one kind of content. Select **Add\n Contract** and search for the Contract to allow; select **Remove** next\n to an already-allowed Contract to take it off the list. This only\n affects *new* or *moved* Components; it never breaks ones already there,\n though they'll show a **Non-conforming** badge as a reminder.\n\nIf you don't have permission to manage a folder's access rules or allowed\nContracts, you can still see what you're allowed to do there — the panel\njust won't let you change it.\n\n### Moving a Component from its own page\n\nOpen the Component, select the **Settings** tab, and select **Move…**\nnext to the **Folder** label. A picker lists every folder (and **Root**);\npick one to move the Component there once you save. A folder you don't\nhave edit access to is shown but disabled, with an explanation. A folder\nwhose **Allowed Contracts** don't include this Component's Contract is\ndisabled too — unlike an *existing* Component whose folder's rules later\nchange (the **Non-conforming** badge case above), a move that would\nviolate the target folder's rules is rejected outright, so the picker\nwon't offer it as an option in the first place.\n\n### Making copies of a Component\n\nWhen you need several near-identical records (a litter, a series of events,\nproduct variants), build one and **duplicate** it. Open the Component and\nselect **Duplicate…** next to **Preview…**. The button is there whenever you\ncould create a Component in the same folder, and absent when you couldn't.\n\nChoose a **number of copies** (1 to 25) and a **name**. Each copy is named\nwith a number after it (`Puppy A 1`, `Puppy A 2`, …), and the dialog previews\nthe first three, with their external ids, before you start.\n\n- **Values are copied, references are shared.** A copy gets its own\n copy of every value in the document. A Component it *references* is not\n copied: every copy points at the same one, so changing that referenced\n Component changes it in all of them.\n- **Copies are drafts.** They are not published, and carry none of the\n original's published state, history, workflow state, or where it is used.\n They sit in the same folder and use the same Contract as the original.\n- **Copies are made from the saved version.** If you have unsaved edits, the\n dialog says so; save first if you want them included.\n- **External ids** follow the original's (`puppy-a-copy-1`) and move to the\n next free number if one is taken, so a batch never fails over a clash.\n\nCopies are created one at a time. If your plan only has room for some of them,\nthe dialog says how many fit and won't start until the number is lowered. If\nsomething goes wrong part-way, it lists which copies exist, which failed and\nwhich were never attempted, and offers **Create the remaining N**, which\ncarries on from where it stopped instead of making extras. If the original no\nlonger matches the latest version of its Contract, nothing is created and the\ndialog names the field to fix first.\n\n### Finding your way back to a folder\n\nThe Component editor shows a breadcrumb above its title (**Content** /\nthe folder it's in / the Component's name) — select the folder name to\nreturn straight to that folder's Contents tab, rather than using your\nbrowser's back button.\n\n## The upgrade badge\n\nIf a Contract changes after a Component was created from it, that\nComponent keeps working exactly as it did — nothing breaks automatically.\nInstead:\n\n- If the Component still satisfies the Contract's latest version, you'll\n see a badge offering **Upgrade to v_N_** — select it to move the\n Component onto the latest version immediately.\n- If it no longer satisfies the latest version, you'll see a\n **Not valid against latest** badge listing exactly what's wrong. Select\n **Start guided upgrade** to switch into editing against the latest\n version, fix the listed issues, and save — the Component moves onto the\n new version as part of that save.\n\nYou're never forced to upgrade; an older Component keeps validating against\nthe version it was created with until you choose to move it forward.\n\n## Asking the assistant to edit this Component\n\nThe assistant (open it from the magenta ebitex-mark icon in the header, beside **?**) can see and edit the\nComponent you have open, not only answer questions about it — see **The assistant** in\n[Getting help](../general/getting-help.md). A field edit it makes saves immediately with the same\nversion history a manual edit gets; anything bigger, like deleting the Component, is proposed for\nyou to review first.\n"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
"slug": "content-adapters",
|
|
@@ -43,6 +43,11 @@ export const HELP_TOPICS = [
|
|
|
43
43
|
"title": "Linking to pages and external sites",
|
|
44
44
|
"body": "# Linking to pages and external sites\n\nA **Link** field lets you point at a page in your own site (an Experience node) or at an external\nURL, with an optional query string and anchor. It replaces the older **URL** field type, which\nstill works on any field that already used it but no longer appears as a choice for a new one.\n\n## Adding a link\n\nSelect **Choose page…** or the kind toggle (if the field allows both **Page** and **External URL**)\nto pick which kind of link this is.\n\n### Linking to a page\n\nSelecting **Page** opens a browser: a list of your sites, then each one's pages, drilling in as you\ngo — the same navigation the Experience tree page itself uses. Select **Select** next to any page to\npick it, or its name to browse into its own children first.\n\nOnce picked, the field shows the page's name, its publish status, and a preview of the current URL\nit resolves to. **This URL is not fixed** — it's recalculated every time the page is delivered, so\nif the page is later renamed or moved, the link updates automatically the next time it's viewed. You\nnever need to re-save anything that links to it.\n\nIf you pick a page that hasn't been published yet, you'll see a warning — you can still save the\nlink, but it won't resolve to a real address until that page is published. Once it is, the link\nstarts working with no further action from you.\n\n### Linking to an external URL\n\nSelecting **External URL** shows a plain address field. If the field's settings restrict which\nprotocols are allowed (for example, only `https`), you'll see that listed, and an address using a\ndifferent one is flagged before you can save.\n\n## Query and anchor\n\nBelow the kind you picked, **Query** and **Anchor** fields let you add extra address detail — for\nexample a query string like `utm_campaign=spring` or an anchor like `specs`, which is appended after\nthe resolved address (`…widget-x?utm_campaign=spring#specs`). These are available for a page link\njust as much as an external one — unless the field's settings turn suffixes off entirely, in which\ncase neither shows.\n\n## If the field only allows pages\n\nSome fields are set up to only ever point at a page in your own site — no kind toggle, no external\noption, no query/anchor. These use a simpler **Experience Reference** field, which behaves exactly\nlike the page-picking half of a Link field above, without any of the extra chrome. You'll typically\nsee this on a field meant to feed something else — a \"Featured pages\" list used to build navigation\ncards, for instance — rather than to be delivered as a clickable link by itself.\n\n## Deleting a linked-to page\n\nA page that's targeted by a Link (or an Experience Reference field) can't be deleted while that link\nexists — you'll see the same \"this can't be deleted, here's what's using it\" message you'd get\ntrying to delete a Component that's still referenced elsewhere.\n"
|
|
45
45
|
},
|
|
46
|
+
{
|
|
47
|
+
"slug": "content-modelling",
|
|
48
|
+
"title": "Modelling your content: best practices",
|
|
49
|
+
"body": "# Modelling your content: best practices\n\nHow to shape Contracts, Templates and Components so a site is easy to build, easy to change and hard to break. It applies whether you model in Content, through the API, or as code, and it is the model the starter kit follows. Read it before you create anything, and read [Building a content model through the API](agent-authoring.md) for the mechanics.\n\n## The one idea\n\n**A Contract holds what is said. A Template holds how it is shown.**\n\n- A **Contract** has editorial fields only: a heading, a body, an image, a link, a label. Nothing about width, colour, columns, emphasis or order of appearance.\n- A **Template** says how a Contract is drawn, and owns a **settings Contract** for every choice that belongs to a *place*: width, background, appearance, layout, a card's emphasis, a banner's tone, a grid's columns, how an accordion opens.\n- A **presentation** is the pair in use: a Template, its settings, and a Component. The same Component can appear on many pages, each with its own settings, so it looks or behaves differently in each, and the words live in one place.\n\nIf you catch yourself adding \"layout\", \"width\" or \"variant\" to a content Contract, it belongs in a Template's settings.\n\n## Choose the right kind of field\n\n| You want | Use | Why |\n|---|---|---|\n| A hero or a list of sections on a page | A **presentation** field, with the Templates it accepts | An editor picks how it is drawn, sets the choices for that place, and supplies the content |\n| A part with no life of its own (a button inside a hero, a tab's label) | An **inline** component | Nothing else can point at it, and it is deleted with what holds it |\n| A thing reused across pages (a testimonial, a venue) | A **reference** to a Component | One edit changes it everywhere |\n| One of a closed set of choices (a theme, a tone) | A **category** from a group | A renderer maps the key; an organization can rename or extend the values |\n| Media | A reference to an **Assets** item | The media library owns files, not Content |\n\nPrefer a presentation field over a component field whenever the thing is *drawn* on a page. A component field gives the editor no place to say how.\n\n## Templates and Contracts\n\n- **One Template per Contract by default.** A Template may also support a Contract another Template supports. That is the right tool when the *same* content needs two genuinely different presentations (a statement and a feature over the same heading, body, media and links): keep the Contract generic and add a Template, instead of copying the Contract.\n- A Template can list several supported Contracts, so a generic abstract parent (\"heading, body, media, links\") can serve one Template for every Contract beneath it.\n- **A renderer is chosen by Template, never by Contract.** That is what makes the many-to-one case work, and what makes a container reusable: it hands each item to the same dispatch the page uses.\n- **A Contract has one parent.** Shared settings are therefore a chain, not a mix: a base for sections (width, background, appearance, anchor), a base for grid cells that extends it (adds span), then each Template's own. Model the chain you need; you cannot inherit two bases.\n- Make a shared base **abstract** so it is never placed on its own.\n\n## Containers are components, not special cases\n\nTabs, accordions, carousels and grids hold *other presentations*. Model them as higher-order components:\n\n- The container has an **inline list of item Contracts**. An item is a **label** (content, localizable) plus an **enumerable presentation field** limited to the Templates suitable inside it.\n- A whole FAQ is then one Component you can reuse on every page that needs it.\n- **How a container behaves** (one drawer open at a time or independent, which start open, how many columns) is a **setting of its Template**, not content. The same Component can behave differently wherever it is used.\n- A container accepts **leaf Templates only**. Never let a container accept itself or another container: Contracts and Templates would depend on each other in a loop and cannot be installed in order.\n\n## Allow-lists\n\n- A presentation field names the Templates it accepts (`allowedTemplateIds`); a component field names its Contracts and modes. **Unset means anything. An empty list means nothing.** Say which you mean, and give an editor a clear control to switch.\n- Prefer an **explicit list** for a field with a clear purpose (a hero accepts the Hero Template only; sections never accept the Hero or the page itself). The cost is that a Template you add later is not offered until you add it to the list, which is a deliberate step, not a surprise.\n- Leave a field **open** only when anything really is valid.\n\n## Settings and vocabularies\n\n- Put every closed choice in a **category group**, never free text, so a renderer can map a key and an organization can edit the values. A category key is what a renderer maps, so **never rename a key**.\n- A category field takes **no default**: an unset choice means \"the renderer's default\". When a nested part should follow its parent, add an explicit **inherit** value to the group and treat it, and an unset value, as \"the parent's\". A renderer can then cascade it (an appearance on a section reaches everything inside it, and a nested part that chooses its own overrides it).\n- Keep a theme or any page-wide look in the **page Template's settings**, so the same page Component can be drawn differently.\n- Keep identifiers and settings **non-localizable**; make prose (headings, body, labels) **localizable**.\n\n## Naming\n\n- Field ids are **kebab-case** (`primary-action`, `meta-title`). A field id is a property name in every delivered document, a path in filters and ordering, and a key in queries, and those accept kebab-case only. A model that ships camelCase ids is uneditable later.\n- Give everything you ship a **prefix** so a customer's own keys can never collide with it. Do not shadow keys that other apps own (the Assets Contracts).\n- Name an editor-built page an **experience**, and avoid the word \"page\" in keys: the same content can be a page, a section of one, or an email.\n\n## Building a renderer\n\n- Register one renderer per **Template** in the SDK's renderer map: `{ ...kitRenderers, 'my-template': MyRenderer }`. A Template with no renderer shows the host's fallback and never breaks the page.\n- A renderer receives the Template, its **settings** and the Component's **content**. Draw inside the shared frame so the Template's width, background, anchor and appearance apply, and so your Template joins the appearance cascade.\n- Read a category by its **key**, with a fallback for a key you do not know, so a value an organization adds degrades to the default rather than breaking the page.\n- Test against a **real delivery response** (install the model, publish, read it back), not one you wrote by hand: a hand-written fixture can pass while the real server sends something else.\n\n## Shipping a model to others\n\nIf you distribute a model (a starter kit, a template for clients), treat it like an API:\n\n- **Semver.** A change to a shipped Contract or Template's shape is a **major** version. Within a major version, mark things deprecated and leave them in place.\n- **Never mix a new major version into an older install.** Give each major version a **marker** Contract that exists only in it. An environment that holds some of the model but not the marker holds an earlier version: refuse the install, write nothing, and leave the existing copy exactly as it is.\n- Install the model into **two organizations in one database** in a test: ids that the model carries must be rewritten per organization.\n- **Save every Contract unchanged** through the real save rules after installing it. An import writes without asking those rules, so a model can install cleanly and still be impossible to edit.\n- Give people a **migration note** with every breaking release, even if the answer is \"install into a new environment\".\n\n## A checklist\n\n1. Does every Contract hold only editorial content?\n2. Is every placement, appearance or behaviour choice a setting of a Template?\n3. Is every closed choice a category with no default, and every nested follow-the-parent choice an `inherit`?\n4. Does every presentation field name the Templates it accepts, and do containers accept leaf Templates only?\n5. Are all field ids kebab-case and all prose localizable?\n6. Is there a renderer for every Template, registered by Template?\n7. If you ship it: is there a major-version marker, a changelog, and a test that installs it twice and saves every Contract?\n"
|
|
50
|
+
},
|
|
46
51
|
{
|
|
47
52
|
"slug": "content-personalization",
|
|
48
53
|
"title": "Personalization & RichText",
|
|
@@ -131,7 +136,7 @@ export const HELP_TOPICS = [
|
|
|
131
136
|
{
|
|
132
137
|
"slug": "starter-kit",
|
|
133
138
|
"title": "Starter kits",
|
|
134
|
-
"body": "# Starter kits\n\nA **starter kit** gives you a working set of Contracts, Templates, categories and a demo experience, so you start from something instead of nothing. Install it once, then change anything you like: it becomes your own content and never updates by itself.\n\n
|
|
139
|
+
"body": "# Starter kits\n\nA **starter kit** gives you a working set of Contracts, Templates, categories and a demo experience, so you start from something instead of nothing. Install it once, then change anything you like: it becomes your own content and never updates by itself.\n\n## Adding a starter kit\n\nOpen **Starter kits** under **Tools**.\n\n1. Read what the kit will add and what you already have, and any permission you are missing. The page tells you before you start, not after.\n2. If Assets is not connected, connect it from the same page first. The kit's media fields choose from your Assets library.\n3. Leave **Include the demo experience** on if you want a finished example to learn from, or clear it to add only the building blocks. The demo's items are all named \"Demo\".\n4. Select **Install the kit**.\n\nWhen it finishes the page tells you the kit is installed, and links to your Contracts and Templates.\n\n## What is safe\n\n- Nothing you already have is changed. If an item with the same name exists, it is left exactly as it is and the preview tells you.\n- Running it again adds only what is missing.\n- If anything goes wrong, nothing from that attempt is kept.\n\n## How the kit is built\n\nThe kit separates **what a section says** from **how it is shown**.\n\n- A **Contract** holds only the content: a hero's heading and lead, a card's title and summary, a tab's label.\n- A **Template** says how a Contract is drawn, and has its own **settings** for the choices that belong to a place: width, background, appearance, a card's emphasis, a banner's tone, a grid's columns, how an accordion behaves.\n- An experience's **Hero** and **Sections** are *presentations*: you choose a Template, set its settings, and give it a Component. The same Component can be used on many pages, each with its own settings, so it looks or behaves differently in each.\n- **Tabs** and **Accordion** hold their own items. Each item is a label and the presentations inside it, so a whole FAQ is one Component you can reuse on every page that needs it.\n- Two Templates can present the same Contract in different ways. Make a second Template over a Contract when the same words need a different look, rather than copying the Contract.\n\n## After you install\n\nEverything is yours. Edit a Contract, rename a category, restyle a theme, or delete what you do not need. Nothing is linked back to the kit, and a newer version of the kit never changes what you have. Installing again adds only what is missing.\n\nA new **major** version of the kit is not mixed into an earlier one, because its Templates would sit beside Contracts of the old shape. If your environment holds an earlier version, the install tells you so and changes nothing; your copy is left exactly as it is. To use the new version, install it into a new environment or organization.\n\nTo use your own Template in an experience's **Sections**, open the experience's Contract and add your Template to the Sections field's allowed Templates. The kit lists the Templates it accepts, so Hero and the experience itself can never be placed as a section.\n\n## Themes and appearances\n\nAn experience has a **theme**, which sets its colours, type and spacing, chosen in the experience Template's settings; leave it empty for the default. A section can have an **appearance** that adjusts the theme for that section and everything nested inside it; leave it on **Inherit** to take the parent's. Themes and appearances are categories, so you edit them under **Categories**.\n\n## Pictures and video\n\nMedia fields use the Assets app, so Assets has to be connected to Content before the kit can be installed. The Starter kits page offers the one-step **Connect Assets** card when it is not.\n"
|
|
135
140
|
},
|
|
136
141
|
{
|
|
137
142
|
"slug": "tasks",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpCorpus.generated.js","sourceRoot":"","sources":["../../src/resources/helpCorpus.generated.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,kGAAkG;AAClG,oGAAoG;AAIpG,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC;QACE,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,0CAA0C;QACnD,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"helpCorpus.generated.js","sourceRoot":"","sources":["../../src/resources/helpCorpus.generated.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAmC,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAG5E;;;GAGG;AAEH,eAAO,MAAM,WAAW,mBAAmB,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,cAAc,EAAE,MAAsB,CAAA;AAiBnD,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,SAAS,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE;IAC1C,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,GAAG,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAE3D,OAAO,EAAmC,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAG5E;;;GAGG;AAEH,eAAO,MAAM,WAAW,mBAAmB,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,cAAc,EAAE,MAAsB,CAAA;AAiBnD,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,SAAS,CAAA;IACjB,OAAO,EAAE,OAAO,CAAA;IAChB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE;IAC1C,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;CACzB,GAAG,OAAO,CAAC,WAAW,CAAC,CA4CvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAuB5E"}
|
package/dist/server.js
CHANGED
|
@@ -63,7 +63,10 @@ export async function buildServer(options) {
|
|
|
63
63
|
'which is where the shape of anything you write comes from. Read the ' +
|
|
64
64
|
'ebitex-content://help/agent-authoring resource before building a model; it explains what ' +
|
|
65
65
|
'Contracts, Templates, Presentations, Adapters and the Experience tree are for, and the ' +
|
|
66
|
-
'order to create them in.
|
|
66
|
+
'order to create them in. Then read ebitex-content://help/content-modelling before you decide ' +
|
|
67
|
+
'what the model looks like: Contracts hold editorial content only, a Template and its settings ' +
|
|
68
|
+
'hold every placement and appearance choice, and a presentation field (not a component field) ' +
|
|
69
|
+
'is how a page draws a section. When a write is refused, the refusal names the failing field: ' +
|
|
67
70
|
'correct that one thing and call again. ' +
|
|
68
71
|
// Spec #792, and it belongs here rather than only in a tool description because an agent
|
|
69
72
|
// reads instructions before its first call — which is before the first empty result it
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAsB,MAAM,aAAa,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,eAAe,EAAgB,MAAM,cAAc,CAAA;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD;;;GAGG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,gBAAgB,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,cAAc,GAAW,WAAW,EAAE,CAAA;AAEnD;;;;;GAKG;AACH,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAA0B,CAAA;QACtF,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAA;IAClG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,eAAe,CAAA;IACxB,CAAC;AACH,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAGjC;IACC,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,CAAA;IAE9C,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAA;IACxG,MAAM,MAAM,GAAyB,MAAM,CAAC,SAAS;QACnD,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;QACjG,CAAC,CAAC,IAAI,CAAA;IAER,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,EAAE,iBAAiB,EAAE,MAAM,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAA;IAEzH,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,EAC9C;QACE,YAAY,EACV,2FAA2F;YAC3F,wFAAwF;YACxF,sEAAsE;YACtE,2FAA2F;YAC3F,yFAAyF;YACzF,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ebitex/content-mcp",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.268",
|
|
4
4
|
"description": "An MCP server for ebitex Content: build and publish a content model from an AI agent.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://developers.ebitex.io/getting-started/content-as-code/",
|