umbraco-extension-registry

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Umbraco Extension Registry

Umbraco扩展注册表

What is it?

什么是扩展注册表?

The Extension Registry is the core system managing all Umbraco backoffice UI elements - almost any UI in the Backoffice is an extension managed by the Extension Registry. The registry allows developers to dynamically add, remove, or modify extensions at runtime using
umbExtensionsRegistry
. Developers have the same possibilities as Umbraco HQ, meaning you can change almost everything that is by default present in Umbraco.
扩展注册表是管理所有Umbraco后台UI元素的核心系统——后台中几乎所有UI都是由扩展注册表管理的扩展。开发者可以通过
umbExtensionsRegistry
在运行时动态添加、移除或修改扩展。开发者拥有与Umbraco官方团队相同的权限,这意味着你可以修改Umbraco默认提供的几乎所有内容。

Documentation

文档

Workflow

工作流程

  1. Fetch docs - Use WebFetch on the URLs above
  2. Ask questions - Register, exclude, or replace? Runtime or static? Conditions needed?
  3. Generate code - Implement registry operations based on latest docs
  4. Explain - Show what was created and how extensions are managed
  1. 获取文档 - 使用WebFetch访问上述URL
  2. 提出问题 - 是注册、排除还是替换?运行时还是静态?是否需要条件?
  3. 生成代码 - 根据最新文档实现注册表操作
  4. 解释说明 - 展示创建的内容以及扩展的管理方式

Minimal Examples

极简示例

Register Extension (Runtime)

注册扩展(运行时)

typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

const manifest = {
  type: 'dashboard',
  alias: 'My.Dashboard',
  name: 'My Dashboard',
  element: () => import('./dashboard.element.js'),
  meta: {
    label: 'My Dashboard',
    pathname: 'my-dashboard'
  }
};

umbExtensionsRegistry.register(manifest);
typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

const manifest = {
  type: 'dashboard',
  alias: 'My.Dashboard',
  name: 'My Dashboard',
  element: () => import('./dashboard.element.js'),
  meta: {
    label: 'My Dashboard',
    pathname: 'my-dashboard'
  }
};

umbExtensionsRegistry.register(manifest);

Exclude Extension

排除扩展

typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

// Permanently hide an extension
umbExtensionsRegistry.exclude('Umb.WorkspaceAction.Document.SaveAndPreview');
typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

// 永久隐藏某个扩展
umbExtensionsRegistry.exclude('Umb.WorkspaceAction.Document.SaveAndPreview');

Unregister Extension

注销扩展

typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

// Remove extension from registry (can be re-registered)
umbExtensionsRegistry.unregister('My.WorkspaceAction.AutoFillWithUnicorns');
typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

// 从注册表中移除扩展(可重新注册)
umbExtensionsRegistry.unregister('My.WorkspaceAction.AutoFillWithUnicorns');

Replace Extension (Overwrites)

替换扩展(覆盖)

typescript
const manifest = {
  type: 'workspaceAction',
  alias: 'My.WorkspaceAction.ExternalPreview',
  name: 'My Custom Preview',
  overwrites: 'Umb.WorkspaceAction.Document.SaveAndPreview',
  element: () => import('./custom-preview.element.js'),
  // ... rest of manifest
};

umbExtensionsRegistry.register(manifest);
typescript
const manifest = {
  type: 'workspaceAction',
  alias: 'My.WorkspaceAction.ExternalPreview',
  name: 'My Custom Preview',
  overwrites: 'Umb.WorkspaceAction.Document.SaveAndPreview',
  element: () => import('./custom-preview.element.js'),
  // ... 清单的其余部分
};

umbExtensionsRegistry.register(manifest);

Replace Multiple Extensions

替换多个扩展

typescript
const manifest = {
  type: 'workspaceAction',
  alias: 'My.CustomSave',
  name: 'My Custom Save',
  overwrites: [
    'Umb.WorkspaceAction.Document.SaveAndPreview',
    'Umb.WorkspaceAction.Document.Save'
  ],
  // ... rest of manifest
};

umbExtensionsRegistry.register(manifest);
typescript
const manifest = {
  type: 'workspaceAction',
  alias: 'My.CustomSave',
  name: 'My Custom Save',
  overwrites: [
    'Umb.WorkspaceAction.Document.SaveAndPreview',
    'Umb.WorkspaceAction.Document.Save'
  ],
  // ... 清单的其余部分
};

umbExtensionsRegistry.register(manifest);

Entry Point Registration

入口点注册

typescript
// entrypoint.ts
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

export const onInit = (host: UmbEntryPointOnInitArgs) => {
  // Exclude default dashboard
  umbExtensionsRegistry.exclude('Umb.Dashboard.UmbracoNews');

  // Register custom dashboard
  umbExtensionsRegistry.register({
    type: 'dashboard',
    alias: 'My.CustomDashboard',
    name: 'Custom Dashboard',
    element: () => import('./custom-dashboard.element.js'),
    meta: {
      label: 'Welcome',
      pathname: 'welcome'
    },
    conditions: [
      {
        alias: 'Umb.Condition.SectionAlias',
        match: 'Umb.Section.Content'
      }
    ]
  });
};
typescript
// entrypoint.ts
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

