From 0325ac0c42c477281b32fc9515fa85339fe02a05 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 23 Oct 2025 12:20:16 +0200 Subject: [PATCH 01/17] Add initial documentation for Property Editor Data Sources Introduces a new section and file explaining Property Editor Data Sources in Umbraco CMS. Details how to enable data source support, register data sources, configure settings, and access data source properties in Property Editor UIs. --- .../property-editors/composition/README.md | 5 ++ .../property-editor-data-source.md | 82 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md diff --git a/17/umbraco-cms/customizing/property-editors/composition/README.md b/17/umbraco-cms/customizing/property-editors/composition/README.md index f0298a26a69..1305f631b49 100644 --- a/17/umbraco-cms/customizing/property-editors/composition/README.md +++ b/17/umbraco-cms/customizing/property-editors/composition/README.md @@ -22,3 +22,8 @@ A Property Editor UI is utilizing a Property Editor Schema, and you can have mul * Data Type Settings for a Property Editor or Property Editor UI is defined in the manifests. * They both use the same format for their settings. + +## Property Editor Data Sources +A Property Editor Data Source is an optional way to provide data to a Property Editor UI. This allows for reuse of the same Property Editor UI but with different data sources. + +* [Property Editor Data Source](property-editor-data-source.md) diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md new file mode 100644 index 00000000000..b7848a6903b --- /dev/null +++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md @@ -0,0 +1,82 @@ +# Property Editor Data Source + +A Property Editor Data Source is a way to provide data to a Property Editor UI. This allows for reuse of the same Property Editor UI but with different data sources. + +Data Sources are an opt-in feature for a Property Editor UI and need to be explicitly enabled. When enabled it allows for other extensions to register Data Sources that can be selected for the Property Editor UI as long as the Data Source Type is supported by the Property Editor UI. + +## Enable Data Source Support + +The Data Source support is enabled in the Property Editor UI manifest. Below is a snippet showing how to enable it. The `forDataSourceTypes` can include any already existing Data Source Types or new custom ones. + +**Property Editor UI Manifest** +```typescript +{ + type: 'propertyEditorUi', + name: 'My Property Editor UI with Data Source support', + //... more + meta: { + //... more + supportsDataSource: { + enabled: true, + forDataSourceTypes: ['myDataSourceType'] + } + } +} +``` + +When this field is enabled, it will be possible to pick a Data Source in the Data Type Workspace next to the Property Editor field. The available Data Sources will match the supported Data Source Types of the chosen Property Editor UI. + +// Insert image of Data Type Workspace with Data Source selection + +## Register a Data Source + +**Data Source Manifest** +```typescript + { + type: 'propertyEditorDataSource', + dataSourceType: 'myDataSourceType' + alias: 'Umb.PropertyEditorDataSource.MyDataSource', + name: 'My Data Data Source', + api: () => import('./my-data-data-source.js'), + meta: { + label: 'My Data', + description: 'A good description of the data', + icon: 'icon-database', + }, + }, +``` + +### Data Source Settings +Like Property Editor UIs and Schemas, Data Sources can have settings for configuration of the data source. These settings are defined in the manifest under `meta.settings`. The settings for a Data Source will be rendered in the Data Type Workspace together with the Property Editor UI and Schema settings. + +**Data Source Manifest** +```typescript +{ + type: 'propertyEditorDataSource', + alias: 'Umb.PropertyEditorDataSource.MyDataSource', + //... more + meta: { + //... more + settings: { + properties: [], + }, + }, +}; +``` + +## Access Data Source Alias in Property Editor UI + +When implementing a Property Editor UI element, the Data Source alias can be accessed through the `dataSourceAlias` property. + +```typescript +interface UmbPropertyEditorUiElement extends HTMLElement { + dataSourceAlias?: string; +} +``` + +## Access Data Source Config in Property Editor UI +The Data Source configuration can be accessed through the `config` property of the Property Editor UI element together with the UI and Schema config. + +## Built-in Data Source Types +* `picker` - Used by Property Editors that pick entities, e.g. the Entity Data Picker Property Editor. + From c90827b85b9128d83bb8e764e7cc26f1e9449795 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 23 Oct 2025 12:26:01 +0200 Subject: [PATCH 02/17] add image --- ...cs-data-type-property-editor-data-source.png | Bin 0 -> 28070 bytes .../composition/property-editor-data-source.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 .gitbook/assets/umbraco-docs-data-type-property-editor-data-source.png diff --git a/.gitbook/assets/umbraco-docs-data-type-property-editor-data-source.png b/.gitbook/assets/umbraco-docs-data-type-property-editor-data-source.png new file mode 100644 index 0000000000000000000000000000000000000000..ee1158546920dc6db17162fa8b64049e30e486d2 GIT binary patch literal 28070 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 G{QnPgGw

