Skip to main content
umbraco-picker-data-source Implement custom picker data sources for property editors in Umbraco backoffice
インストールへ移動 Skills Marketplace コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/umbraco/Umbraco-CMS-Backoffice-Skills --skill umbraco-picker-data-sourceコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?SkillsMP が現在取得できるファイルをダウンロードできます。
Zipをダウンロード ダウンロード中... 関連職種
SOC
name umbraco-picker-data-source description Implement custom picker data sources for property editors in Umbraco backoffice version 1.0.0 location managed allowed-tools Read, Write, Edit, WebFetch
Umbraco Picker Data Source
What is it?
A Picker Data Source provides data for picker-based property editors. It allows you to create custom data sources that supply items for content pickers, defining how items are fetched, searched, and displayed in a tree or collection format. This is useful for creating pickers that select from custom entities, external APIs, or filtered subsets of existing content.
Documentation
Always fetch the latest docs before implementing:
Reference Example The Umbraco source includes working examples:
Location : /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/picker-data-source/
This example demonstrates multiple picker data source implementations:
Custom collection picker
Custom tree picker with search
Document picker with start node configuration
Media, Language, Webhook, and User pickers
Related Foundation Skills
Workflow
Fetch docs - Use WebFetch on the URLs above
Ask questions - What data to pick? Tree or collection? Search needed? Configuration options?
Generate files - Create manifest + data source class based on latest docs
Explain - Show what was created and how to use with a property editor
Manifest Example import { UMB_PICKER_DATA_SOURCE_TYPE } from '@umbraco-cms/backoffice/picker-data-source' ;
export const manifests : Array <UmbExtensionManifest > = [
{
type : 'propertyEditorDataSource' ,
dataSourceType : UMB_PICKER_DATA_SOURCE_TYPE ,
alias : 'My.PropertyEditorDataSource.CustomPicker' ,
name : 'Custom Picker Data Source' ,
api : () => import ('./my-picker-data-source.js' ),
meta : {
label : 'Custom Items' ,
icon : 'icon-list' ,
description : 'Pick from custom items' ,
},
},
];
Tree Picker Data Source For hierarchical data with parent-child relationships:
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 MyPickerTreeDataSource
extends UmbControllerBase
implements UmbPickerTreeDataSource , UmbPickerSearchableDataSource
{
treePickableFilter : (treeItem : UmbTreeItemModel ) => boolean = (treeItem ) =>
!!treeItem.unique && treeItem.entityType === 'my-entity' ;
searchPickableFilter : (searchItem : UmbSearchResultItemModel ) => boolean = (searchItem ) =>
!!searchItem.unique && searchItem.entityType === 'my-entity' ;
async requestTreeRoot ( ) {
return {
data : {
unique : null ,
name : 'My Items' ,
icon : 'icon-folder' ,
hasChildren : true ,
entityType : 'my-entity-root' ,
isFolder : true ,
},
};
}
async requestTreeRootItems ( ) {
const rootItems = myItems.filter ((item ) => item.parent .unique === null );
return {
data : {
items : rootItems,
total : rootItems.length ,
},
};
}
async requestTreeItemsOf (args : UmbTreeChildrenOfRequestArgs ) {
const items = myItems.filter (
(item ) =>
item.parent .entityType === args.parent .entityType &&
item.parent .unique === args.parent .unique
);
return {
data : {
items : items,
total : items.length ,
},
};
}
async requestTreeItemAncestors ( ) {
return { data : [] };
}
async requestItems (uniques : Array <string > ) {
const items = myItems.filter ((x ) => uniques.includes (x.unique ));
return { data : items };
}
async search (args : UmbSearchRequestArgs ) {
const result = myItems.filter ((item ) =>
item.name .toLowerCase ().includes (args.query .toLowerCase ())
);
return {
data : {
items : result,
total : result.length ,
},
};
}
}
export { MyPickerTreeDataSource as api };
const myItems : Array <UmbTreeItemModel > = [
{
unique : '1' ,
entityType : 'my-entity' ,
name : 'Item 1' ,
icon : 'icon-document' ,
parent : { unique : null , entityType : 'my-entity-root' },
isFolder : false ,
hasChildren : false ,
},
{
unique : '2' ,
entityType : 'my-entity' ,
name : 'Item 2' ,
icon : 'icon-document' ,
parent : { unique : null , entityType : 'my-entity-root' },
isFolder : false ,
hasChildren : false ,
},
];
Collection Picker Data Source For flat lists without hierarchy:
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api' ;
import type { UmbPickerCollectionDataSource } from '@umbraco-cms/backoffice/picker-data-source' ;
import type { UmbCollectionItemModel } from '@umbraco-cms/backoffice/collection' ;
export class MyPickerCollectionDataSource
extends UmbControllerBase
implements UmbPickerCollectionDataSource
{
async requestCollection ( ) {
const items : UmbCollectionItemModel [] = [
{ unique : '1' , entityType : 'my-entity' , name : 'Item 1' , icon : 'icon-document' },
{ unique : '2' , entityType : 'my-entity' , name : 'Item 2' , icon : 'icon-document' },
{ unique : '3' , entityType : 'my-entity' , name : 'Item 3' , icon : 'icon-document' },
];
return {
data : {
items,
total : items.length ,
},
};
}
async requestItems (uniques : Array <string > ) {
const allItems = await this .requestCollection ();
const items = allItems.data .items .filter ((x ) => uniques.includes (x.unique ));
return { data : items };
}
}
export { MyPickerCollectionDataSource as api };
Data Source with Configuration Add settings to your picker data source:
export const manifests : Array <UmbExtensionManifest > = [
{
type : 'propertyEditorDataSource' ,
dataSourceType : UMB_PICKER_DATA_SOURCE_TYPE ,
alias : 'My.PropertyEditorDataSource.ConfigurablePicker' ,
name : 'Configurable Picker Data Source' ,
api : () => import ('./my-configurable-picker-data-source.js' ),
meta : {
label : 'Configurable Items' ,
icon : 'icon-settings' ,
description : 'Pick items with configuration options' ,
settings : {
properties : [
{
alias : 'startNode' ,
label : 'Start Node' ,
description : 'Select where to start picking from' ,
propertyEditorUiAlias : 'Umb.PropertyEditorUi.ContentPicker.Source' ,
},
{
alias : 'filter' ,
label : 'Filter Types' ,
description : 'Select which types can be picked' ,
propertyEditorUiAlias : 'Umb.PropertyEditorUi.ContentPicker.SourceType' ,
},
],
},
},
},
];
Interfaces interface UmbPickerTreeDataSource {
treePickableFilter ?: (treeItem : UmbTreeItemModel ) => boolean ;
requestTreeRoot (): Promise <{ data : UmbTreeItemModel }>;
requestTreeRootItems (): Promise <{ data : { items : UmbTreeItemModel []; total : number } }>;
requestTreeItemsOf (args : UmbTreeChildrenOfRequestArgs ): Promise <{ data : { items : UmbTreeItemModel []; total : number } }>;
requestTreeItemAncestors (): Promise <{ data : UmbTreeItemModel [] }>;
requestItems (uniques : string []): Promise <{ data : UmbTreeItemModel [] }>;
}
interface UmbPickerSearchableDataSource {
searchPickableFilter ?: (searchItem : UmbSearchResultItemModel ) => boolean ;
search (args : UmbSearchRequestArgs ): Promise <{ data : { items : UmbSearchResultItemModel []; total : number } }>;
}
interface UmbPickerCollectionDataSource {
requestCollection (): Promise <{ data : { items : UmbCollectionItemModel []; total : number } }>;
requestItems (uniques : string []): Promise <{ data : UmbCollectionItemModel [] }>;
}
Key Concepts Concept Description dataSourceTypeMust be UMB_PICKER_DATA_SOURCE_TYPE for picker data sources treePickableFilterFunction to determine which tree items can be selected searchPickableFilterFunction to determine which search results can be selected requestItemsReturns items by their unique IDs (for displaying selected values) entityTypeIdentifies the type of entity (used for filtering and routing)
Best Practices
Implement search - Users expect to search in pickers with many items
Use appropriate icons - Help users identify item types visually
Filter pickable items - Not all tree items should be selectable (e.g., folders)
Handle configuration - Support start nodes and type filters when applicable
Return consistent data - Ensure requestItems returns the same format as tree/collection
That's it! Always fetch fresh docs, keep examples minimal, generate complete working code.