@picked/client 0.0.72-next.2 → 0.0.72-next.3

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.
Files changed (51) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/{api-D9899KCk.cjs → api-B4qxWoQN.cjs} +1 -1
  3. package/dist/{api-B8SVav6V.js → api-DNvaLWw_.js} +1 -1
  4. package/dist/cjs/index.js +2 -2
  5. package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
  6. package/dist/cjs/server/index.js +1 -1
  7. package/dist/docs/explanation/content-references.md +99 -0
  8. package/dist/docs/explanation/the-content-model.md +38 -28
  9. package/dist/docs/how-to/create-a-content-entry.md +48 -0
  10. package/dist/docs/how-to/define-a-page-layout.md +12 -5
  11. package/dist/docs/how-to/point-one-entry-at-another.md +61 -0
  12. package/dist/docs/how-to/read-a-referenced-entry.md +111 -0
  13. package/dist/docs/how-to/reuse-a-section.md +26 -10
  14. package/dist/docs/index.md +1 -1
  15. package/dist/docs/reference/dashboard/content/blocks.mdx +57 -0
  16. package/dist/docs/reference/dashboard/content/content-entries.mdx +61 -10
  17. package/dist/docs/reference/dashboard/content/models.mdx +108 -0
  18. package/dist/docs/reference/dashboard/content/pages.mdx +4 -3
  19. package/dist/docs/reference/dashboard/fields.mdx +1 -1
  20. package/dist/docs/reference/dashboard/steps.mdx +2 -2
  21. package/dist/docs/reference/delivery-api/experience-content.md +68 -13
  22. package/dist/docs/reference/glossary.md +13 -5
  23. package/dist/docs/reference/management-api/error-handling.md +2 -2
  24. package/dist/docs/reference/sdk/content.md +216 -0
  25. package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +1 -1
  26. package/dist/docs/reference/sdk/ssr/serialize.md +6 -3
  27. package/dist/docs/tutorials/first-api-call.md +1 -1
  28. package/dist/docs/tutorials/first-server-rendered-page.mdx +1 -1
  29. package/dist/esm/index.js +464 -430
  30. package/dist/esm/plugins/dynamic-experiences/index.js +3 -3
  31. package/dist/esm/server/index.js +2 -2
  32. package/dist/{plugin-EFn9ALEF.cjs → plugin-DkSWIASL.cjs} +1 -1
  33. package/dist/{plugin-YytfMG0n.js → plugin-DviILBha.js} +1 -1
  34. package/dist/{provider-GuxX7UDO.js → provider-Bskcgd6U.js} +1 -1
  35. package/dist/{provider-DmXJ58nW.cjs → provider-Bv5nM3So.cjs} +1 -1
  36. package/dist/{registry-CMsN5pHn.cjs → registry-BMXsAEbZ.cjs} +1 -1
  37. package/dist/{registry-DzpNnRIF.js → registry-DjBZ8upD.js} +1 -1
  38. package/dist/types/entities/content/reference.d.ts +101 -0
  39. package/dist/types/entities/content/reference.d.ts.map +1 -0
  40. package/dist/types/exports.d.ts +2 -0
  41. package/dist/types/exports.d.ts.map +1 -1
  42. package/dist/types/index.d.ts +1 -0
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/dist/types/plugins/dynamic-experiences/plugin.d.ts.map +1 -1
  45. package/dist/types/plugins/dynamic-experiences/types.d.ts +10 -0
  46. package/dist/types/plugins/dynamic-experiences/types.d.ts.map +1 -1
  47. package/dist/types/server/serialize.d.ts +6 -1
  48. package/dist/types/server/serialize.d.ts.map +1 -1
  49. package/package.json +1 -1
  50. package/dist/docs/reference/dashboard/content/layouts.mdx +0 -62
  51. package/dist/docs/reference/dashboard/content/sections.mdx +0 -28
@@ -5,52 +5,61 @@ layout: docs
5
5
 
6
6
  # About the content model
7
7
 
8
- Picked splits your content into three pieces: a layout, a section, and a content entry.
8
+ Picked splits your content into three pieces: a Model, a Block, and a content entry.
9
9
  Why three, when a page editor needs only one?
10
10
 
11
11
  ## Schema and data are separate
12
12
 