Property Editor Data Source Picker

## Register a Data Source From 3c947838f0c80f150768b995d1a68913894bf660 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 24 Oct 2025 11:47:52 +0200 Subject: [PATCH 03/17] add property editor + picker data source docs --- .../property-editor-data-source.md | 6 +- .../README.md | 26 +++ .../picker-collection-data-source.md | 88 ++++++++++ .../picker-tree-data-source.md | 156 ++++++++++++++++++ .../entity-data-picker.md | 43 +++++ 5 files changed, 316 insertions(+), 3 deletions(-) create mode 100644 17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/README.md create mode 100644 17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-collection-data-source.md create mode 100644 17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-tree-data-source.md create mode 100644 17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md index 673ea1c28e3..d57c10710ee 100644 --- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md @@ -1,8 +1,8 @@ # Property Editor Data Source -A Property Editor Data Source is a way to provide data to a Property Editor UI. This allows for reuse of the same Property Editor UI but with different data sources. +A Property Editor Data Source is a way to provide data to a Property Editor UI. This allows for reuse of the same UI but with different data sources. -Data Sources are an opt-in feature for a Property Editor UI and need to be explicitly enabled. When enabled it allows for other extensions to register Data Sources that can be selected for the Property Editor UI as long as the Data Source Type is supported by the Property Editor UI. +Data Sources are an opt-in feature for a Property Editor UI and need to be explicitly enabled. When enabled it allows for other extensions to register Data Sources that can be selected for the Property Editor UI as long as the Data Source Type is supported by the UI. ## Enable Data Source Support @@ -78,5 +78,5 @@ interface UmbPropertyEditorUiElement extends HTMLElement { The Data Source configuration can be accessed through the `config` property of the Property Editor UI element together with the UI and Schema config. ## Built-in Data Source Types -* `picker` - Used by Property Editors that pick entities, e.g. the Entity Data Picker Property Editor. +* [picker](../property-editor-data-source-types/picker.md) - Used by Property Editors that pick entities, e.g. the Entity Data Picker Property Editor. diff --git a/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/README.md b/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/README.md new file mode 100644 index 00000000000..0bf915f7b3a --- /dev/null +++ b/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/README.md @@ -0,0 +1,26 @@ +# Picker Data Source Type + +The `picker` Data Source Type is used by Property Editors that pick entities, e.g. the built-in [Entity Data Picker Property Editor](../../../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md). + +## Register a Picker Data Source + +**Data Source Manifest** + +```typescript +{ + type: 'propertyEditorDataSource', + dataSourceType: 'picker' + alias: 'Umb.PropertyEditorDataSource.MyPickerDataSource', + name: 'My Picker Data Source', + api: () => import('./my-picker-data-source.js'), + meta: { + label: 'My Data Source', + description: 'A good description of the data source', + icon: 'icon-database', + }, +}, +``` + +The new Picker supports two types of data structures: +* [Collection Data](./collection-data.md) +* [Tree Data](./tree-data.md) \ No newline at end of file diff --git a/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-collection-data-source.md b/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-collection-data-source.md new file mode 100644 index 00000000000..e5d2b0e3981 --- /dev/null +++ b/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-collection-data-source.md @@ -0,0 +1,88 @@ +## Picker Collection Data Source + +The interface below is simplified for clarity and omits return types and args. See full interfaces in the [UI Api Documentation](https://apidocs.umbraco.com/v17/ui-api/modules/packages_core_picker-data-source.html) + +```typescript +interface UmbPickerPropertyEditorCollectionDataSource { + requestCollection(); + requestItems(); + search?(); + setConfig?(); + getConfig?(); +} +``` + +### Example +```typescript +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbCollectionFilterModel, UmbCollectionItemModel } from '@umbraco-cms/backoffice/collection'; +import type { + UmbPickerCollectionDataSource, + UmbPickerSearchableDataSource, +} from '@umbraco-cms/backoffice/picker-data-source'; +import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search'; + +interface ExampleCollectionItemModel extends UmbCollectionItemModel { + isPickable: boolean; +} + +export class MyCustomPickerCollectionPropertyEditorDataSource + extends UmbControllerBase + implements UmbPickerCollectionDataSource, UmbPickerSearchableDataSource +{ + collectionPickableFilter = (item: ExampleCollectionItemModel) => item.isPickable; + + async requestCollection(args: UmbCollectionFilterModel) { + const data = { + items: customItems, + total: customItems.length, + }; + + return { data }; + } + + async requestItems(uniques: Array) { + const items = customItems.filter((x) => uniques.includes(x.unique)); + return { data: items }; + } + + async search(args: UmbSearchRequestArgs) { + const items = customItems.filter((item) => item.name?.toLowerCase().includes(args.query.toLowerCase())); + const total = items.length; + + const data = { + items, + total, + }; + + return { data }; + } +} + +export { ExampleCustomPickerCollectionPropertyEditorDataSource as api }; + +const customItems: Array = [ + { + unique: '1', + entityType: 'example', + name: 'Example 1', + icon: 'icon-shape-triangle', + isPickable: true, + }, + { + unique: '2', + entityType: 'example', + name: 'Example 2', + icon: 'icon-shape-triangle', + isPickable: false, + }, + { + unique: '3', + entityType: 'example', + name: 'Example 3', + icon: 'icon-shape-triangle', + isPickable: true, + }, +]; + +``` \ No newline at end of file diff --git a/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-tree-data-source.md b/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-tree-data-source.md new file mode 100644 index 00000000000..da1b3ab9ee5 --- /dev/null +++ b/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-tree-data-source.md @@ -0,0 +1,156 @@ +## Picker Tree Data Source + +The interface below is simplified for clarity and omits return types and args. See full interfaces in the [UI Api Documentation](https://apidocs.umbraco.com/v17/ui-api/modules/packages_core_picker-data-source.html) + + +```typescript +interface UmbPickerPropertyEditorCollectionDataSource { + requestTreeRoot(); + requestTreeRootItems(); + requestTreeItemsOf(); + requestTreeItemAncestors(); + requestItems(); + search?(); + setConfig?(); + getConfig?(); +} +``` + + +### Example +```typescript +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { + UmbPickerSearchableDataSource, + UmbPickerTreeDataSource, +} from '@umbraco-cms/backoffice/picker-data-source'; +import type { UmbSearchRequestArgs, UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search'; +import type { UmbTreeChildrenOfRequestArgs, UmbTreeItemModel } from '@umbraco-cms/backoffice/tree'; + +export class ExampleCustomPickerTreePropertyEditorDataSource + extends UmbControllerBase + implements UmbPickerTreeDataSource, UmbPickerSearchableDataSource +{ + treePickableFilter: (treeItem: UmbTreeItemModel) => boolean = (treeItem) => + !!treeItem.unique && treeItem.entityType === 'example'; + + searchPickableFilter: (searchItem: UmbSearchResultItemModel) => boolean = (searchItem) => + !!searchItem.unique && searchItem.entityType === 'example'; + + async requestTreeRoot() { + const root = { + unique: null, + name: 'Examples', + icon: 'icon-folder', + hasChildren: true, + entityType: 'example-root', + isFolder: true, + }; + + return { data: root }; + } + + async requestTreeRootItems() { + const rootItems = customItems.filter((item) => item.parent.unique === null); + + const data = { + items: rootItems, + total: rootItems.length, + }; + + return { data }; + } + + async requestTreeItemsOf(args: UmbTreeChildrenOfRequestArgs) { + const items = customItems.filter( + (item) => item.parent.entityType === args.parent.entityType && item.parent.unique === args.parent.unique, + ); + + const data = { + items: items, + total: items.length, + }; + + return { data }; + } + + async requestTreeItemAncestors() { + // TODO: implement when needed + return { data: [] }; + } + + async requestItems(uniques: Array) { + const items = customItems.filter((x) => uniques.includes(x.unique)); + return { data: items }; + } + + async search(args: UmbSearchRequestArgs) { + const result = customItems.filter((item) => item.name.toLowerCase().includes(args.query.toLowerCase())); + + const data = { + items: result, + total: result.length, + }; + + return { data }; + } +} + +export { ExampleCustomPickerTreePropertyEditorDataSource as api }; + +const customItems: Array = [ + { + unique: '1', + entityType: 'example', + name: 'Example 1', + icon: 'icon-shape-triangle', + parent: { unique: null, entityType: 'example-root' }, + isFolder: false, + hasChildren: false, + }, + { + unique: '2', + entityType: 'example', + name: 'Example 2', + icon: 'icon-shape-triangle', + parent: { unique: null, entityType: 'example-root' }, + isFolder: false, + hasChildren: false, + }, + { + unique: '3', + entityType: 'example', + name: 'Example 3', + icon: 'icon-shape-triangle', + parent: { unique: null, entityType: 'example-root' }, + isFolder: false, + hasChildren: false, + }, + { + unique: '4', + entityType: 'example', + name: 'Example 4', + icon: 'icon-shape-triangle', + parent: { unique: '6', entityType: 'example-folder' }, + isFolder: false, + hasChildren: false, + }, + { + unique: '5', + entityType: 'example', + name: 'Example 5', + icon: 'icon-shape-triangle', + parent: { unique: '6', entityType: 'example-folder' }, + isFolder: false, + hasChildren: false, + }, + { + unique: '6', + entityType: 'example-folder', + name: 'Example Folder 1', + parent: { unique: null, entityType: 'example-root' }, + isFolder: true, + hasChildren: true, + }, +]; +``` \ No newline at end of file diff --git a/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md b/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md new file mode 100644 index 00000000000..ff1aeb68d3d --- /dev/null +++ b/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md @@ -0,0 +1,43 @@ +# Entity Data Picker + +`Schema Alias: Umbraco.Plain.Json` // TODO: update when alias is final + +`UI Alias: Umb.PropertyEditorUi.EntityDataPicker` + +`Returns: IEnumerable` + +`Supported Data Source Types:` [picker](../../../../customizing/property-editors/property-editor-data-source-types/README.md) + +The Entity Data Picker property editor allows editors to pick one or more entities from a configurable data source. The selected entities are stored as an array of strings, where each string represents the ID of the selected entity. + +### With Models Builder + +```csharp +@if(Model.MyDataItems.Any()){ +
    + @foreach(var item in Model.MyDataItems){ +
  • @item
  • + } +
