mcpField
U
umbraco-manifest-picker

umbraco-manifest-picker

github.com/umbraco开发27385 次安装6 周前更新
代码仓库

关于 umbraco-manifest-picker

用于构建 Umbraco 后台界面的技能,可让用户选择已注册的扩展。内容涵盖选择器配置、动态扩展类型及所选清单的处理。

主要功能

  1. 01选择已注册的扩展清单
  2. 02按扩展类型筛选选项
  3. 03处理选择变更事件
  4. 04查看所选清单数据

适用场景

  1. 01在设置中选择仪表板或工作区
  2. 02配置导航目标
  3. 03选择要应用的条件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/umbraco/umbraco-cms-backoffice-skills --skill umbraco-manifest-picker

安装后在 Claude Code 中输入/umbraco-manifest-picker确认已加载。

详细介绍

Umbraco 清单选择器

这是什么?

<umb-input-manifest> 组件提供了一个选择器 UI,可从 Umbraco 扩展注册表中选择已注册的扩展。用户可以选择任意扩展类型(工作区、仪表板、属性编辑器等),并返回所选清单。这适用于用户需要引用其他扩展的配置 UI。

文档

实现前请务必获取最新文档:

参考示例

Umbraco 源码中包含一个可运行的示例:

位置:/Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/manifest-picker/

此示例展示了一个仪表板,用户可以按类型浏览和选择扩展。

相关 Foundation 技能

  • 扩展注册表:了解如何注册扩展

    • 参考技能:umbraco-extension-registry
  • Umbraco Element:用于创建选择器 UI

    • 参考技能:umbraco-umbraco-element

工作流

  1. 获取文档 - 对上述 URL 使用 WebFetch
  2. 提问 - 要选择哪些扩展类型?如何使用所选项?
  3. 生成文件 - 创建带清单选择器的元素
  4. 说明 - 展示创建的内容以及选择的工作方式

基本用法

import { 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=${'workspace'}
              @change=${this.#onChange}
            ></umb-input-manifest>
          </div>
        </umb-property-layout>

        ${this._selectedManifest
          ? html`<p>Selected: <code>${this._selectedManifest}</code></p>`
          : ''}
      </uui-box>
    `;
  }
}

动态选择扩展类型

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.observe(umbExtensionsRegistry.extensions, (extensions) => {
      const types = [...new Set(extensions.map((x) => x.type))];
      this.#options = types.sort().map((x) => ({
        name: x,
        value: x,
        selected: x === this._selectedExtensionType,
      }));
    });
  }

  #onTypeSelect(event: UUISelectEvent) {
    this._selectedManifest = '';
    this._selectedExtensionType = event.target.value as string;
  }

  #onManifestChange(event: { target: UmbInputManifestElement }) {
    const selectedManifest = event.target.value;
    this._selectedManifest = selectedManifest?.value ?? '';
  }

  override render() {
    return html`
      <uui-box>
        <umb-property-layout label="Extension Type">
          <uui-select
            slot="editor"
            label="Select type"
            placeholder="Select type..."
            .options=${this.#options}
            @change=${this.#onTypeSelect}
          ></uui-select>
        </umb-property-layout>

        ${when(
          this._selectedExtensionType,
          () => html`
            <umb-property-layout
              label="Select Extension"
              description="Pick a ${this._selectedExtensionType}"
            >
              <div slot="editor">
                <umb-input-manifest
                  .extensionType=${this._selectedExtensionType}
                  @change=${this.#onManifestChange}
                ></umb-input-manifest>
              </div>
            </umb-property-layout>
          `,
          () => nothing
        )}

        ${when(
          this._selectedManifest,
          () => html`
            <umb-property-layout label="Selected Manifest">
              <div slot="editor">
                <code>${this._selectedManifest}</code>
              </div>
            </umb-property-layout>
          `,
          () => nothing
        )}
      </uui-box>
    `;
  }
}

获取所有扩展类型

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);
});

常见扩展类型

类型说明
dashboard区段仪表板
workspace实体工作区
workspaceView工作区内的视图
workspaceAction工作区操作按钮
propertyEditorUi属性编辑器 UI
propertyEditorSchema属性编辑器架构
entityAction上下文菜单操作
tree导航树
treeItem树项渲染器
section后台管理区段
sectionView区段视图
headerApp标题栏应用
modal模态对话框
condition扩展条件

UmbInputManifest 属性

属性类型说明
extensionTypestring要从中选择的扩展类型
valueManifestBase | undefined所选清单

事件

事件详情说明
change{ target: UmbInputManifestElement }选择更改时触发

访问所选清单数据

#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);
  }
}

使用场景

  1. 配置页面 - 让用户选择要显示的仪表板/工作区
  2. 扩展管理 - 浏览和检查已注册的扩展
  3. 动态路由 - 配置导航目标
  4. 条件配置 - 选择要应用的条件
  5. 包开发 - 测试扩展注册

最佳实践

  1. 清除选择 - 类型更改时重置 _selectedManifest
  2. 处理 undefined - 访问属性前检查 value 是否存在
  3. 使用属性布局 - 使用 <umb-property-layout> 包裹,以保持样式一致
  4. 显示反馈 - 显示所选清单的别名/名称,以确认选择
  5. 对类型排序 - 按字母顺序排列扩展类型选项,以便于使用

就是这样!请务必获取最新文档,保持示例简洁,并生成完整可运行的代码。

评论

支持 Markdown