13
- A **layout** is a schema. It sets which fields a piece of content can hold, and it holds
13
+ A **Model** is a schema. It sets which fields a piece of content can hold, and it holds
14
14
  no data itself. A **content entry** is one instance of that schema, filled with real
15
15
  values.
16
16
 
17
- One layout backs many entries. Describe a campaign page one time, then make many pages
17
+ One Model backs many entries. Describe a campaign page one time, then make many pages
18
18
  from it. Each entry carries its own title, its own body, and its own image, but they all
19
19
  share the shape.
20
20
 
21
21
  That split is also what lets your code depend on content that it never saw. Your component
22
- reads `content.title` because the layout promises a `title`. It works for every entry that
23
- comes from that layout.
22
+ reads `content.title` because the Model promises a `title`. It works for every entry that
23
+ comes from that Model.
24
24
 
25
- ## A layout has a fixed category
25
+ ## A category gives a Model a role
26
26
 
27
- Each layout is a **page layout** or a **step layout**, and you choose which when you
28
- create it. The category cannot change later.
29
-
30
- | Layout | It gives shape to | Who renders it |
31
- | --- | --- | --- |
32
- | Page layout | A standalone [Page](/reference/dashboard/content/pages). | The SDK renders the entry on your server. |
33
- | Step layout | One [Step](/reference/dashboard/steps) inside a Flow. | The Step renders the entry in the browser. |
27
+ A Model can carry a **category**, and the category decides what the Model gives its shape
28
+ to. A **page layout** backs a standalone Page. A **step layout** backs one Step inside a
29
+ Flow.
34
30
 
35
31
  The category is fixed because it decides where the SDK renders the entry. That is not a
36
- property you can change under an entry that exists already. See
37
- [About pages and flows](/explanation/pages-and-flows).
32
+ property that you can change under an entry that exists already.
33
+
34
+ A Model can also carry no category. Such a Model has no layout role, and nothing renders
35
+ its entries directly. It holds the content that other content points at, such as a
36
+ product or a category of your own. See
37
+ [About content references](/explanation/content-references).
38
+
39
+ The three roles are one machine. A layout is a Model with a job in the render path. A
40
+ Model with no category is the same machine with no such job.
38
41
 
39
- ## A section is a schema fragment
42
+ ## A Block is a schema fragment
40
43
 
41
- A layout gives shape to a whole page or a whole step. A **section** is a part that you put
42
- inside one or more layouts.
44
+ A Model gives shape to a whole page or a whole step. A **Block** is a part that you put
45
+ inside one or more Models.
43
46
 
44
- Define a hero one time as a section, then point at it from every page layout that needs
45
- one. Change the section and every layout that holds it changes with it.
47
+ Define a hero one time as a Block, then point at it from every Model that needs one.
48
+ Change the Block and every Model that holds it changes with it.
46
49
 
47
- This is the reason sections exist at all. Without them you must describe a common
48
- structure again in each layout, and the copies then become different. It is the same
50
+ This is the reason Blocks exist at all. Without them you must describe a common
51
+ structure again in each Model, and the copies then become different. It is the same
49
52
  argument for one fact in one place that runs through the rest of this documentation.
50
53
 
54
+ A Block sits **inside** the entry that embeds it. It has no entry of its own, and no id
55
+ that you can point at.
56
+
57
+ That is the difference between a Block and a reference. A Block is a shape that many
58
+ entries hold. A reference is a pointer at one entry that many entries share.
59
+
51
60
  ## Why a schema change does not migrate your data
52
61
 
53
- Change a layout or a section, and Picked does not rewrite the entries behind it. An entry
62
+ Change a Model or a Block, and Picked does not rewrite the entries behind it. An entry
54
63
  that no longer matches its schema becomes invalid, and the dashboard shows an error on
55
64
  each field that does not fit.
56
65
 
@@ -58,20 +67,21 @@ That is deliberate. An automatic change must decide what a new required field ho
58
67
  every entry that came before it. Any value that it chooses is content that nobody wrote.
59
68
  Picked reports the error instead, and you correct it.
60
69
 
61
- The cost is real. After a schema change, check every entry that uses that layout and fix
70
+ The cost is real. After a schema change, check every entry that uses that Model and fix
62
71
  each error before you publish. Picked serves valid content only, so an entry with an error
63
72
  does not reach a visitor.
64
73
 
65
74
  ## An error points at the exact field
66
75
 
67
76
  A validation error carries a path in JSON style, such as `sections[0].data.title`. The