export const onInit = (host: UmbEntryPointOnInitArgs) => {
  // 排除默认仪表盘
  umbExtensionsRegistry.exclude('Umb.Dashboard.UmbracoNews');

  // 注册自定义仪表盘
  umbExtensionsRegistry.register({
    type: 'dashboard',
    alias: 'My.CustomDashboard',
    name: 'Custom Dashboard',
    element: () => import('./custom-dashboard.element.js'),
    meta: {
      label: 'Welcome',
      pathname: 'welcome'
    },
    conditions: [
      {
        alias: 'Umb.Condition.SectionAlias',
        match: 'Umb.Section.Content'
      }
    ]
  });
};

Dynamic Registration from Server Data

从服务器数据动态注册

typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

async function registerDynamicDashboards() {
  // Fetch configuration from server
  const response = await fetch('/api/dashboard-config');
  const dashboards = await response.json();

  // Register each dashboard dynamically
  dashboards.forEach(config => {
    umbExtensionsRegistry.register({
      type: 'dashboard',
      alias: config.alias,
      name: config.name,
      element: () => import(config.elementPath),
      meta: {
        label: config.label,
        pathname: config.pathname
      }
    });
  });
}
typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

async function registerDynamicDashboards() {
  // 从服务器获取配置
  const response = await fetch('/api/dashboard-config');
  const dashboards = await response.json();

  // 动态注册每个仪表盘
  dashboards.forEach(config => {
    umbExtensionsRegistry.register({
      type: 'dashboard',
      alias: config.alias,
      name: config.name,
      element: () => import(config.elementPath),
      meta: {
        label: config.label,
        pathname: config.pathname
      }
    });
  });
}

Conditional Registration

条件注册

typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

// Register extension only if condition is met
if (userIsAdmin) {
  umbExtensionsRegistry.register({
    type: 'dashboard',
    alias: 'My.AdminDashboard',
    name: 'Admin Dashboard',
    element: () => import('./admin-dashboard.element.js'),
    meta: {
      label: 'Admin',
      pathname: 'admin'
    }
  });
}
typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

// 仅在满足条件时注册扩展
if (userIsAdmin) {
  umbExtensionsRegistry.register({
    type: 'dashboard',
    alias: 'My.AdminDashboard',
    name: 'Admin Dashboard',
    element: () => import('./admin-dashboard.element.js'),
    meta: {
      label: 'Admin',
      pathname: 'admin'
    }
  });
}

Batch Operations

批量操作

typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

// Exclude multiple extensions
const extensionsToHide = [
  'Umb.Dashboard.UmbracoNews',
  'Umb.Dashboard.RedirectManagement',
];

extensionsToHide.forEach(alias => {
  umbExtensionsRegistry.exclude(alias);
});

// Register multiple extensions
const myExtensions = [
  { type: 'dashboard', alias: 'My.Dashboard1', /* ... */ },
  { type: 'dashboard', alias: 'My.Dashboard2', /* ... */ },
];

myExtensions.forEach(manifest => {
  umbExtensionsRegistry.register(manifest);
});
typescript
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';

// 排除多个扩展
const extensionsToHide = [
  'Umb.Dashboard.UmbracoNews',
  'Umb.Dashboard.RedirectManagement',
];

extensionsToHide.forEach(alias => {
  umbExtensionsRegistry.exclude(alias);
});

// 注册多个扩展
const myExtensions = [
  { type: 'dashboard', alias: 'My.Dashboard1', /* ... */ },
  { type: 'dashboard', alias: 'My.Dashboard2', /* ... */ },
];

myExtensions.forEach(manifest => {
  umbExtensionsRegistry.register(manifest);
});

View Registered Extensions

查看已注册扩展

Navigate to: Settings > Extensions Insights in the backoffice to see all registered extensions.
在后台导航至:设置 > 扩展洞察,即可查看所有已注册的扩展。

Key Concepts

核心概念

umbExtensionsRegistry: Central registry for managing extensions
register(): Add new extension at runtime
exclude(): Permanently hide extension (never displayed)
unregister(): Remove extension from registry (can be re-registered)
overwrites: Replace existing extension(s) with custom implementation
Runtime vs Static:
  • Static: Use
    umbraco-package.json
    for most extensions
  • Runtime: Use
    umbExtensionsRegistry
    for dynamic/conditional registration
Entry Point: Common place to execute registry operations during startup
Extension Insights: View all registered extensions at Settings > Extensions Insights
Use Cases:
  • Hide default Umbraco features
  • Register extensions based on server data
  • Replace built-in actions with custom logic
  • Conditionally enable features
  • Dynamic dashboard registration
umbExtensionsRegistry:管理扩展的中央注册表
register():在运行时添加新扩展
exclude():永久隐藏扩展(不会被显示)
unregister():从注册表中移除扩展(可重新注册)
overwrites:用自定义实现替换现有扩展
运行时 vs 静态
  • 静态:对于大多数扩展,使用
    umbraco-package.json
  • 运行时:使用
    umbExtensionsRegistry
    进行动态/条件注册
入口点:在启动时执行注册表操作的常用位置
扩展洞察:在“设置 > 扩展洞察”中查看所有已注册扩展
使用场景
  • 隐藏Umbraco默认功能
  • 根据服务器数据注册扩展
  • 用自定义逻辑替换内置操作
  • 有条件地启用功能
  • 动态注册仪表盘

Sources

来源

That's it! Always fetch fresh docs, keep examples minimal, generate complete working code.
就是这样!请始终获取最新文档,保持示例极简,生成完整可运行的代码。