+} +``` + +### Without Models Builder + +```csharp +@if(Model.HasValue("MyDataItems")) +{ + var myDataItems = Model.Value>("MyDataItems"); +
    + @foreach(var item in myDataItems) + { +
  • @item
  • + } +
+} +``` + +### Content Delivery API +```json +// Missing example +``` From aebb50380d86e2056df1c2e62fbc22c65113ab62 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 27 Oct 2025 21:11:09 +0100 Subject: [PATCH 04/17] update with data editor alias and razor examples --- .../property-editor-data-source.md | 23 +++--- .../data-source-types/picker/README.md | 27 +++++++ .../picker}/picker-collection-data-source.md | 0 .../picker}/picker-tree-data-source.md | 0 .../README.md | 26 ------ .../entity-data-picker.md | 80 +++++++++++++------ 6 files changed, 97 insertions(+), 59 deletions(-) create mode 100644 17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md rename 17/umbraco-cms/customizing/property-editors/{property-editor-data-source-types => data-source-types/picker}/picker-collection-data-source.md (100%) rename 17/umbraco-cms/customizing/property-editors/{property-editor-data-source-types => data-source-types/picker}/picker-tree-data-source.md (100%) delete mode 100644 17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/README.md diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md index d57c10710ee..c430002f192 100644 --- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md @@ -9,6 +9,7 @@ Data Sources are an opt-in feature for a Property Editor UI and need to be expli The Data Source support is enabled in the Property Editor UI manifest. Below is a snippet showing how to enable it. The `forDataSourceTypes` can include any already existing Data Source Types or new custom ones. **Property Editor UI Manifest** + ```typescript { type: 'propertyEditorUi', @@ -18,7 +19,7 @@ The Data Source support is enabled in the Property Editor UI manifest. Below is //... more supportsDataSource: { enabled: true, - forDataSourceTypes: ['myDataSourceType'] + forDataSourceTypes: ['My.DataSourceType.Custom'] } } } @@ -28,16 +29,17 @@ When this field is enabled, it will be possible to pick a Data Source in the Dat