68
- path holds through nested groups, repeated fields, and sections. An error inside a
77
+ path holds through nested groups, repeated fields, and Blocks. An error inside a
69
78
  repeated group therefore tells you which item in that group holds it.
70
79
 
71
80
  ## Related
72
81
 
73
- - [Page and step layouts](/reference/dashboard/content/layouts) — every field type.
74
- - [Sections](/reference/dashboard/content/sections) — the reusable fragments.
82
+ - [Models](/reference/dashboard/content/models) — every field type.
83
+ - [Blocks](/reference/dashboard/content/blocks) — the reusable fragments.
75
84
  - [Content entries](/reference/dashboard/content/content-entries) — the editor and the
76
85
  validation.
77
- - [About pages and flows](/explanation/pages-and-flows) — which layout category you need.
86
+ - [About content references](/explanation/content-references) — how one entry points at another.
87
+ - [About pages and flows](/explanation/pages-and-flows) — which category you need.
@@ -0,0 +1,48 @@
1
+ ---
2
+ type: how-to
3
+ layout: docs
4
+ ---
5
+
6
+ # How to create a content entry
7
+
8
+ This guide shows you how to make one instance of a Model and fill it with data. You need
9
+ a Model first. See [How to define a page layout](/how-to/define-a-page-layout).
10
+
11
+ A Page makes its own entry when you create the page. Use this guide for the content that
12
+ no Page and no Step owns, such as an author or a product.
13
+
14
+ ## 1. Open the entries list
15
+
16
+ 1. Open your workspace.
17
+ 2. Click **CMS** in the sidebar.
18
+ 3. Click **Content entries**.
19
+
20
+ ## 2. Create the entry
21
+
22
+ 1. Click **New content**.
23
+ 2. Choose the **Model** for the entry.
24
+ 3. Fill in each field. The form comes from the schema of the Model.
25
+ 4. Click **Create entry**.
26
+
27
+ The Model is fixed when you create the entry. To move content to another Model, make a
28
+ new entry and copy the values across.
29
+
30
+ ## 3. Correct every error
31
+
32
+ An invalid field shows an error next to it while you edit. The error carries the path to
33
+ the exact field. Correct each one before you publish, because Picked serves valid content
34
+ only.
35
+
36
+ ## Find an entry again
37
+
38
+ The entries list shows a title for each entry. The title is the first single-line text
39
+ field of the entry. It shows the entry id when no such field holds a value.
40
+
41
+ Use the **Model** filter to narrow the list to one Model.
42
+
43
+ ## Related
44
+
45
+ - [Content entries](/reference/dashboard/content/content-entries) — the editor reference.
46
+ - [Models](/reference/dashboard/content/models) — every field type.
47
+ - [How to point one entry at another](/how-to/point-one-entry-at-another)
48
+ - [How to publish a workspace](/how-to/publish-a-workspace)
@@ -5,8 +5,8 @@ layout: docs
5
5
 
6
6
  # How to define a page layout
7
7
 
8
- This guide shows you how to define the shape of a page. A layout sets which fields a page
9
- can hold, and it holds no data itself.
8
+ This guide shows you how to define the shape of a page. A page layout sets which fields a
9
+ page can hold, and it holds no data itself.
10
10
 
11
11
  ## Steps
12
12
 
@@ -19,7 +19,7 @@ can hold, and it holds no data itself.
19
19
  6. Add your fields. Choose a type for each one.
20
20
  7. Click **Create model**.
21
21
 
22
- The category is fixed when you create the layout. You cannot change it later.
22
+ The category is fixed when you create the Model. You cannot change it later.
23
23
 
24
24
  ## Make a field repeatable
25
25
 
@@ -31,9 +31,16 @@ for a gallery, or for a list of features.
31
31
  Add a **Group** field to hold a set of fields under one key. Make the group repeatable to
32
32
  describe a list of objects, such as a list of feature cards.
33
33
 
34
+ ## Define content with no layout role
35
+
36
+ A Model needs no category. Leave **Category** as **None (general content)** for content
37
+ that no Page and no Step renders, such as an author or a product. Reach such a Model
38
+ under **CMS** in the sidebar, and point at its entries with a **Reference** field.
39
+
34
40
  ## Related
35
41
 
36
42
  - [About the content model](/explanation/the-content-model) — why the schema and the data
