重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
umbraco-workspace by umbraco/umbraco-cms-backoffice-skills
npx skills add https://github.com/umbraco/umbraco-cms-backoffice-skills --skill umbraco-workspace工作区是 Umbraco 中为特定实体类型设计的专用编辑环境。它们创建了独立的区域,用户可以在其中使用针对每种类型定制的专用界面来编辑内容、媒体、成员和其他实体。工作区维护与已发布版本分离的实体数据草稿副本,并支持多种扩展类型,包括上下文、视图、操作和页脚应用。
在实施前务必获取最新文档:
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
kind: 'default' 与 kind: 'routable'| 特性 | kind: 'default' | kind: 'routable' |
|---|---|---|
| 使用场景 | 静态页面,根工作区 | 具有唯一 ID 的实体编辑 |
| 树集成 | 无选择状态 | 正确的选择状态 |
| URL 路由 | 无路由参数 | 支持 edit/:unique |
| 上下文 | 简单 | 具有 unique 可观察对象 |
对于树项导航,务必使用 kind: 'routable' - 否则:
对于 kind: 'routable' 工作区,必须创建一个工作区上下文类:
import { UmbWorkspaceRouteManager, UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import { LitElement, html } from '@umbraco-cms/backoffice/external/lit';
import { customElement } from '@umbraco-cms/backoffice/external/lit';
// 渲染视图的工作区编辑器元素
@customElement('my-workspace-editor')
class MyWorkspaceEditorElement extends LitElement {
override render() {
return html`<umb-workspace-editor></umb-workspace-editor>`;
}
}
interface MyEntityData {
unique: string;
name?: string;
}
export class MyWorkspaceContext extends UmbContextBase {
public readonly workspaceAlias = 'My.Workspace';
#data = new UmbObjectState<MyEntityData | undefined>(undefined);
readonly data = this.#data.asObservable();
// 关键:工作区视图使用的可观察唯一标识符
readonly unique = this.#data.asObservablePart((data) => data?.unique);
readonly name = this.#data.asObservablePart((data) => data?.name);
readonly routes = new UmbWorkspaceRouteManager(this);
constructor(host: UmbControllerHost) {
super(host, UMB_WORKSPACE_CONTEXT);
// 树项导航的路由模式
this.routes.setRoutes([
{
path: 'edit/:unique',
component: MyWorkspaceEditorElement,
setup: (_component, info) => {
const unique = info.match.params.unique;
this.load(unique);
},
},
]);
}
async load(unique: string) {
// 加载实体数据并更新状态
this.#data.setValue({ unique });
}
getUnique() {
return this.#data.getValue()?.unique;
}
getEntityType() {
return 'my-entity'; // 必须与树项 entityType 匹配!
}
public override destroy(): void {
this.#data.destroy();
super.destroy();
}
}
export { MyWorkspaceContext as api };
工作区视图观察上下文的 unique 以响应导航:
import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
override connectedCallback() {
super.connectedCallback();
this.consumeContext(UMB_WORKSPACE_CONTEXT, (context) => {
if (!context) return;
// 观察唯一标识符 - 在项之间导航时会触发
this.observe((context as any).unique, (unique: string | null) => {
if (unique) {
this._loadData(unique);
}
});
});
}
Umbraco 源代码包含工作示例:
工作区上下文计数器 : /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/workspace-context-counter/
此示例演示了包含上下文、视图和页脚应用的工作区。包含单元测试。
工作区上下文初始名称 : /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/
此示例展示了工作区上下文初始化模式。
工作区视图提示 : /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/workspace-view-hint/
此示例演示了工作区视图提示和元数据。
如果在实现工作区时需要解释这些基础概念,请参考以下技能:
上下文 API : 当实现工作区上下文、上下文消费或解释工作区扩展通信时
umbraco-context-api状态管理 : 当实现草稿状态、可观察对象、响应式更新或工作区数据管理时
umbraco-state-managementUmbraco 元素 : 当实现工作区视图元素、解释 UmbElementMixin 或创建工作区组件时
umbraco-umbraco-element控制器 : 当实现工作区操作、控制器、副作用或操作逻辑时
umbraco-controllers树 : 当工作区链接到树导航时
umbraco-treekind: 'routable',静态页面使用 kind: 'default'.csproj 文件
* 如果恰好找到一个 Umbraco 实例,则向其添加引用
* 如果找到多个 Umbraco 实例,询问用户使用哪一个
* 如果未找到 Umbraco 实例,向用户询问路径export const manifests: UmbExtensionManifest[] = [
// 用于树集成的可路由工作区
{
type: 'workspace',
kind: 'routable',
alias: 'My.Workspace',
name: 'My Workspace',
api: () => import('./my-workspace.context.js'),
meta: {
entityType: 'my-entity', // 必须与树项 entityType 匹配!
},
},
// 工作区视图
{
type: 'workspaceView',
alias: 'My.WorkspaceView',
name: 'My Workspace View',
element: () => import('./my-workspace-view.element.js'),
weight: 100,
meta: {
label: 'Details',
pathname: 'details',
icon: 'icon-info',
},
conditions: [
{
alias: 'Umb.Condition.WorkspaceAlias',
match: 'My.Workspace',
},
],
},
];
在生成代码之前务必获取最新文档 - API 和模式可能已更改。
每周安装次数
70
仓库
GitHub 星标数
14
首次出现
2026年2月4日
安全审计
安装于
github-copilot51
cursor24
opencode22
codex22
gemini-cli20
amp20
Workspaces are dedicated editing environments designed for specific entity types in Umbraco. They create isolated areas where users can edit content, media, members, and other entities with specialized interfaces tailored to each type. Workspaces maintain draft copies of entity data separate from published versions and support multiple extension types including contexts, views, actions, and footer apps.
Always fetch the latest docs before implementing:
kind: 'default' vs kind: 'routable'| Feature | kind: 'default' | kind: 'routable' |
|---|---|---|
| Use case | Static pages, root workspaces | Entity editing with unique IDs |
| Tree integration | No selection state | Proper selection state |
| URL routing | No route params | Supports edit/:unique |
| Context | Simple | Has unique observable |
For tree item navigation, ALWAYS usekind: 'routable' - otherwise:
For kind: 'routable' workspaces, you MUST create a workspace context class:
import { UmbWorkspaceRouteManager, UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import { LitElement, html } from '@umbraco-cms/backoffice/external/lit';
import { customElement } from '@umbraco-cms/backoffice/external/lit';
// Workspace editor element that renders views
@customElement('my-workspace-editor')
class MyWorkspaceEditorElement extends LitElement {
override render() {
return html`<umb-workspace-editor></umb-workspace-editor>`;
}
}
interface MyEntityData {
unique: string;
name?: string;
}
export class MyWorkspaceContext extends UmbContextBase {
public readonly workspaceAlias = 'My.Workspace';
#data = new UmbObjectState<MyEntityData | undefined>(undefined);
readonly data = this.#data.asObservable();
// CRITICAL: Observable unique for workspace views to consume
readonly unique = this.#data.asObservablePart((data) => data?.unique);
readonly name = this.#data.asObservablePart((data) => data?.name);
readonly routes = new UmbWorkspaceRouteManager(this);
constructor(host: UmbControllerHost) {
super(host, UMB_WORKSPACE_CONTEXT);
// Route pattern for tree item navigation
this.routes.setRoutes([
{
path: 'edit/:unique',
component: MyWorkspaceEditorElement,
setup: (_component, info) => {
const unique = info.match.params.unique;
this.load(unique);
},
},
]);
}
async load(unique: string) {
// Load entity data and update state
this.#data.setValue({ unique });
}
getUnique() {
return this.#data.getValue()?.unique;
}
getEntityType() {
return 'my-entity'; // Must match tree item entityType!
}
public override destroy(): void {
this.#data.destroy();
super.destroy();
}
}
export { MyWorkspaceContext as api };
Workspace views observe the context's unique to react to navigation:
import { UMB_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/workspace';
override connectedCallback() {
super.connectedCallback();
this.consumeContext(UMB_WORKSPACE_CONTEXT, (context) => {
if (!context) return;
// Observe unique - will fire when navigating between items
this.observe((context as any).unique, (unique: string | null) => {
if (unique) {
this._loadData(unique);
}
});
});
}
The Umbraco source includes working examples:
Workspace Context Counter : /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/workspace-context-counter/
This example demonstrates a workspace with context, views, and footer apps. Includes unit tests.
Workspace Context Initial Name : /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/workspace-context-initial-name/
This example shows workspace context initialization patterns.
Workspace View Hint : /Umbraco-CMS/src/Umbraco.Web.UI.Client/examples/workspace-view-hint/
This example demonstrates workspace view hints and metadata.
If you need to explain these foundational concepts when implementing workspaces, reference these skills:
Context API : When implementing workspace contexts, context consumption, or explaining workspace extension communication
umbraco-context-apiState Management : When implementing draft state, observables, reactive updates, or workspace data management
umbraco-state-managementUmbraco Element : When implementing workspace view elements, explaining UmbElementMixin, or creating workspace components
umbraco-umbraco-elementControllers : When implementing workspace actions, controllers, side effects, or action logic
umbraco-controllersTrees : When workspace is linked to tree navigation
kind: 'routable' for tree navigation, kind: 'default' for static pages.csproj files in the current working directoryexport const manifests: UmbExtensionManifest[] = [
// Routable workspace for tree integration
{
type: 'workspace',
kind: 'routable',
alias: 'My.Workspace',
name: 'My Workspace',
api: () => import('./my-workspace.context.js'),
meta: {
entityType: 'my-entity', // Must match tree item entityType!
},
},
// Workspace view
{
type: 'workspaceView',
alias: 'My.WorkspaceView',
name: 'My Workspace View',
element: () => import('./my-workspace-view.element.js'),
weight: 100,
meta: {
label: 'Details',
pathname: 'details',
icon: 'icon-info',
},
conditions: [
{
alias: 'Umb.Condition.WorkspaceAlias',
match: 'My.Workspace',
},
],
},
];
Always fetch fresh docs before generating code - the API and patterns may have changed.
Weekly Installs
70
Repository
GitHub Stars
14
First Seen
Feb 4, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
github-copilot51
cursor24
opencode22
codex22
gemini-cli20
amp20
2025 Node.js 最佳实践指南:框架选择、架构原则与错误处理
5,500 周安装
umbraco-tree