Property Editor Data Source Picker

-## Register a Data Source +## Register a Property Editor Data Source **Data Source Manifest** + ```typescript { type: 'propertyEditorDataSource', - dataSourceType: 'myDataSourceType' - alias: 'Umb.PropertyEditorDataSource.MyDataSource', - name: 'My Data Data Source', - api: () => import('./my-data-data-source.js'), + dataSourceType: 'My.DataSourceType.Custom', + alias: 'Umb.PropertyEditorDataSource.MyCustomDataSource', + name: 'My Custom Data Source', + api: () => import('./my-custom-data-source.js'), meta: { label: 'My Data', description: 'A good description of the data', @@ -47,13 +49,15 @@ When this field is enabled, it will be possible to pick a Data Source in the Dat ``` ### Data Source Settings + Like Property Editor UIs and Schemas, Data Sources can have settings for configuration of the data source. These settings are defined in the manifest under `meta.settings`. The settings for a Data Source will be rendered in the Data Type Workspace together with the Property Editor UI and Schema settings. **Data Source Manifest** + ```typescript { type: 'propertyEditorDataSource', - alias: 'Umb.PropertyEditorDataSource.MyDataSource', + alias: 'Umb.PropertyEditorDataSource.MyCustomDataSource', //... more meta: { //... more @@ -70,13 +74,14 @@ When implementing a Property Editor UI element, the Data Source alias can be acc ```typescript interface UmbPropertyEditorUiElement extends HTMLElement { - dataSourceAlias?: string; + dataSourceAlias?: string; } ``` ## Access Data Source Config in Property Editor UI + The Data Source configuration can be accessed through the `config` property of the Property Editor UI element together with the UI and Schema config. ## Built-in Data Source Types -* [picker](../property-editor-data-source-types/picker.md) - Used by Property Editors that pick entities, e.g. the Entity Data Picker Property Editor. +- [Picker](../data-source-types/picker/README.md) - Used by Property Editors that pick entities, e.g. the Entity Data Picker Property Editor. diff --git a/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md new file mode 100644 index 00000000000..4dfd909a196 --- /dev/null +++ b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md @@ -0,0 +1,27 @@ +# Picker Data Source Type + +The `Umb.DataSourceType.Picker` Data Source Type is used by Property Editors that pick entities, e.g. the built-in [Entity Data Picker Property Editor](../../../../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md). + +## Register a Picker Data Source + +**Data Source Manifest** + +```typescript +{ + type: 'propertyEditorDataSource', + dataSourceType: 'Umb.DataSourceType.Picker', + alias: 'Umb.PropertyEditorDataSource.MyPickerDataSource', + name: 'My Picker Data Source', + api: () => import('./my-picker-data-source.js'), + meta: { + label: 'My Data Source', + description: 'A good description of the data source', + icon: 'icon-database', + }, +}, +``` + +The new Picker supports two types of data structures: + +- [Collection Data](./picker-collection-data-source.md) +- [Tree Data](./picker-tree-data-source.md) diff --git a/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-collection-data-source.md b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-collection-data-source.md similarity index 100% rename from 17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-collection-data-source.md rename to 17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-collection-data-source.md diff --git a/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-tree-data-source.md b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-tree-data-source.md similarity index 100% rename from 17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/picker-tree-data-source.md rename to 17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-tree-data-source.md diff --git a/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/README.md b/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/README.md deleted file mode 100644 index 0bf915f7b3a..00000000000 --- a/17/umbraco-cms/customizing/property-editors/property-editor-data-source-types/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Picker Data Source Type - -The `picker` Data Source Type is used by Property Editors that pick entities, e.g. the built-in [Entity Data Picker Property Editor](../../../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md). - -## Register a Picker Data Source - -**Data Source Manifest** - -```typescript -{ - type: 'propertyEditorDataSource', - dataSourceType: 'picker' - alias: 'Umb.PropertyEditorDataSource.MyPickerDataSource', - name: 'My Picker Data Source', - api: () => import('./my-picker-data-source.js'), - meta: { - label: 'My Data Source', - description: 'A good description of the data source', - icon: 'icon-database', - }, -}, -``` - -The new Picker supports two types of data structures: -* [Collection Data](./collection-data.md) -* [Tree Data](./tree-data.md) \ No newline at end of file diff --git a/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md b/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md index ff1aeb68d3d..64792e4ae32 100644 --- a/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md +++ b/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md @@ -1,43 +1,75 @@ # Entity Data Picker -`Schema Alias: Umbraco.Plain.Json` // TODO: update when alias is final +`Schema Alias: Umbraco.EntityDataPicker` `UI Alias: Umb.PropertyEditorUi.EntityDataPicker` -`Returns: IEnumerable` +`Returns: Umbraco.Cms.Core.Models.EntityDataPickerValue` -`Supported Data Source Types:` [picker](../../../../customizing/property-editors/property-editor-data-source-types/README.md) +`Supported Data Source Types:` [picker](../../../../customizing/property-editors/data-source-types/picker/README.md) The Entity Data Picker property editor allows editors to pick one or more entities from a configurable data source. The selected entities are stored as an array of strings, where each string represents the ID of the selected entity. ### With Models Builder -```csharp -@if(Model.MyDataItems.Any()){ -
    - @foreach(var item in Model.MyDataItems){ -
  • @item
  • - } -