37
43
  are separate.
38
- - [Page and step layouts](/reference/dashboard/content/layouts) — every field type.
39
- - [How to reuse a section](/how-to/reuse-a-section).
44
+ - [Models](/reference/dashboard/content/models) — every field type.
45
+ - [How to reuse a section](/how-to/reuse-a-section)
46
+ - [How to point one entry at another](/how-to/point-one-entry-at-another)
@@ -0,0 +1,61 @@
1
+ ---
2
+ type: how-to
3
+ layout: docs
4
+ ---
5
+
6
+ # How to point one entry at another
7
+
8
+ This guide shows you how to point one content entry at another, such as a product at its
9
+ category. You need two Models: the one that holds the pointer, and the one that the
10
+ pointer reaches.
11
+
12
+ ## 1. Create the target Model
13
+
14
+ 1. Click **CMS** in the sidebar, then **Models**.
15
+ 2. Click **New model**.
16
+ 3. Enter a **Name** and a **Key**, such as `category`.
17
+ 4. Leave **Category** as **None (general content)**.
18
+ 5. Add your fields.
19
+ 6. Click **Create model**.
20
+
21
+ ## 2. Add a Reference field
22
+
23
+ 1. Open the Model that holds the pointer.
24
+ 2. Drag a **Reference** property onto the schema.
25
+ 3. Enter a **Name** and a **Key**, such as `category`.
26
+ 4. Set **Target Model** to the Model from step 1.
27
+ 5. Click **Save**.
28
+
29
+ Turn on **repeatable** for a field that points at more than one entry. Leave **Target
30
+ Model** as **Any Model** to accept an entry of any Model in the workspace.
31
+
32
+ ## 3. Choose a target on an entry
33
+
34
+ 1. Open a content entry that uses the Model.
35
+ 2. Find your Reference field.
36
+ 3. Click **Choose entry**.
37
+ 4. Search for the entry.
38
+ 5. Choose the entry.
39
+ 6. Click **Save**.
40
+
41
+ Use **Change entry** to point the field somewhere else. Use **Clear** to remove the
42
+ pointer. **Clear** deletes no content.
43
+
44
+ ## Delete a target
45
+
46
+ Picked does not delete an entry while another entry points at it. Clear the reference on
47
+ each entry that points at the target, then delete the target.
48
+
49
+ The same rule holds for a Model. Remove the Reference field that holds it as its **Target
50
+ Model** first.
51
+
52
+ ## Read it in your code
53
+
54
+ The pointer and the entry travel separately. See
55
+ [How to read a referenced entry](/how-to/read-a-referenced-entry).
56
+
57
+ ## Related
58
+
59
+ - [About content references](/explanation/content-references) — why a reference is a pointer.
60
+ - [Models](/reference/dashboard/content/models) — the field and its options.
61
+ - [Content entries](/reference/dashboard/content/content-entries) — the editor reference.
@@ -0,0 +1,111 @@
1
+ ---
2
+ type: how-to
3
+ layout: docs
4
+ ---
5
+
6
+ # How to read a referenced entry
7
+
8
+ This guide shows you how to read the content that a
9
+ [Reference field](/reference/dashboard/content/models#reference-fields) points at. You
10
+ need a component that renders a step first. See
11
+ [How to render a step form](/how-to/render-a-step-form).
12
+
13
+ A Reference field holds a pointer, and not the content. The entry travels beside the
14
+ content of the step, so you resolve the pointer against the content of the client.
15
+
16
+ ## 1. Resolve a single reference
17
+
18
+ Pass the raw field value to `useReference()` in React, or to `getReference()` in Svelte.
19
+
20
+ :::code-group
21
+
22
+ ```tsx [React]
23
+ import { useUnit } from 'effector-react'
24
+ import { useReference, useStepContent } from '@picked/react/hooks'
25
+
26
+ export function ProductCategory() {
27
+ const content = useStepContent()
28
+ const category = useUnit(useReference(content?.category))
29
+
30
+ if (!category) return null
31
+
32
+ return <span>{String(category.data.name ?? '')}</span>
33
+ }
34
+ ```
35
+
36
+ ```svelte [Svelte]
37
+ <script lang="ts">
38
+ import { getStepContent, getReference } from '@picked/svelte/hooks'
39
+
40
+ const content = getStepContent()
41
+ const category = getReference(content.map((c) => c?.category ?? null, { skipVoid: false }))
42
+ </script>
43
+
44
+ {#if $category}
45
+ <span>{$category.data.name ?? ''}</span>
46
+ {/if}
47
+ ```
48
+
49
+ :::
50
+
51
+ In Svelte, pass a store and not a plain value. Content arrives after the component
52
+ starts. A plain value therefore holds the result at "not set".
53
+
54
+ ## 2. Resolve a repeatable reference
55
+
56
+ Use `useReferences()` or `getReferences()`. They give a list in field order.
57
+
58
+ :::code-group
59
+
60
+ ```tsx [React]
61
+ import { useUnit } from 'effector-react'
62
+ import { useReferences, useStepContent } from '@picked/react/hooks'
63
+
64
+ export function ProductCategories() {
65
+ const content = useStepContent()
66
+ const categories = useUnit(useReferences(content?.categories))
67
+
68
+ return (
69
+ <ul>
70
+ {categories.map((category) => (
71
+ <li key={category.id}>{String(category.data.name ?? '')}</li>
72
+ ))}
73
+ </ul>
74
+ )
75
+ }
76
+ ```
77
+
78
+ ```svelte [Svelte]
79
+ <script lang="ts">
80
+ import { getStepContent, getReferences } from '@picked/svelte/hooks'
81
+
82
+ const content = getStepContent()
83
+ const categories = getReferences(content.map((c) => c?.categories ?? null, { skipVoid: false }))
84
+ </script>
85
+
86
+ <ul>
87
+ {#each $categories as category (category.id)}
88
+ <li>{category.data.name ?? ''}</li>
89
+ {/each}
90
+ </ul>
91
+ ```
92
+
93
+ :::
94
+
95
+ The list holds no empty places, so you need no check for each item.
96
+
97
+ ## Handle a target that does not resolve
98
+
99
+ A single reference gives an empty result when Picked cannot resolve the target. A
100
+ repeatable reference leaves the item out of the list.
101
+
102
+ This happens when somebody deleted the target, when the target belongs to another
103
+ workspace, or when the chain of references is deeper than the limit.
104
+
105
+ Render something else for the empty case, as the React example above does.
106
+
107
+ ## Related
108
+
109
+ - [Content](/reference/sdk/content) — every hook and its return type.
110
+ - [About content references](/explanation/content-references) — why the entry travels separately.
111
+ - [How to point one entry at another](/how-to/point-one-entry-at-another) — the dashboard side.
@@ -6,27 +6,42 @@ layout: docs
6
6
  # How to reuse a section
7
7
 
8
8
  This guide shows you how to define a common structure one time and use it in more than
9
- one layout.
9
+ one Model.
10
10
 
11
- ## Create a section
11
+ ## 1. Create the section
12
12
 
13
- 1. Open your workspace.
14
- 2. Click **Pages** in the sidebar, then **Sections**.
13
+ 1. Click **Pages** in the sidebar.
14
+ 2. Click **Page Sections**.
15
15
  3. Click **New block**.
16
16
  4. Enter a **Name** and a **Key**.
17
17
  5. Add your fields.
18
18
  6. Click **Create block**.
19
19
 
20
- ## Use it in a layout
20
+ The **Category** is **Section** already, because you opened the list from **Page
21
+ Sections**.
22
+
23
+ ## 2. Accept the section in a Model
21
24
 
22
25
  1. Open a page layout or a step layout.
23
- 2. Add a **Section** field.
24
- 3. Point that field at your section.
26
+ 2. Add a **Page Sections** field to the schema.
27
+ 3. Click **Save**.
28
+
29
+ The field now accepts any Block of the Section category. Make the field repeatable to
30
+ build a page from a list of sections.
31
+
32
+ If you want one section at a fixed place instead of a list, add a **Content block** field.
33
+ Set its **Block category** to the **Section** category.
34
+
35
+ ## 3. Choose the section in an entry
25
36
 
26
- The layout now carries the fields of the section at every place where that field appears.
37
+ 1. Open a content entry that uses the Model.
38
+ 2. Find the field that you added.
39
+ 3. Choose your Block.
40
+ 4. Fill in the fields of the Block.
41
+ 5. Click **Save**.
27
42
 
28
43
  :::warning
29
- An edit to a section does not migrate the entries that use it. Check each affected content
44
+ An edit to a Block does not migrate the entries that use it. Check each affected content
30
45
  entry again, and correct every field error before you publish.
31
46
  :::
32
47
 
@@ -34,4 +49,5 @@ entry again, and correct every field error before you publish.
34
49
 
35
50
  - [About the content model](/explanation/the-content-model) — why a schema change does not
36
51
  migrate your data.
37
- - [Sections](/reference/dashboard/content/sections) — the reference.
52
+ - [Blocks](/reference/dashboard/content/blocks) — the reference.
53
+ - [Models](/reference/dashboard/content/models) — every field type.
@@ -25,7 +25,7 @@ Then:
25
25
 
26
26
  - **[Build](/how-to/create-an-experience)** — experiences, flows, conditions, and A/B
27
27
  tests.
28
- - **[Content](/how-to/define-a-page-layout)** — layouts, sections, pages, and assets.
28
+ - **[Content](/how-to/define-a-page-layout)** — Models, Blocks, entries, pages, and assets.
29
29
  - **[Publish](/how-to/publish-a-workspace)** — preview, publish, and roll back.
30
30
  - **[Administer and measure](/how-to/invite-and-remove-members)** — members, API keys,
31
31
  analytics, and the tools that connect Picked to Google Tag Manager and to an AI tool.
@@ -0,0 +1,57 @@
1
+ ---
2
+ type: reference
3
+ layout: docs
4
+ ---
5
+
6
+ import { Screenshot } from '../../../../../components/Screenshot'
7
+
8
+ # Blocks
9
+
10
+ A Block is a reusable schema fragment that you embed inside a Model, so that a common structure is defined one time.
11
+
12
+ <Screenshot
13
+ route="/{orgSlug}/{projectId}/workspaces/{workspaceId}/blocks"
14
+ alt="The blocks list in the schema builder on the Picked dashboard"
15
+ />
16
+
17
+ ## What a Block is
18
+
19
+ A Block is a schema fragment with its own **Key**. A
20
+ [Model](/reference/dashboard/content/models) gives its shape to a whole Page or Step. A
21
+ Block is a part that you put into one or more Models. Define the shape one time, then
22
+ reuse it everywhere.
23
+
24
+ A Block holds no data of its own. The content that fills a Block sits inside the entry
25
+ of the Model that embeds it.
26
+
27
+ ## Where a Block appears
28
+
29
+ **CMS** in the sidebar holds **Blocks**, and that list shows every Block in the
30
+ workspace. **Pages** holds **Page Sections**, which is the same list limited to the
31
+ Section category.
32
+
33
+ ## Category
34
+
35
+ | Category | What it does |
36
+ | --- | --- |
37
+ | **Section** | Marks the Block as a page section. A **Page Sections** field accepts it. |
38
+ | **None (general content)** | Gives the Block no layout role. |
39
+
40
+ The category is fixed when you create the Block. You cannot change it later.
41
+
42
+ A **Content block** field holds the category of the Blocks that it accepts. Give that
43
+ field the **Section** category to build a page section list.
44
+
45
+ A field set to **Any category** accepts every Block in the workspace. This is the only
46
+ kind of field that can hold a Block with no category.
47
+
48
+ ## Field types
49
+
50
+ A Block holds the same field types as a Model. See
51
+ [Field types](/reference/dashboard/content/models#field-types).
52
+
53
+ ## Related
54
+
55
+ - [About the content model](/explanation/the-content-model) — why Blocks exist.
56
+ - [How to reuse a section](/how-to/reuse-a-section)
57
+ - [Models](/reference/dashboard/content/models)
@@ -7,7 +7,7 @@ import { Screenshot } from '../../../../../components/Screenshot'
7
7
 
8
8
  # Content Entries
9
9
 
10
- A Content Entry is an instance of a layout filled with real data. A Page renders one entry; a Flow Step can render one too.
10
+ A content entry is one instance of a Model, filled with real data. A Page renders one entry, and a Flow Step can render one too.
11
11
 
12
12
  <Screenshot
13
13
  route="/{orgSlug}/{projectId}/workspaces/{workspaceId}/content"
@@ -16,29 +16,80 @@ A Content Entry is an instance of a layout filled with real data. A Page renders
16
16
 
17
17
  ## What a content entry is
18
18
 
19
- A Content Entry is an instance of a layout's schema. The [layout](/reference/dashboard/content/layouts) defines the fields; the entry holds the actual values. One layout can back many entries, each with its own data.
19
+ A content entry is an instance of the schema of a
20
+ [Model](/reference/dashboard/content/models). The Model sets the fields, and the entry
21
+ holds the values. One Model backs many entries, and each entry holds its own data.
22
+
23
+ The Model of an entry is fixed when you create the entry.
24
+
25
+ ## The entries list
26
+
27
+ **CMS** in the sidebar holds **Content entries**, with a count of every entry in the
28
+ workspace.
29
+
30
+ | Column | What it shows |
31
+ | --- | --- |
32
+ | Title | The value of the first single-line text field of the entry. It falls back to the entry id when no such field holds a value. |
33
+ | Model | The Model that the entry belongs to. |
34
+ | Entry ID | The stable id of the entry. |
35
+ | Last updated | When somebody last saved the entry. |
36
+
37
+ The **Model** filter narrows the list to one Model. The list has no search, because the
38
+ title is derived at read time and is not a column that Picked can search.
20
39
 
21
40
  ## How entries bind to pages and steps
22
41
 
23
- A [Page](/reference/dashboard/content/pages) has a single Step, and that Step links to its entry through the layout content link. A Flow [Step](/reference/dashboard/steps) backed by a Step Layout binds an entry the same way. When the SDK renders the Page or Step, it resolves the linked entry and hands its data to your component.
42
+ A [Page](/reference/dashboard/content/pages) has a single Step, and that Step links to
43
+ its entry through the layout content link. A Flow [Step](/reference/dashboard/steps)
44
+ with a Step Layout binds an entry the same way. When the SDK renders the Page or the
45
+ Step, it resolves the linked entry and gives the data to your component.
24
46
 
25
47
  ## Edit entry data
26
48
 
27
- The entry editor renders a form from the layout schema. There is one input for each
28
- field, in the order that the schema sets. A repeatable field appears as a sortable
49
+ The entry editor renders a form from the schema of the Model. There is one input for
50
+ each field, in the order that the schema sets. A repeatable field shows as a sortable
29
51
  list. You can add to that list and put it into a new order. A group field holds its
30
52
  inputs under one heading.
31
53
 
54
+ ## Reference fields
55
+
56
+ A [Reference field](/reference/dashboard/content/models#reference-fields) holds a pointer
57
+ at another entry, and not a copy of it.
58
+
59
+ | Control | What it does |
60
+ | --- | --- |
61
+ | **Choose entry** | Opens the entry picker. |
62
+ | **Change entry** | Opens the entry picker on a field that holds a target already. |
63
+ | **Clear** | Removes the pointer. It does not delete the entry. |
64
+
65
+ The entry picker lists the entries that the **Target Model** of the field allows, and it
66
+ has a search box. **Open model** opens the Model of an entry in a new tab.
67
+
32
68
  ## Validation
33
69
 
34
- Invalid data appears as an error on each field. The error carries a path in the JSON
35
- style, and it points at the exact place in the entry, for example
36
- `sections[0].data.title`. Fix every error before you publish, because Picked serves
70
+ Invalid data shows as an error on each field. The error carries a path in the JSON style,
71
+ and it points at the exact place in the entry, for example `sections[0].data.title`.
72
+
73
+ A reference field reports an error when its target does not exist, or when the target
74
+ belongs to the wrong Model. Fix every error before you publish, because Picked serves
37
75
  valid content only.
38
76
 
77
+ ## Delete rules
78
+
79
+ Picked does not delete an entry while something still points at it.
80
+
81
+ | Condition | Result |
82
+ | --- | --- |
83
+ | A Step uses the entry as its layout | The delete stops. |
84
+ | Another entry points at it through a Reference field | The delete stops. |
85
+
86
+ Clear the reference on the other entry first, then delete the target.
87
+
39
88
  ## Related
40
89
 
41
90
  - [About the content model](/explanation/the-content-model) — why the schema and the data
42
91
  are separate.
43
- - [How to fill and publish a page](/how-to/fill-and-publish-a-page)
44
- - [Page and step layouts](/reference/dashboard/content/layouts)
92
+ - [About content references](/explanation/content-references) — why a delete stops.
93
+ - [How to create a content entry](/how-to/create-a-content-entry)
94
+ - [How to point one entry at another](/how-to/point-one-entry-at-another)
95
+ - [Models](/reference/dashboard/content/models)