用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/umbraco/Umbraco-CMS-Backoffice-Skills --skill umbraco-manifest-picker命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Run tests from skill examples and generate a report (project)
Validate links and references in SKILL.md files using deterministic scripts
Umbraco backoffice extension customisation - complete working examples showing how extension types combine
正在显示 SKILL.md
基于 SOC 职业分类
| name | umbraco-manifest-picker |
| description | Use umb-input-manifest to pick registered extensions in Umbraco backoffice |
| version | 1.0.0 |
| location | managed |
| allowed-tools | Read, Write, Edit, WebFetch |
The <umb-input-manifest> component provides a picker UI for selecting registered extensions from the Umbraco extension registry. It allows users to pick from any extension type (workspaces, dashboards, property editors, etc.) and returns the selected manifest. This is useful for configuration UIs where users need to reference other extensions.
Always fetch the latest docs before implementing:
The Umbraco source includes a working example:
Location: /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/manifest-picker/
This example demonstrates a dashboard that lets users browse and select extensions by type.
Extension Registry: For understanding how extensions are registered
umbraco-extension-registryUmbraco Element: For creating picker UIs
umbraco-umbraco-elementimport { html, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbInputManifestElement } from '@umbraco-cms/backoffice/components';
@customElement('my-manifest-picker-example')
export class MyManifestPickerExampleElement extends UmbLitElement {
@state()
private _selectedManifest = '';
#onChange(event: { target: UmbInputManifestElement }) {
const selectedManifest = event.target.value;
this._selectedManifest = selectedManifest?.value ?? '';
}
override render() {
return html`
<uui-box>
<umb-property-layout label="Select a workspace">
<div slot="editor">
<umb-input-manifest
.extensionType=${};
}
}
import { html, customElement, state, when, nothing } from '@umbraco-cms/backoffice/external/lit';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UmbInputManifestElement } from '@umbraco-cms/backoffice/components';
import type { UUISelectEvent } from '@umbraco-cms/backoffice/external/uui';
interface Option {
name: string;
value: string;
selected: boolean;
}
@customElement('my-extension-browser')
export class MyExtensionBrowserElement extends UmbLitElement {
#options: Option[] = [];
@state()
private _selectedExtensionType = 'dashboard';
@state()
private _selectedManifest = '';
constructor() {
super();
// Build list of available extension types from registry
this.(umbExtensionsRegistry., {
types = [... (extensions.( x.))];
.#options = types.().( ({
: x,
: x,
: x === .,
}));
});
}
#() {
. = ;
. = event.. ;
}
#() {
selectedManifest = event..;
. = selectedManifest?. ?? ;
}
() {
html`;
}
}
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
// In your element constructor
this.observe(umbExtensionsRegistry.extensions, (extensions) => {
// Get unique extension types
const types = [...new Set(extensions.map((x) => x.type))];
console.log('Available types:', types);
// Filter by type
const dashboards = extensions.filter((x) => x.type === 'dashboard');
console.log('Dashboards:', dashboards);
// Get extension by alias
const specific = extensions.find((x) => x.alias === 'Umb.Dashboard.Welcome');
console.log('Specific extension:', specific);
});
| Type | Description |
|---|---|
dashboard | Section dashboards |
workspace | Entity workspaces |
workspaceView | Views within workspaces |
workspaceAction | Workspace action buttons |
propertyEditorUi | Property editor UIs |
propertyEditorSchema | Property editor schemas |
entityAction | Context menu actions |
tree | Navigation trees |
treeItem | Tree item renderers |
section | Backoffice sections |
sectionView | Section views |
headerApp | Header bar apps |
modal | Modal dialogs |
condition | Extension conditions |
| Property | Type | Description |
|---|---|---|
extensionType | string | The type of extension to pick from |
value | ManifestBase | undefined | The selected manifest |
| Event | Detail | Description |
|---|---|---|
change | { target: UmbInputManifestElement } | Fired when selection changes |
#onManifestChange(event: { target: UmbInputManifestElement }) {
const manifest = event.target.value;
if (manifest) {
console.log('Alias:', manifest.alias);
console.log('Name:', manifest.name);
console.log('Type:', manifest.type);
console.log('Full manifest:', manifest);
}
}
_selectedManifest when type changesvalue exists before accessing properties<umb-property-layout> for consistent stylingThat's it! Always fetch fresh docs, keep examples minimal, generate complete working code.