+```razor +@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage +@{ + Layout = null; } + + + Entity Data Picker + + +@if (Model.MyEntityPicker is null) +{ +

No entity picker value found

+} +else +{ +

Data source: @Model.MyEntityPicker.DataSource

+

Picked IDs:

+
    + @foreach (string id in Model.MyEntityPicker.Ids) + { +
  • @id
  • + } +
+} + + ``` ### Without Models Builder -```csharp -@if(Model.HasValue("MyDataItems")) +```razor +@using Umbraco.Cms.Core.Models +@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage +@{ + Layout = null; + var entityDataPickerValue = Model.Value("myEntityPicker"); +} + + + Entity Data Picker + + +@if (entityDataPickerValue is null) { - var myDataItems = Model.Value>("MyDataItems"); -
    - @foreach(var item in myDataItems) - { -
  • @item
  • - } -
+

No entity picker value found

} -``` - -### Content Delivery API -```json -// Missing example +else +{ +

Data source: @entityDataPickerValue.DataSource

+

Picked IDs:

+
    + @foreach (string id in @entityDataPickerValue.Ids) + { +
  • @id
  • + } +
+} + + ``` From 67c4bf9f6b1092cec9e63c74e1fe16688b0df703 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Oct 2025 08:38:21 +0100 Subject: [PATCH 05/17] Clarify example usage in Picker Data Source Type README --- .../property-editors/data-source-types/picker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md index 4dfd909a196..dfc3415888c 100644 --- a/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md +++ b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md @@ -1,6 +1,6 @@ # Picker Data Source Type -The `Umb.DataSourceType.Picker` Data Source Type is used by Property Editors that pick entities, e.g. the built-in [Entity Data Picker Property Editor](../../../../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md). +The `Umb.DataSourceType.Picker` Data Source Type is used by Property Editors that pick entities, for example, the built-in [Entity Data Picker Property Editor](../../../../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md). ## Register a Picker Data Source From 2d94abca03eefa9c7ac5390a3afe1e8b25090b44 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Oct 2025 08:40:46 +0100 Subject: [PATCH 06/17] Clarify example usage in Data Source documentation --- .../property-editors/composition/property-editor-data-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md index c430002f192..6e67f9a57da 100644 --- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md @@ -84,4 +84,4 @@ The Data Source configuration can be accessed through the `config` property of t ## Built-in Data Source Types -- [Picker](../data-source-types/picker/README.md) - Used by Property Editors that pick entities, e.g. the Entity Data Picker Property Editor. +- [Picker](../data-source-types/picker/README.md) - Used by Property Editors that pick entities, for example, the Entity Data Picker Property Editor. From d07d67dcf4fb9ac139d63a048a19fbd208fa1330 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Oct 2025 08:47:05 +0100 Subject: [PATCH 07/17] Refine Property Editor Data Source documentation Clarified the explanation of Property Editor Data Sources and their usage in the Property Editor UI. --- .../composition/property-editor-data-source.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md index 6e67f9a57da..9f87860bcfb 100644 --- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md @@ -1,8 +1,8 @@ # Property Editor Data Source -A Property Editor Data Source is a way to provide data to a Property Editor UI. This allows for reuse of the same UI but with different data sources. +A Property Editor Data Source is a way to provide data to a Property Editor UI. This allows for the reuse of the same UI across different data sources. -Data Sources are an opt-in feature for a Property Editor UI and need to be explicitly enabled. When enabled it allows for other extensions to register Data Sources that can be selected for the Property Editor UI as long as the Data Source Type is supported by the UI. +Data Sources are an opt-in feature for the Property Editor UI. When enabled, extensions can register Data Sources, which can be selected in the UI if their type is supported. ## Enable Data Source Support From 3ce9969ae519eb0541d5377c3cdf81434751314d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Oct 2025 10:40:28 +0100 Subject: [PATCH 08/17] Update SUMMARY.md --- 17/umbraco-cms/SUMMARY.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/17/umbraco-cms/SUMMARY.md b/17/umbraco-cms/SUMMARY.md index f43de56b210..4cf1a2776e2 100644 --- a/17/umbraco-cms/SUMMARY.md +++ b/17/umbraco-cms/SUMMARY.md @@ -64,6 +64,7 @@ * [Date Time (Unspecified)](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date-time-editor/date-time-unspecified.md) * [Decimal](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/decimal.md) * [Email Address](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/email-address.md) + * [Entity Data Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md) * [Eye Dropper Color Picker](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/eye-dropper-color-picker.md) * [File Upload](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/file-upload.md) * [Image Cropper](fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/image-cropper.md) @@ -227,6 +228,11 @@ * [Property Editors Composition](customizing/property-editors/composition/README.md) * [Property Editor Schema](customizing/property-editors/composition/property-editor-schema.md) * [Property Editor UI](customizing/property-editors/composition/property-editor-ui.md) + * [Property Editor Data Source](customizing/property-editors/composition/property-editor-data-source.md) + * Property Editor Data Source Types + * [Picker](customizing/property-editors/data-source-types/picker/README.md) + * [Collection Data Source](customizing/property-editors/data-source-types/picker/picker-collection-data-source.md) + * [Tree Data Source](customizing/property-editors/data-source-types/picker/picker-tree-data-source.md) * [Property Value Converters](customizing/property-editors/property-value-converters.md) * [Property Value Converter Example](customizing/property-editors/full-examples-value-converters.md) * [Property Actions](customizing/property-editors/property-actions.md) From c548984419f844b850fc793b26fe8abdbc030388 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Oct 2025 10:42:22 +0100 Subject: [PATCH 09/17] Update property-editor-data-source.md --- .../property-editors/composition/property-editor-data-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md index 9f87860bcfb..92f80a6f53d 100644 --- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md @@ -25,7 +25,7 @@ The Data Source support is enabled in the Property Editor UI manifest. Below is } ``` -When this field is enabled, it will be possible to pick a Data Source in the Data Type Workspace next to the Property Editor field. The available Data Sources will match the supported Data Source Types of the chosen Property Editor UI. +When this feature is enabled, it will be possible to pick a Data Source in the Data Type Workspace next to the Property Editor field. The available Data Sources will match the supported Data Source Types of the chosen Property Editor UI.

Property Editor Data Source Picker

From 2687fda1da07480c861027070899857b624a98c9 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Oct 2025 10:48:51 +0100 Subject: [PATCH 10/17] Update property-editor-data-source.md --- .../property-editors/composition/property-editor-data-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md index 92f80a6f53d..4bdee197dff 100644 --- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md @@ -80,7 +80,7 @@ interface UmbPropertyEditorUiElement extends HTMLElement { ## Access Data Source Config in Property Editor UI -The Data Source configuration can be accessed through the `config` property of the Property Editor UI element together with the UI and Schema config. +The Data Source configuration can be accessed through the `config` property of the Property Editor UI element merged with the UI and Schema config. ## Built-in Data Source Types From 73ee48e4abec828f5a35c4e15bf97a50fe3b6c97 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Oct 2025 10:51:03 +0100 Subject: [PATCH 11/17] Update README.md --- .../property-editors/data-source-types/picker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md index dfc3415888c..b542f7a9d05 100644 --- a/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md +++ b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/README.md @@ -21,7 +21,7 @@ The `Umb.DataSourceType.Picker` Data Source Type is used by Property Editors tha }, ``` -The new Picker supports two types of data structures: +The Picker Data Source supports two types of data structures: - [Collection Data](./picker-collection-data-source.md) - [Tree Data](./picker-tree-data-source.md) From af09907f110bed22b50cab573fe1c94ca6ecef77 Mon Sep 17 00:00:00 2001 From: Esha Noronha <82437098+eshanrnh@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:14:13 +0100 Subject: [PATCH 12/17] Update 17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md --- .../property-editors/composition/property-editor-data-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md index 4bdee197dff..bd2f6547860 100644 --- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md @@ -27,7 +27,7 @@ The Data Source support is enabled in the Property Editor UI manifest. Below is When this feature is enabled, it will be possible to pick a Data Source in the Data Type Workspace next to the Property Editor field. The available Data Sources will match the supported Data Source Types of the chosen Property Editor UI. -

Property Editor Data Source Picker

+

Property Editor Data Source Picker

## Register a Property Editor Data Source From 47a7e17e432a81419bfa257c600c30b1d614c820 Mon Sep 17 00:00:00 2001 From: Esha Noronha <82437098+eshanrnh@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:14:24 +0100 Subject: [PATCH 13/17] Update 17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md --- .../property-editors/composition/property-editor-data-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md index bd2f6547860..1fc8197ef7a 100644 --- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-data-source.md @@ -25,7 +25,7 @@ The Data Source support is enabled in the Property Editor UI manifest. Below is } ``` -When this feature is enabled, it will be possible to pick a Data Source in the Data Type Workspace next to the Property Editor field. The available Data Sources will match the supported Data Source Types of the chosen Property Editor UI. +When this feature is enabled, you can pick a Data Source in the Data Type Workspace next to the Property Editor field. The available Data Sources will match the supported Data Source Types of the chosen Property Editor UI.

Property Editor Data Source Picker

From c496eb0c148b5824749bf2d45fe329d427e9bfd7 Mon Sep 17 00:00:00 2001 From: Esha Noronha <82437098+eshanrnh@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:14:31 +0100 Subject: [PATCH 14/17] Update 17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-collection-data-source.md --- .../data-source-types/picker/picker-collection-data-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-collection-data-source.md b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-collection-data-source.md index e5d2b0e3981..88f39313858 100644 --- a/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-collection-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-collection-data-source.md @@ -1,6 +1,6 @@ ## Picker Collection Data Source -The interface below is simplified for clarity and omits return types and args. See full interfaces in the [UI Api Documentation](https://apidocs.umbraco.com/v17/ui-api/modules/packages_core_picker-data-source.html) +The interface below is simplified for clarity and omits return types and arguments. See full interfaces in the [UI API Documentation](https://apidocs.umbraco.com/v17/ui-api/modules/packages_core_picker-data-source.html) ```typescript interface UmbPickerPropertyEditorCollectionDataSource { From aa3a189dc1ed02d4707daddcec278b3695a92a4f Mon Sep 17 00:00:00 2001 From: Esha Noronha <82437098+eshanrnh@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:14:40 +0100 Subject: [PATCH 15/17] Update 17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-tree-data-source.md --- .../data-source-types/picker/picker-tree-data-source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-tree-data-source.md b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-tree-data-source.md index da1b3ab9ee5..f488437966e 100644 --- a/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-tree-data-source.md +++ b/17/umbraco-cms/customizing/property-editors/data-source-types/picker/picker-tree-data-source.md @@ -1,6 +1,6 @@ ## Picker Tree Data Source -The interface below is simplified for clarity and omits return types and args. See full interfaces in the [UI Api Documentation](https://apidocs.umbraco.com/v17/ui-api/modules/packages_core_picker-data-source.html) +The interface below is simplified for clarity and omits return types and arguments. See full interfaces in the [UI API Documentation](https://apidocs.umbraco.com/v17/ui-api/modules/packages_core_picker-data-source.html) ```typescript From add873c3b5161ffec427cf13a17f3742fd42df6b Mon Sep 17 00:00:00 2001 From: Esha Noronha <82437098+eshanrnh@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:14:47 +0100 Subject: [PATCH 16/17] Update 17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md --- .../built-in-umbraco-property-editors/entity-data-picker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md b/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md index 64792e4ae32..0f7c8c3fd87 100644 --- a/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md +++ b/17/umbraco-cms/fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/entity-data-picker.md @@ -6,7 +6,7 @@ `Returns: Umbraco.Cms.Core.Models.EntityDataPickerValue` -`Supported Data Source Types:` [picker](../../../../customizing/property-editors/data-source-types/picker/README.md) +`Supported Data Source Types:` [Picker](../../../../customizing/property-editors/data-source-types/picker/README.md) The Entity Data Picker property editor allows editors to pick one or more entities from a configurable data source. The selected entities are stored as an array of strings, where each string represents the ID of the selected entity. From 802738e641340c3ce2de150fcf02a0dd93436a92 Mon Sep 17 00:00:00 2001 From: Esha Noronha <82437098+eshanrnh@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:14:54 +0100 Subject: [PATCH 17/17] Update 17/umbraco-cms/SUMMARY.md --- 17/umbraco-cms/SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/umbraco-cms/SUMMARY.md b/17/umbraco-cms/SUMMARY.md index 4cf1a2776e2..fbaa8a7e65b 100644 --- a/17/umbraco-cms/SUMMARY.md +++ b/17/umbraco-cms/SUMMARY.md @@ -230,7 +230,7 @@ * [Property Editor UI](customizing/property-editors/composition/property-editor-ui.md) * [Property Editor Data Source](customizing/property-editors/composition/property-editor-data-source.md) * Property Editor Data Source Types - * [Picker](customizing/property-editors/data-source-types/picker/README.md) + * [Picker Data Source Type](customizing/property-editors/data-source-types/picker/README.md) * [Collection Data Source](customizing/property-editors/data-source-types/picker/picker-collection-data-source.md) * [Tree Data Source](customizing/property-editors/data-source-types/picker/picker-tree-data-source.md) * [Property Value Converters](customizing/property-editors/property-value-converters.md)