diff --git a/14/umbraco-cms/.gitbook.yaml b/14/umbraco-cms/.gitbook.yaml
index 16658e92984..5da1f71712e 100644
--- a/14/umbraco-cms/.gitbook.yaml
+++ b/14/umbraco-cms/.gitbook.yaml
@@ -103,3 +103,24 @@ redirects:
fundamentals/backoffice/infinite-editing: fundamentals/backoffice/sidebar.md
extending/backoffice-tours: extending/README.md
tutorials/creating-a-backoffice-tour: tutorials/overview.md
+ customize-the-backoffce/extending-overview/extending-types/dashboard: customizing/extending-overview/extending-types/dashboard.md
+ customize-the-backoffce/extending-overview/extending-types/entity-actions: customizing/extending-overview/extending-types/entity-actions.md
+ customize-the-backoffce/extending-overview/extending-types/entity-bulk-actions: customizing/extending-overview/extending-types/entity-bulk-actions.md
+ customize-the-backoffce/extending-overview/extending-types/global-context: customizing/extending-overview/extending-types/global-context.md
+ customize-the-backoffce/extending-overview/extending-types/localization: customizing/extending-overview/extending-types/localization.md
+ customize-the-backoffce/extending-overview/extending-types/section-view: customizing/extending-overview/extending-types/section-view.md
+ customize-the-backoffce/extending-overview/extending-types/section: customizing/extending-overview/extending-types/section.md
+ customize-the-backoffce/extending-overview/extending-types/tree: customizing/extending-overview/extending-types/tree.md
+ customize-the-backoffce/extending-overview/extending-types/section-sidebar: customizing/extending-overview/extending-types/section-sidebar.md
+ customize-the-backoffce/extending-overview/extending-types/workspace-context: customizing/extending-overview/extending-types/workspace-context.md
+ customize-the-backoffce/extending-overview/extending-types/workspace-view: customizing/extending-overview/extending-types/workspace-view.md
+ customize-the-backoffice/foundation/contexts/property-dataset-context: customizing/foundation/context/property-dataset-context.md
+ customize-the-backoffice/foundation/icons: customizing/foundation/icons.md
+ customize-the-backoffice/foundation/localization: customizing/foundation/localization.md
+ customize-the-backoffice/foundation/terminology: customizing/foundation/terminology.md
+ customize-the-backoffice/overivew: customizing/overview.md
+ customize-the-backoffice/searchable-trees: customizing/searchable-trees.md
+ customize-the-backoffice/section-trees: customizing/section-trees.md
+ customize-the-backoffice/ui-library: customizing/ui-library.md
+ customize-the-backoffice/umbraco-package: customizing/umbraco-package.md
+ customize-the-backoffice/workspaces: customizing/workspaces.md
diff --git a/14/umbraco-cms/SUMMARY.md b/14/umbraco-cms/SUMMARY.md
index a7fea1c84ee..b2f80825b45 100644
--- a/14/umbraco-cms/SUMMARY.md
+++ b/14/umbraco-cms/SUMMARY.md
@@ -139,7 +139,7 @@
## Customize the Backoffice
-* [Extend and customize the editing experience](customize-the-backoffice/overview.md)
+* [Extend and customize the editing experience](customizing/overview.md)
* [Project Bellissima](customizing/project-bellissima.md)
* [Setup Your Development Environment](customizing/development-flow/README.md)
* [Vite Package Setup](customizing/development-flow/vite-package-setup.md)
@@ -150,15 +150,15 @@
* [Store](customizing/foundation/working-with-data/store.md)
* [States](customizing/foundation/working-with-data/states.md)
* [Contexts](customizing/foundation/contexts/README.md)
- * [Property Dataset Context](customize-the-backoffice/foundation/contexts/property-dataset-context.md)
+ * [Property Dataset Context](customizing/foundation/contexts/property-dataset-context.md)
* [Umbraco Element](customizing/foundation/umbraco-element/README.md)
* [Controllers](customizing/foundation/umbraco-element/controllers/README.md)
* [Write your own controller](customizing/foundation/umbraco-element/controllers/write-your-own-controller.md)
* [Sorting](customizing/foundation/sorting.md)
* [Routes](customizing/foundation/routes.md)
- * [Icons](customize-the-backoffice/foundation/icons.md)
- * [Backoffice Localization](customize-the-backoffice/foundation/localization.md)
- * [Terminology](customize-the-backoffice/foundation/terminology.md)
+ * [Icons](customizing/foundation/icons.md)
+ * [Backoffice Localization](customizing/foundation/localization.md)
+ * [Terminology](customizing/foundation/terminology.md)
* [Extension Overview](customizing/extending-overview/README.md)
* [Extension Registry](customizing/extending-overview/extension-registry/README.md)
* [Extension Registration](customizing/extending-overview/extension-registry/extension-registry.md)
@@ -175,23 +175,23 @@
* [Kind](customizing/extending-overview/extension-types/kind.md)
* [Backoffice Entry Point](customizing/extending-overview/extension-types/backoffice-entry-point.md)
* [Extension Conditions](customizing/extending-overview/extension-types/condition.md)
- * [Dashboards](customize-the-backoffice/extending-overview/extension-types/dashboard.md)
- * [Entity Actions](customize-the-backoffice/extending-overview/extension-types/entity-actions.md)
- * [Entity Bulk Actions](customize-the-backoffice/extending-overview/extension-types/entity-bulk-actions.md)
- * [Trees](customize-the-backoffice/extending-overview/extension-types/tree.md)
- * [Global Context](customize-the-backoffice/extending-overview/extension-types/global-context.md)
- * [Section Sidebar](customize-the-backoffice/extending-overview/extension-types/section-sidebar.md)
- * [Section View](customize-the-backoffice/extending-overview/extension-types/section-view.md)
- * [Sections](customize-the-backoffice/extending-overview/extension-types/section.md)
- * [Workspace Context](customize-the-backoffice/extending-overview/extension-types/workspace-context.md)
- * [Workspace Views](customize-the-backoffice/extending-overview/extension-types/workspace-views.md)
- * [Workspace Actions](customize-the-backoffice/extending-overview/extension-types/workspace-editor-actions.md)
- * [Localization](customize-the-backoffice/extending-overview/extension-types/localization.md)
+ * [Dashboards](customizing/extending-overview/extension-types/dashboard.md)
+ * [Entity Actions](customizing/extending-overview/extension-types/entity-actions.md)
+ * [Entity Bulk Actions](customizing/extending-overview/extension-types/entity-bulk-actions.md)
+ * [Trees](customizing/extending-overview/extension-types/tree.md)
+ * [Global Context](customizing/extending-overview/extension-types/global-context.md)
+ * [Section Sidebar](customizing/extending-overview/extension-types/section-sidebar.md)
+ * [Section View](customizing/extending-overview/extension-types/section-view.md)
+ * [Sections](customizing/extending-overview/extension-types/section.md)
+ * [Workspace Context](customizing/extending-overview/extension-types/workspace-context.md)
+ * [Workspace Views](customizing/extending-overview/extension-types/workspace-views.md)
+ * [Workspace Actions](customizing/extending-overview/extension-types/workspace-editor-actions.md)
+ * [Localization](customizing/extending-overview/extension-types/localization.md)
* [Extension Kind](customizing/extending-overview/extension-kind.md)
* [Extension Conditions](customizing/extending-overview/extension-conditions.md)
* [Custom Extension types](customizing/extending-overview/custom-extension-type.md)
-* [Sections & Trees](customize-the-backoffice/section-trees.md)
-* [Searchable Trees (ISearchableTree)](customize-the-backoffice/searchable-trees.md)
+* [Sections & Trees](customizing/section-trees.md)
+* [Searchable Trees (ISearchableTree)](customizing/searchable-trees.md)
* [Property Editors](customizing/property-editors/README.md)
* [Property Editors Composition](customizing/property-editors/composition/README.md)
* [Property Editor Schema](customizing/property-editors/composition/property-editor-schema.md)
@@ -204,9 +204,9 @@
* [Content Picker Value Converter Example](customizing/property-editors/full-examples-value-converters.md)
* [Property Dataset](customizing/property-editors/property-dataset.md)
* [Integrate Validaction](customizing/property-editors/integrate-validation.md)
-* [Workspaces](customize-the-backoffice/workspaces.md)
-* [Umbraco Package](customize-the-backoffice/umbraco-package.md)
-* [UI Library](customize-the-backoffice/ui-library.md)
+* [Workspaces](customizing/workspaces.md)
+* [Umbraco Package](customizing/umbraco-package.md)
+* [UI Library](customizing/ui-library.md)
## Extending
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/dashboard.md b/14/umbraco-cms/customizing/extending-overview/extension-types/dashboard.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/dashboard.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/dashboard.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/entity-actions.md b/14/umbraco-cms/customizing/extending-overview/extension-types/entity-actions.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/entity-actions.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/entity-actions.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/entity-bulk-actions.md b/14/umbraco-cms/customizing/extending-overview/extension-types/entity-bulk-actions.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/entity-bulk-actions.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/entity-bulk-actions.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/global-context.md b/14/umbraco-cms/customizing/extending-overview/extension-types/global-context.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/global-context.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/global-context.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/localization.md b/14/umbraco-cms/customizing/extending-overview/extension-types/localization.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/localization.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/localization.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/section-sidebar.md b/14/umbraco-cms/customizing/extending-overview/extension-types/section-sidebar.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/section-sidebar.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/section-sidebar.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/section-view.md b/14/umbraco-cms/customizing/extending-overview/extension-types/section-view.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/section-view.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/section-view.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/section.md b/14/umbraco-cms/customizing/extending-overview/extension-types/section.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/section.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/section.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/tree.md b/14/umbraco-cms/customizing/extending-overview/extension-types/tree.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/tree.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/tree.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/workspace-context.md b/14/umbraco-cms/customizing/extending-overview/extension-types/workspace-context.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/workspace-context.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/workspace-context.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/workspace-editor-actions.md b/14/umbraco-cms/customizing/extending-overview/extension-types/workspace-editor-actions.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/workspace-editor-actions.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/workspace-editor-actions.md
diff --git a/14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/workspace-views.md b/14/umbraco-cms/customizing/extending-overview/extension-types/workspace-views.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/extending-overview/extension-types/workspace-views.md
rename to 14/umbraco-cms/customizing/extending-overview/extension-types/workspace-views.md
diff --git a/14/umbraco-cms/customize-the-backoffice/foundation/contexts/property-dataset-context.md b/14/umbraco-cms/customizing/foundation/contexts/property-dataset-context.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/foundation/contexts/property-dataset-context.md
rename to 14/umbraco-cms/customizing/foundation/contexts/property-dataset-context.md
diff --git a/14/umbraco-cms/customize-the-backoffice/foundation/icons.md b/14/umbraco-cms/customizing/foundation/icons.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/foundation/icons.md
rename to 14/umbraco-cms/customizing/foundation/icons.md
diff --git a/14/umbraco-cms/customize-the-backoffice/foundation/localization.md b/14/umbraco-cms/customizing/foundation/localization.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/foundation/localization.md
rename to 14/umbraco-cms/customizing/foundation/localization.md
diff --git a/14/umbraco-cms/customize-the-backoffice/foundation/terminology.md b/14/umbraco-cms/customizing/foundation/terminology.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/foundation/terminology.md
rename to 14/umbraco-cms/customizing/foundation/terminology.md
diff --git a/14/umbraco-cms/customize-the-backoffice/overview.md b/14/umbraco-cms/customizing/overview.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/overview.md
rename to 14/umbraco-cms/customizing/overview.md
diff --git a/14/umbraco-cms/customize-the-backoffice/searchable-trees.md b/14/umbraco-cms/customizing/searchable-trees.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/searchable-trees.md
rename to 14/umbraco-cms/customizing/searchable-trees.md
diff --git a/14/umbraco-cms/customize-the-backoffice/section-trees.md b/14/umbraco-cms/customizing/section-trees.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/section-trees.md
rename to 14/umbraco-cms/customizing/section-trees.md
diff --git a/14/umbraco-cms/customize-the-backoffice/ui-library.md b/14/umbraco-cms/customizing/ui-library.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/ui-library.md
rename to 14/umbraco-cms/customizing/ui-library.md
diff --git a/14/umbraco-cms/customize-the-backoffice/umbraco-package.md b/14/umbraco-cms/customizing/umbraco-package.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/umbraco-package.md
rename to 14/umbraco-cms/customizing/umbraco-package.md
diff --git a/14/umbraco-cms/customize-the-backoffice/workspaces.md b/14/umbraco-cms/customizing/workspaces.md
similarity index 100%
rename from 14/umbraco-cms/customize-the-backoffice/workspaces.md
rename to 14/umbraco-cms/customizing/workspaces.md
diff --git a/15/umbraco-cms/SUMMARY.md b/15/umbraco-cms/SUMMARY.md
index 1a22f92f9a5..163278f2f8b 100644
--- a/15/umbraco-cms/SUMMARY.md
+++ b/15/umbraco-cms/SUMMARY.md
@@ -40,6 +40,7 @@
* [Health Check](extending/health-check/README.md)
* [Health Check Guides](extending/health-check/guides/README.md)
* [Content Content Security Policy (CSP)](extending/health-check/guides/contentsecuritypolicy.md)
+* [Creating a Custom Database Table](extending/database.md)
## Reference
@@ -73,6 +74,7 @@
* [Type finder settings](reference/configuration/typefindersettings.md)
* [Unattended](reference/configuration/unattendedsettings.md)
* [Web routing](reference/configuration/webroutingsettings.md)
+* [Common Pitfalls & Anti-Patterns](reference/common-pitfalls.md)
## Tutorials
diff --git a/15/umbraco-cms/customizing/development-flow/vite-package-setup.md b/15/umbraco-cms/customizing/development-flow/vite-package-setup.md
index 288db06e101..6d88193858a 100644
--- a/15/umbraco-cms/customizing/development-flow/vite-package-setup.md
+++ b/15/umbraco-cms/customizing/development-flow/vite-package-setup.md
@@ -171,7 +171,7 @@ export default class MyElement extends LitElement {
```
{% endhint %}
-Learn more about the abilities of the manifest file in the [Umbraco Package Manifest](../package-manifest.md) article.
+Learn more about the abilities of the manifest file in the [Umbraco Package Manifest](../../customize-the-backoffice/umbraco-package.md) article.
#### Testing your package
diff --git a/15/umbraco-cms/customizing/extending-overview/README.md b/15/umbraco-cms/customizing/extending-overview/README.md
index b04dce24f8a..ff02036a0f8 100644
--- a/15/umbraco-cms/customizing/extending-overview/README.md
+++ b/15/umbraco-cms/customizing/extending-overview/README.md
@@ -4,6 +4,12 @@ description: Getting started with backoffice setup and configurations
# Extension Overview
+The Backoffice architecture is based on Extensions, making different UI parts extendable. Enabling you to append, replace, or remove parts.
+
+You are not limited to any specific tech stack. UI Elements are based on Web Components and the Backoffice APIs are based on native code.
+
+
+
In this section you can find the common terms, concepts and guides used to extend the Umbraco backoffice.
{% hint style="warning" %}
diff --git a/15/umbraco-cms/customizing/extending-overview/custom-extension-type.md b/15/umbraco-cms/customizing/extending-overview/custom-extension-type.md
new file mode 100644
index 00000000000..48284d67b25
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/custom-extension-type.md
@@ -0,0 +1,23 @@
+# Custom Extension Types
+
+The extension registry is an open system, which can hold any Extension Manifest Type. This article describes how you can declare your types.
+Types can be declared for re-useability/maintainability or to open up for other package extensions.
+
+## Manifest Type Declaration
+
+A Manifest Type is declared via a TypeScript Interface, like shown below:
+
+```typescript
+import type { ManifestBase } from '@umbraco-cms/backoffice/extension-api';
+
+export interface ManifestPreviewAppProvider extends ManifestBase {
+ type: 'myPrefixedExtensionType';
+}
+
+// Declare the Manifest Type in the global UmbExtensionManifestMap interface:
+declare global {
+ interface UmbExtensionManifestMap {
+ MyPrefixedExtensionManifest: MyExtensionManifestType;
+ }
+}
+```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-conditions.md b/15/umbraco-cms/customizing/extending-overview/extension-conditions.md
new file mode 100644
index 00000000000..43ed0413918
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-conditions.md
@@ -0,0 +1,49 @@
+---
+description: Learn how to use Extension Conditions when working with the Umbraco backoffice.
+---
+
+# Extension Conditions
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Extension Manifest Conditions enable you to declare requirements for an Extension before it becomes available.
+
+## Utilizing Conditions in your Manifest
+
+Conditions are referenced via their alias. The Declaration of a Condition is shown in the following example:
+
+```typescript
+const manifest = {
+ type: 'workspaceView',
+ ...
+ conditions: [
+ {
+ alias: 'Umb.Condition.WorkspaceAlias',
+ match: 'Umb.Workspace.Document',
+ },
+ ],
+};
+```
+
+By declaring a condition the extension will become available only once the condition is permitted.
+
+The example above requires the nearest Workspaces Alias to be equal to `'Umb.Workspace.Document'`.
+
+When declaring multiple conditions all of them must be permitted for the extension to be available.
+
+## Condition Configuration
+
+The conditions are defined as an array of condition configurations. Each entry can contain the following properties:
+
+* `alias`- The alias of the condition to utilize.
+* `...` - The rest of the properties of the object are specific to the condition configuration.
+
+## Learn more
+
+Learn about built-in conditions and how to create your own:
+
+{% content-ref url="extension-types/condition.md" %}
+Condition Extension Type
+{% endcontent-ref %}
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-kind.md b/15/umbraco-cms/customizing/extending-overview/extension-kind.md
new file mode 100644
index 00000000000..32dbe0443bd
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-kind.md
@@ -0,0 +1,55 @@
+---
+description: Learn how to use the Kind extension in your manifest files when extending the Umbraco CMS backoffice.
+---
+
+# Extension Kind
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Extension Manifest Kind enables declarations to be based upon a preset Manifest.
+
+This is used for maintainability or to inherit existing features.
+
+## Manifest Kind Declaration
+
+A Kind is utilized by declaring it in the `kind` field of a Manifest:
+
+```typescript
+const manifest = {
+ type: 'headerApp',
+ kind: 'button',
+ ...
+};
+```
+
+By declaring a kind, the Manifest will inherit fields of the defined Kind.
+
+A typical use case is a Kind that provides an element, but requires additional meta fields, to fulfill the needs of its element.
+
+In the following example, a manifest using the type 'headerApp' utilizes the 'button' kind. This brings an element and requires some additional information as part of the meta object.
+
+Adding the metadata provides the ability to use and configure existing functionality to a specific need.
+
+```typescript
+const manifest = {
+ type: 'headerApp',
+ kind: 'button',
+ name: 'My Header App Example',
+ alias: 'My.HeaderApp.Example',
+ meta: {
+ label: 'My Example',
+ icon: 'icon-home',
+ href: '/some/path/to/open/when/clicked',
+ },
+};
+```
+
+## Learn more
+
+Learn more about Kinds and how to create your own:
+
+{% content-ref url="extension-types/kind.md" %}
+Kind Extension Type
+{% endcontent-ref %}
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-registry/README.md b/15/umbraco-cms/customizing/extending-overview/extension-registry/README.md
index 1257f680c29..9152123dc7a 100644
--- a/15/umbraco-cms/customizing/extending-overview/extension-registry/README.md
+++ b/15/umbraco-cms/customizing/extending-overview/extension-registry/README.md
@@ -6,15 +6,15 @@ This page is a work in progress and may undergo further revisions, updates, or a
Most of BackOffice is based on Extensions making it crucial to understand how to register your own extensions. This introduction will give you an outline of the abilities of the extension registry.
-## [Extension Registration](./extension-registry.md)
+## [Extension Registration](extension-registry.md)
The extension registry is a global registry that can be accessed and changed at anytime while Backoffice is running.
-## [Extension Manifest](./extension-manifest.md)
+## [Extension Manifest](extension-manifest.md)
Each Extension Manifest has to declare its type, this is used to determine where it hooks into the system. It also looks at what data is required to declare within it.
-## [Extension Types](../extension-types/README.md)
+## [Extension Types](../extension-types/)
### [Extension Conditions](../extension-types/condition.md)
@@ -28,10 +28,10 @@ The kinds feature enables you to base your extension registration on a preset. A
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
```
-### [Entry Point](../extension-types/entry-point.md)
+### [Entry Point](../extension-types/backoffice-entry-point.md)
The Entry Point manifest type is used to register an entry point for the backoffice. An entry point is a single JavaScript file that is loaded when the backoffice is initialized. This file can be used to do anything, this enables more complex logic to take place on startup.
-### [Bundle](../extension-types/bundle.md)
+### [Bundle](../extension-types/bundle.md)
The `bundle` extension type enables you to gather many extension manifests into one.
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-registry/extension-manifest.md b/15/umbraco-cms/customizing/extending-overview/extension-registry/extension-manifest.md
index ae09f33d5f9..404ddb04f0d 100644
--- a/15/umbraco-cms/customizing/extending-overview/extension-registry/extension-manifest.md
+++ b/15/umbraco-cms/customizing/extending-overview/extension-registry/extension-manifest.md
@@ -1,14 +1,16 @@
+---
+description: Learn about the different methods for declaring an Extension Manifest.
+---
+
# Extension Manifest
{% hint style="warning" %}
This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
{% endhint %}
-Each Extension Manifest has to declare its type, this is used to determine where it hooks into the system. It also looks at what data is required to declare within it.
-
-The abilities of the extensions rely on the specific extension type. The Type sets the scene for what the extension can do and what it needs to be utilized. Some extension types rely on a reference to other extensions.
+The Extension Manifest is the point of entry for any extension. This is the declaration of what you want to register.
-The pages of this article describe all the extension types that Backoffice supports. Here is a list of the most common types:
+The content in this section describes all the extension types that the Backoffice supports. Here is a list of the most common types:
{% content-ref url="../../../tutorials/creating-a-custom-dashboard/" %}
[creating-a-custom-dashboard](../../../tutorials/creating-a-custom-dashboard/)
@@ -18,43 +20,71 @@ The pages of this article describe all the extension types that Backoffice suppo
[composition](../../property-editors/composition/)
{% endcontent-ref %}
-{% content-ref url="../../section-trees/" %}
-[section-trees](../../section-trees/)
+{% content-ref url="../../../customize-the-backoffice/section-trees.md" %}
+[section-trees.md](../../../customize-the-backoffice/section-trees.md)
{% endcontent-ref %}
-## Declare Extension Manifest
+## Manifest Data
-Extension Manifest and can be declared in multiple ways. One of these is to declare it as part of the [Umbraco Package Manifest](../../package-manifest.md).
+Each Extension Manifest has to declare its type. This is used to determine where it hooks into the system. It also determines what data is required of this manifest.
-You can declare new Extension Manifests in JavaScript at any given point.
+The abilities of the extensions rely on the specific extension type. The Type sets the scene for what the extension can do and what it needs to be utilized. Some extension types can be made purely via the manifest. Other requires files, like a JavaScript file containing a Web Component.
-```typescript
-import { umbExtensionsRegistry } from "@umbraco-cms/backoffice/extension-registry"
+The required fields of any extension manifest are:
-const manifest = {
- type: '...',
- ...
-};
+* `type` - The type defines the type and purpose of the extension. It is used to determine where the extension will be used and defines the data needed for this manifest.
+* `alias`- The alias is used to identify the extension. This has to be unique for each extension.
+* `name` - The name of the extension. This is used to identify the extension in the UI.
-umbExtensionsRegistry.register(extension);
-```
+Additionally, many extensions supports the use of the following fields:
+
+* `weight` - Define a weight, to determine the importance or visual order of this extension.
+* `conditions` - Define one or more conditions which must be permitted for the extension to become available. [Extension Conditions](../extension-conditions/extension-conditions.md).
+* `kind` - Define a kind-alias of which this manifest should be based upon. Kinds acts like a preset for your manifest. [Extension Kinds](../extension-kind/extension-kind.md).
+
+Many of the Extension Types requires additional information declared as part of a `meta` field.
+
+## Registration
+
+An Extension Manifest can be declared in multiple ways.
+
+The primary way is to declare it as part of the [Umbraco Package Manifest](../../../customize-the-backoffice/umbraco-package.md).
+
+Additionally, two Extension types can be used to register other extensions.
-Backoffice also comes with two Extension types which can be used to register more extensions.
+A typical use case is to declare one main Extension Manifest as part of the [Umbraco Package Manifest](../../../customize-the-backoffice/umbraco-package.md). Such main Extension Manifest would be using one of the following types:
-### Using `bundle` to declare other Extension Manifest
+### The `bundle` extension type
-The bundle extension type can be used for declaring multiple Extension Manifests with JavaScript in a single file.
+The Bundle extension type can be used for declaring multiple Extension Manifests with JavaScript in a single file.
-The bundle declares a single JavaScript file that will be loaded at startup. All the Extension Manifests exported from this Module will be registered in the Extension Registry.
+The Bundle declares a single JavaScript file that will be loaded at startup. All the Extension Manifests exported of this Module will be registered in the Extension Registry.
Read more about the `bundle` extension type in the [Bundle](../../../extending/extending-overview/extension-registry/bundle.md) article.
-### Using `backofficeEntryPoint` as your foundation
+### The `backofficeEntryPoint` extension type
+
+The `backofficeEntryPoint` extension type can run any JavaScript code at startup. This can be used as an entry point for a package.
-The `backofficeEntryPoint` extension type is special, it can be used to run any JavaScript code at startup.\
-This can be used as an entry point for a package.\
The entry point declares a single JavaScript file that will be loaded and run when the Backoffice starts.
-The `entryPbackofficeEntryPointoint` extension is also the way to go if you want to load in external libraries such as jQuery, Angular, React, etc. You can use the `backofficeEntryPoint` to load in the external libraries to be shared by all your extensions. Loading **global CSS files** can also be used in the `backofficeEntryPoint` extension.
+The `entryPbackofficeEntryPointoint` extension is also the way to go if you want to load in external libraries such as jQuery, Angular, or React. You can use the `backofficeEntryPoint` type to load in the external libraries to be shared by all your extensions. Loading **global CSS files** can also be used in the `backofficeEntryPoint` extension.
Read more about the `backofficeEntryPoint` extension type in the [Entry Point](../../../extending/extending-overview/extension-registry/entry-point.md) article.
+
+## Registration via any JavaScript code
+
+Alternatively, an Extension Manifest can be declared in JavaScript at any given point.
+
+The following example shows how to register an extension manifest via JavaScript code:
+
+```typescript
+import { umbExtensionsRegistry } from "@umbraco-cms/backoffice/extension-registry"
+
+const manifest = {
+ type: '...',
+ ...
+};
+
+umbExtensionsRegistry.register(extension);
+```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-registry/extension-registry.md b/15/umbraco-cms/customizing/extending-overview/extension-registry/extension-registry.md
index 943e68c414b..95d32da9eb0 100644
--- a/15/umbraco-cms/customizing/extending-overview/extension-registry/extension-registry.md
+++ b/15/umbraco-cms/customizing/extending-overview/extension-registry/extension-registry.md
@@ -4,26 +4,15 @@
This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
{% endhint %}
-The extension registry is the center piece of the Backoffice UI.
-It holds information about most of the Backoffice UI, as most are extensions. This includes the built-in UI.
-The registry can be manipulated at any time, meaning you can add or remove extensions at runtime.
+The extension registry is the center piece of the Backoffice UI. It holds information about most of the Backoffice UI, as most are extensions. This includes the built-in UI. The registry can be manipulated at any time, meaning you can add or remove extensions at runtime.
To provide new UI to the backoffice, you must register them via an extension manifest. This has to be initiated via an Umbraco Package JSON file on the server. This will be your starting point, which enables you to register one or more extensions.
-Declaring a new extension is done by declaring an [extension manifest](./extension-manifest.md). This can be done in one of two ways:
+Declaring a new extension is done by declaring an [extension manifest](extension-manifest.md). This can be done in one of two ways:
1. Via a manifest JSON file on the server.
2. In a JavaScript/TypeScript file.
These two options can be combined as you like.
-A typical use case of such is achieved by registering a single extension manifest in your Umbraco Package JSON file. This manifest would then load a JS file, that registers the rest of your extensions.
-Learn more about these abilities in the [bundle](../extension-types/bundle.md) or [backoffice entry point](../extension-types/entry-point.md) articles.
-
-## Extension Manifest Data
-
-The necessary properties that any extension manifest needs are:
-
-* `type` - The type defines the type and purpose of the extension. It is used to determine where the extension will be used and defines the data needed for this manifest.
-* `alias`- The alias is used to identify the extension. This has to be unique for each extension.
-* `name` - The name of the extension. This is used to identify the extension in the UI.
+A typical use case of such is achieved by registering a single extension manifest in your Umbraco Package JSON file. This manifest would then load a JS file, that registers the rest of your extensions. Learn more about these abilities in the [bundle](../extension-types/bundle.md) or [backoffice entry point](../extension-types/backoffice-entry-point.md) articles.
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/backoffice-entry-point.md b/15/umbraco-cms/customizing/extending-overview/extension-types/backoffice-entry-point.md
index 0ff7faa9215..d4ca3c733f7 100644
--- a/15/umbraco-cms/customizing/extending-overview/extension-types/backoffice-entry-point.md
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/backoffice-entry-point.md
@@ -1,4 +1,4 @@
-# Backoffice Entry Point
+# Entry Point
{% hint style="warning" %}
This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
@@ -15,14 +15,14 @@ The Entry Point manifest type is used to register an entry point for the backoff
```json
{
- "name": "Name of your package",
- "extensions: [
- {
- "type": "backofficeEntryPoint",
- "alias": "My.EntryPoint",
- "js": "/App_Plugins/YourFolder/index.js"
- }
- ]
+ "name": "Name of your package",
+ "extensions: [
+ {
+ "type": "backofficeEntryPoint",
+ "alias": "My.EntryPoint",
+ "js": "/App_Plugins/YourFolder/index.js"
+ }
+ ]
}
```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/condition.md b/15/umbraco-cms/customizing/extending-overview/extension-types/condition.md
index a2147a5ea93..3b6094524d0 100644
--- a/15/umbraco-cms/customizing/extending-overview/extension-types/condition.md
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/condition.md
@@ -1,49 +1,37 @@
-# Extension Conditions
-
-Extension conditions are used to determine if an extension should be used or not. Many of the Extension Types support conditions, but not all of them.
-
-{% hint style="warning" %}
-This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
-{% endhint %}
-
-All given conditions for an extension must be valid for an extension to be utilized.
+---
+description: Learn how to declare requirements for your extensions using the Extension Conditions.
+---
-## Using conditions
-
-In the following example we define the manifest for a Workspace Action, this action will only be available in the workspace with the alias `My.Example.Workspace`.
-
-```typescript
-{
- type: 'workspaceAction',
- name: 'example-workspace-action',
- alias: 'My.Example.WorkspaceAction',
- elementName: 'my-workspace-action-element',
- conditions: [
- {
- alias: 'Umb.Condition.SectionAlias',
- match: 'My.Example.Workspace'
- }
- ]
-}
-```
-
-The conditions are defined as an array of conditions. Each condition is an object with the following properties:
+# Extension Conditions
-* `alias`- The alias of the condition to utilize.
-* `...` - The rest of the properties of the object are specific to the condition.
+Extension Conditions declare requirements that should be permitted for the extension to be available. Many, but not all, Extension Types support Conditions.
-In the above example the `Umb.Condition.SectionAlias` condition is used, this condition takes a property `match` which must be set to the alias of the section to match.
+[Read about utilizing conditions in Manifests](../extension-conditions/extension-conditions.md).
## Built-in conditions types
-The following conditions are available out of the box, for all extension types that support conditions.
-
-* `Umb.Condition.SectionAlias` - Checks if the current section alias matches the one specified.
-* `Umb.Condition.WorkspaceAlias` - Checks if the current workspace alias matches the one specified.
-
-## Make your own conditions
+The following conditions are available out of the box, for all extension types that support Conditions.
+
+* `Umb.Condition.SectionAlias` - Requires the current Section Alias to match the one specified.
+* `Umb.Condition.MenuAlias` - Requires the current Menu Alias to match the one specified.
+* `Umb.Condition.WorkspaceAlias` - Requires the current Workspace Alias to match the one specified.
+* `Umb.Condition.WorkspaceEntityType` - Requires the current workspace to work on the given Entity Type. Examples: 'document', 'block' or 'user'.
+* `Umb.Condition.WorkspaceContentTypeAlias` - Requires the current workspace to be based on a Content Type which Alias matches the one specified.
+* `Umb.Condition.Workspace.ContentHasProperties` - Requires the Content Type of the current Workspace to have properties.
+* `Umb.Condition.WorkspaceHasCollection` - Requires the current Workspace to have a Collection.
+* `Umb.Condition.WorkspaceEntityIsNew` - Requires the current Workspace data to be new, not yet persisted on the server.
+* `Umb.Condition.EntityIsTrashed` - Requires the current entity to be trashed.
+* `Umb.Condition.EntityIsNotTrashed` - Requires the current entity to not be trashed.
+* `Umb.Condition.SectionUserPermission` - Requires the current user to have permissions to the given Section Alias.
+* `Umb.Condition.UserPermission.Document` - Requires the current user to have specific Document permissions. Example: 'Umb.Document.Save'
+
+## Make your own conditions
+
+```html
+
+```
-You can make your own conditions by creating a class that implements the `UmbExtensionCondition` interface.
+You can make your own Conditions by creating a class that implements the `UmbExtensionCondition` interface.
```typescript
import {
@@ -55,12 +43,12 @@ import {
import { UmbConditionBase } from '@umbraco-cms/backoffice/extension-registry';
import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
-export type MyConditionConfig = UmbConditionConfigBase & {
+export type MyExtensionConditionConfig = UmbConditionConfigBase & {
match: string;
};
-export class MyExtensionCondition extends UmbConditionBase implements UmbExtensionCondition {
- constructor(host: UmbControllerHost, args: UmbConditionControllerArguments) {
+export class MyExtensionCondition extends UmbConditionBase implements UmbExtensionCondition {
+ constructor(host: UmbControllerHost, args: UmbConditionControllerArguments) {
super(host, args);
// enable extension after 10 seconds
@@ -70,9 +58,16 @@ export class MyExtensionCondition extends UmbConditionBase im
}, 10000);
}
}
+
+// Declare the Condition Configuration Type in the global UmbExtensionConditionConfigMap interface:
+declare global {
+ interface UmbExtensionConditionConfigMap {
+ MyExtensionConditionConfig: MyExtensionCondition;
+ }
+}
```
-This has to be registered in the extension registry like shown below:
+This has to be registered in the extension registry, shown below:
```typescript
export const manifest: ManifestCondition = {
@@ -108,8 +103,8 @@ As can be seen in the code above, we never make use of `match`. We can do this b
```typescript
// ...
-export class MyExtensionCondition extends UmbConditionBase implements UmbExtensionCondition {
- constructor(host: UmbControllerHost, args: UmbConditionControllerArguments) {
+export class MyExtensionCondition extends UmbConditionBase implements UmbExtensionCondition {
+ constructor(host: UmbControllerHost, args: UmbConditionControllerArguments) {
super(host, args);
if (args.config.match === 'Yes') {
@@ -132,7 +127,7 @@ With all that in place, the configuration can look like shown below:
{
alias: 'My.Condition.CustomName',
match: 'Yes'
- } as MyConditionConfig
+ }
]
}
```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/dashboard.md b/15/umbraco-cms/customizing/extending-overview/extension-types/dashboard.md
new file mode 100644
index 00000000000..671b42c49d5
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/dashboard.md
@@ -0,0 +1,138 @@
+---
+description: A guide to creating custom dashboards in Umbraco
+---
+
+# Dashboards
+
+Each section of the Umbraco backoffice has its own set of default dashboards. Your own custom sections can show dashboards, and you can create your own custom dashboards for existing sections.
+
+
The Getting Started dashboard in Umbraco
+
+The dashboard area of Umbraco is used to display an "editor" for the selected item in the tree. If no item is selected, then the default set of section dashboards is shown in the dashboard area.
+
+Notice that [Section Views](section-view.md) is another similar approach to append information to the root of a Section. Section views are thought mainly to be used as Secondary pages. These two approaches should ideally not be combined.
+
+## Default Dashboards in Umbraco
+
+The default dashboards in Umbraco are the ones that are displayed when you first enter a section in the backoffice. These dashboards are used to display information and functionality that is relevant to the section you are in.
+
+The default sections in Umbraco are:
+
+| Alias | Name |
+| ----------------------- | ---------- |
+| Umb.Section.Content | Content |
+| Umb.Section.Media | Media |
+| Umb.Section.Settings | Settings |
+| Umb.Section.Members | Members |
+| Umb.Section.Users | Users |
+| Umb.Section.Translation | Dictionary |
+
+Here is a table of the default dashboards in Umbraco and the sections they are used including their aliases:
+
+| Alias | Section | Weight | Description |
+| -------------------------------- | -------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
+| Umb.Dashboard.UmbracoNews | Umb.Section.Content | 20 | The Getting Started dashboard users see when they first enter Umbraco. Contains the latest news of Umbraco including outbound links to resources |
+| Umb.Dashboard.RedirectManagement | Umb.Section.Content | 10 | Contains a list of active URL redirects |
+| Umb.Dashboard.SettingsWelcome | Umb.Section.Settings | 500 | Contains a set of boxes with links to appropriate resources |
+
+Even though these dashboards are useful, you might want to create your own custom dashboard to display specific information or functionality.
+
+You can try and [create a custom dashboard](../../../../tutorials/creating-a-custom-dashboard/) as a way on getting started on this topic.
+
+## Registering your Dashboard
+
+This section dives into the Dashboard Extension Manifest, shows how to register one, and append additional details.
+
+### Example Extension Manifest
+
+{% hint style="info" %}
+You can read more about manifests in the tutorial [Creating Your First Extension](../../../tutorials/creating-your-first-extension.md).
+{% endhint %}
+
+Insert this as an entry in the `extensions` list in a `umbraco-package.json` file.
+
+{% code title="~/App_Plugins/WelcomeDashboard/umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "type": "dashboard",
+ "alias": "my.welcome.dashboard",
+ "name": "My Welcome Dashboard",
+ "element": "/App_Plugins/WelcomeDashboard/dashboard.js",
+ "weight": -1,
+ "meta": {
+ "label": "Welcome Dashboard",
+ "pathname": "welcome-dashboard"
+ }
+}
+```
+{% endcode %}
+
+This will register a dashboard with the alias `my.welcome.dashboard` and the name `My Welcome Dashboard`. The dashboard will be loaded from the file `/App_Plugins/WelcomeDashboard/dashboard.js`. The dashboard will be displayed with the label `Welcome Dashboard` and the URL `/welcome-dashboard` on _all sections_, e.g. `/section/content/dashboard/welcome-dashboard`.
+
+### Conditions
+
+You can specify conditions for when the dashboard should be displayed. This is done by adding a `conditions` property to the manifest. Ideally, we would like the dashboard to be shown only in a specific section. This can be done by specifying the condition called `Umb.Condition.SectionAlias` and providing the [alias of the section](dashboard.md#default-dashboards-in-umbraco) you want the dashboard to be displayed on:
+
+```json
+"conditions": [
+ {
+ "alias": "Umb.Condition.SectionAlias",
+ "match": "Umb.Section.Content"
+ }
+]
+```
+
+This will make the dashboard only be displayed on the Content section.
+
+{% hint style="info" %}
+You can read more about [Extension Conditions](../../../customizing/extending-overview/extension-types/condition.md) in the documentation.
+{% endhint %}
+
+### Properties
+
+The dashboard manifest can contain the following properties:
+
+| Property | Type | Description |
+| ----------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| type | string | The type of extension, should be `dashboard` |
+| alias | string | A unique alias for the dashboard extension |
+| name | string | The name of the dashboard extension |
+| element | string | The path to the JavaScript file that exports the dashboard |
+| elementName | string | (Optional) The name of the Web Component that contains the dashboard (only if not a default export) |
+| weight | number | (Optional) The weight of the dashboard, higher numbers are displayed first |
+| meta | object |
Additional metadata for the dashboard
Property
Type
Description
Label
string
The label shown to the user
pathname
string
The routable URL pathname
|
+| Property | Type | Description |
+| Label | string | The label shown to the user |
+| pathname | string | The routable URL pathname |
+| Property | Type | Description |
+| Label | string | The label shown to the user |
+| pathname | string | The routable URL pathname |
+| conditions | array | (Optional) [Conditions](../../../customizing/extending-overview/extension-types/condition.md) for when the dashboard should be displayed |
+
+### Full Example
+
+{% code title="~/App_Plugins/WelcomeDashboard/umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "type": "dashboard",
+ "alias": "my.welcome.dashboard",
+ "name": "My Welcome Dashboard",
+ "element": "/App_Plugins/WelcomeDashboard/dashboard.js",
+ "weight": -1,
+ "meta": {
+ "label": "Welcome Dashboard",
+ "pathname": "welcome-dashboard"
+ },
+ "conditions": [
+ {
+ "alias": "Umb.Condition.SectionAlias",
+ "match": "Umb.Section.Content"
+ }
+ ]
+}
+```
+{% endcode %}
+
+
The Welcome Dashboard appears in the Content section
+
+You can learn about [creating a custom dashboard](../../../tutorials/creating-a-custom-dashboard/) in the tutorials section. Here you will learn how to build the dashboard itself as a Web Component.
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/entity-actions.md b/15/umbraco-cms/customizing/extending-overview/extension-types/entity-actions.md
new file mode 100644
index 00000000000..b91de56a43c
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/entity-actions.md
@@ -0,0 +1,216 @@
+---
+description: Entity Actions perform an action on a specific item
+---
+
+# Entity Actions
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+{% hint style="info" %}
+Entity Actions was previously called Tree Actions.
+{% endhint %}
+
+Entity Actions is a feature that provides a generic place for secondary or additional functionality for an entity type. An entity type can be a media, document and so on.
+
+Items in an Umbraco Tree can have associated Actions. The actions visible to the currently logged in user can be controlled via User Permissions.
+
+You can set a User's permissions for each item in the Umbraco Content tree from the User Section of the Umbraco Backoffice.
+
+If you are developing a custom section or a custom Dashboard, you might want to display some different options. This depends on a User's permission set on a particular item.
+
+## Entity Actions in the UI
+
+
+
+
Sidebar Context Menu
+
+
+
+
Workspace Entity Action Menu
+
+
+
+
+
+
Collection
+
+
+
+
Pickers
+
+
+
+### Sidebar Context Menu
+
+Sidebar Context Menu is an entity action that can be performed on a menu item. For example in the content section you can perform some extra actions on the content such as sorting, moving, etc.
+
+
Default Entity Action in the Content Section
+
+## Registering an Entity Action
+
+```typescript
+import { extensionRegistry } from '@umbraco-cms/extension-registry';
+import { MyEntityAction } from './entity-action';
+
+const manifest = {
+ type: 'entityAction',
+ alias: 'My.EntityAction',
+ name: 'My Entity Action',
+ weight: 10,
+ api: MyEntityAction,
+ forEntityTypes: ['my-entity'],
+ meta: {
+ icon: 'icon-add',
+ label: 'My Entity Action',
+ repositoryAlias: 'My.Repository',
+ },
+};
+
+extensionRegistry.register(manifest);
+```
+
+**Default Element**
+
+```typescript
+interface UmbEntityActionElement {}
+```
+
+### The Entity Action Class
+
+As part of the Extension Manifest you can attach a class that will be instanciated as part of the action. It will have access to the host element, a repository with the given alias and the unique (key etc) of the entity.
+
+The class either provides a getHref method, or an execute method. If the getHref method is provided, the action will use the link. Otherwise the `execute` method will be used. When the action is clicked the `execute` method on the api class will be run. When the action is completed, an event on the host element will be dispatched to notify any surrounding elements.
+
+Example of providing a `getHref` method:
+
+```typescript
+import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
+import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
+import type { MyRepository } from './my-repository';
+
+export class MyEntityAction extends UmbEntityActionBase {
+ constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) {
+ super(host, repositoryAlias, unique);
+ }
+
+ async getHref() {
+ return 'my-link/path-to-something';
+ }
+}
+```
+
+Example of providing a `execute` method:
+
+```typescript
+import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
+import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
+import type { MyRepository } from './my-repository';
+
+export class MyEntityAction extends UmbEntityActionBase {
+ constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) {
+ super(host, repositoryAlias, unique);
+ }
+
+ async execute() {
+ await this.repository.myAction(this.unique);
+ }
+}
+```
+
+If any additional contexts are needed, these can be consumed from the host element:
+
+```typescript
+import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action';
+import { UmbContextConsumerController } from '@umbraco-cms/controller';
+import { UMB_MODAL_SERVICE_CONTEXT } from '@umbraco-cms/modal';
+import { MyRepository } from './my-repository';
+
+export class MyEntityAction extends UmbEntityActionBase {
+ constructor(host: UmbControllerHostElement, repositoryAlias: string, unique: string) {
+ super(host, repositoryAlias, unique);
+
+ new UmbContextConsumerController(this.host, UMB_MODAL_SERVICE_CONTEXT, (instance) => {
+ this.#modalService = instance;
+ });
+ }
+ ...
+}
+```
+
+We currently have a couple of generic actions that can be used across silos, so we don't have to write the same logic again. These actions include copy, move, trash, delete, etc. We can add more as we discover the needs.
+
+## User Permission Codes
+
+Here is a list of the entity actions and associated user permission codes shipped by Umbraco CMS and add-on projects, such as Umbraco Deploy. This list also includes codes used by some community packages.
+
+If you are building a package or adding custom entity actions to your solution, it's important to pick a permission letter. Ensure that it doesn't clash with one of these.
+
+If you have created a package using a custom entity action, please consider providing an update to this documentation page. You can do this via a PR to the [documentation repository](https://github.com/umbraco/UmbracoDocs). This will allow other developers to discover and avoid using the same permission letter.
+
+Currently, we allow two extension points on the client for user permissions:
+
+* **Entity User Permissions** - Relates to an entity (example document).
+
+
Entity User Permissions UI
+
+* **Granular User Permission** - Relates to a $type server schemaType.
+
+
Granular User Permission UI
+
+Each permission comes with a set of verbs, that will be checked against client and server-side.
+
+The Core currently ships with entity user permission for documents. The permissions are as follows:
+
+| Current Backoffice Letter | Verb |
+| ------------------------- | -------------------------------- |
+| C | Umb.Document.Create |
+| F | Umb.Document.Read |
+| A | Umb.Document.Update |
+| D | Umb.Document.Delete |
+| I | Umb.Document.CreateBlueprint |
+| N | Umb.Document.Notifications |
+| U | Umb.Document.Publish |
+| R | Umb.Document.Permissions |
+| Z | Umb.Document.Unpublish |
+| O | Umb.Document.Duplicate |
+| M | Umb.Document.Move |
+| S | Umb.Document.Sort |
+| I | Umb.Document.CultureAndHostnames |
+| P | Umb.Document.PublicAccess |
+| K | Umb.Document.Rollback |
+| V | Umb.DocumentRecycleBin.Restore |
+
+**Entity User Permissions** will be registered in the extension registry with a manifest with the following type. Example:
+
+```typescript
+{
+ "type": "entityUserPermission",
+ "alias": "Umb.UserPermission.Document.Rollback",
+ "name": "Document Rollback User Permission",
+ "meta": {
+ "entityType": "document",
+ "verbs": ["Umb.Document.Rollback"],
+ "labelKey": "actions_rollback",
+ "descriptionKey": "actionDescriptions_rollback",
+ "group": "administration",
+ },
+ },
+```
+
+**Granular permissions** will also be registered. It is possible to provide a custom element to build the needed UX for that type of permission:
+
+```typescript
+{
+ "type": "userGranularPermission",
+ "alias": "Umb.UserGranularPermission.Document",
+ "name": "Document Granular User Permission",
+ "element": "element.js",
+ "meta": {
+ "schemaType": "DocumentPermissionPresentationModel",
+ "label": "Documents",
+ "description": "Assign permissions to specific documents",
+ },
+ },
+```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/entity-bulk-actions.md b/15/umbraco-cms/customizing/extending-overview/extension-types/entity-bulk-actions.md
new file mode 100644
index 00000000000..797b5aebc15
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/entity-bulk-actions.md
@@ -0,0 +1,57 @@
+# Entity Bulk Actions
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+**Entity Bulk Action:** Relates to an entity type: document, media, etc. Performs the action on a selection of items.
+
+
Entity Bulk Collection
+
+## Registering an Entity Bulk Action
+
+```typescript
+import { extensionRegistry } from '@umbraco-cms/extension-registry';
+import { MyEntityBulkAction } from './entity-bulk-action';
+
+const manifest = {
+ type: 'entityBulkAction',
+ alias: 'My.EntityBulkAction',
+ name: 'My Entity Bulk Action',
+ weight: 10,
+ api: MyEntityBulkAction,
+ meta: {
+ icon: 'icon-add',
+ label: 'My Entity Bulk Action',
+ repositoryAlias: 'My.Repository',
+ },
+ conditions: [
+ {
+ alias: 'Umb.Condition.CollectionAlias',
+ match: 'my-collection-alias',
+ },
+ ],
+};
+
+extensionRegistry.register(manifest);
+```
+
+## The Entity Bulk Action Class
+
+As part of the Extension Manifest you can attach a class that will be instantiated as part of the action. It will have access to the host element, a repository with the given alias and the unique (key etc) of the entity. When the action is clicked the `execute` method on the api class will be run. When the action is completed, an event on the host element will be dispatched to notify any surrounding elements.
+
+```typescript
+import { UmbEntityBulkActionBase } from '@umbraco-cms/entity-action';
+import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
+import { MyRepository } from './my-repository';
+
+export class MyEntityBulkAction extends UmbEntityBulkActionBase {
+ constructor(host: UmbControllerHostElement, repositoryAlias: string, selection: Array) {
+ super(host, repositoryAlias, selection);
+ }
+
+ async execute() {
+ await this.repository?.myBulkAction(this.selection);
+ }
+}
+```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/global-context.md b/15/umbraco-cms/customizing/extending-overview/extension-types/global-context.md
new file mode 100644
index 00000000000..744314d195c
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/global-context.md
@@ -0,0 +1,24 @@
+---
+description: Establish the bond for extensions to communication across the application
+---
+
+# Global Context
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A global context manages the logic code from your Lit Element controllers.
+
+## Registration of a Global Context
+
+You can register a global context like so:
+
+```typescript
+{
+ type: 'globalContext',
+ alias: 'My.GlobalContext.Products',
+ name: 'My Products Context',
+ api: 'my-products.context.js',
+}
+```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/localization.md b/15/umbraco-cms/customizing/extending-overview/extension-types/localization.md
new file mode 100644
index 00000000000..a56a00f9a97
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/localization.md
@@ -0,0 +1,77 @@
+---
+description: Learn how to manage and use the Backoffice UI Localization files.
+---
+
+# Localization
+
+## Registering Localization
+
+When registering localizations to a language, you must add a new manifest to the Extension API. The manifest can be added through the `umbraco-package.json` file. Usually, the localization keys are provided through a JavaScript module. In this example, we will use a file named `en.js`:
+
+{% code title="umbraco-package.json" %}
+```json
+{
+ "name": "MyPackage",
+ "extensions": [
+ {
+ "type": "localization",
+ "alias": "MyPackage.Localize.EnUS",
+ "name": "English",
+ "meta": {
+ "culture": "en"
+ },
+ "js": "/App_Plugins/MyPackage/Localization/en.js"
+ }
+ ]
+}
+```
+{% endcode %}
+
+{% hint style="info" %}
+Read more about extensions in the [Package Manifest](../../umbraco-package.md) article.
+{% endhint %}
+
+## The Localization file
+
+The localization files for the UI are JavaScript modules with a default export containing a key-value structure organized in sections.
+
+{% code title="en.js" %}
+```javascript
+export default {
+ section: {
+ key1: 'value1',
+ key2: 'value2',
+ },
+};
+```
+{% endcode %}
+
+The sections and keys will be formatted into a map in Umbraco with the format `section_key1` and `section_key2.` These form the unique key they are requested.
+
+If you do not have many translations, you can also choose to include them directly in the meta-object:
+
+{% code title="umbraco-package.json" %}
+```json
+{
+ "name": "MyPackage",
+ "extensions": [
+ {
+ "type": "localization",
+ "alias": "MyPackage.Localize.EnUS",
+ "name": "English",
+ "meta": {
+ "culture": "en",
+ "translations": {
+ "section": {
+ "key1": "value1",
+ "key2": "value2"
+ }
+ }
+ },
+ }
+ ]
+}
+```
+{% endcode %}
+
+In this case, the `en.js` file is not required and we can remove the "js" property from the manifest. Only strings can be used in the meta-object.
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/section-sidebar.md b/15/umbraco-cms/customizing/extending-overview/extension-types/section-sidebar.md
new file mode 100644
index 00000000000..ca9355ce648
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/section-sidebar.md
@@ -0,0 +1,69 @@
+# Section Sidebar
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+
Section Sidebar
+
+## Section Sidebar Apps
+
+
Section Sidebar Apps
+
+**Manifest**
+
+```typescript
+{
+ "type": "sectionSidebarApp",
+ "alias": "My.SectionSidebarApp",
+ "name": "My Section Sidebar App",
+ "meta": {
+ "sections": ["My.Section"]
+ }
+}
+```
+
+**Default Element**
+
+```typescript
+interface UmbSectionSidebarAppElement {}
+```
+
+## **Menu Sidebar App**
+
+**Sidebar Menu**:
+
+* The Backoffice comes with a menu sidebar app that can be used to create a menu in the sidebar.
+* To register a new menu sidebar app, add the following to your manifest
+* The menu sidebar app will reference a menu that you have registered in the menu with a menu manifest
+
+
Menu Sidebar App
+
+**Manifest**
+
+```typescript
+{
+ "type": "menuSectionSidebarApp",
+ "alias": "My.SectionSidebarApp.MyMenu",
+ "name": "My Menu Section Sidebar App",
+ "meta": {
+ "label": "My Sidebar Menu",
+ "sections": ["My.Section"],
+ "menu": "My.Menu"
+ }
+}
+```
+
+**Default Element**
+
+```typescript
+interface UmbMenuSectionSidebarAppElement {}
+```
+
+**Adding Items to an existing menu**
+
+This will make it possible to compose a sidebar menu from multiple Apps:
+
+
Composed sidebar menu
+
+You can read more about this in the [Menu](../../../extending/section-trees/menu/) article.
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/section-view.md b/15/umbraco-cms/customizing/extending-overview/extension-types/section-view.md
new file mode 100644
index 00000000000..d8f37c9a624
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/section-view.md
@@ -0,0 +1,28 @@
+---
+description: >-
+ Append a secondary view for a Section, use it for additional features or
+ information.
+---
+
+# Section View
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+
Section View
+
+**Manifest**
+
+```json
+{
+ "type": "sectionView",
+ "alias": "My.SectionView",
+ "name": "My Section View",
+ "meta": {
+ "sections": ["My.Section"],
+ "label": "My View",
+ "pathname": "/my-view"
+ }
+}
+```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/section.md b/15/umbraco-cms/customizing/extending-overview/extension-types/section.md
new file mode 100644
index 00000000000..49f769dcea4
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/section.md
@@ -0,0 +1,76 @@
+---
+description: A guide to creating a section
+---
+
+# Sections
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Umbraco backoffice consists of Sections. Section is the main division shown in the top navigation.
+
+For example, when you load the backoffice, you'll see the 'Content' section, 'Settings' section, and so on.
+
+You can create your own sections to extend Umbraco with room for more features.
+
+
Section
+
+## **Creating a section**
+
+### **Manifests**
+
+When creating a new section it's recommended to use a [Entry Point](../../../customizing/extending-overview/extension-types/backoffice-entry-point.md)-extension in your [Umbraco Package Manifest](../../umbraco-package.md). This is to get better control over all the additional extensions required for the new section.
+
+Create a section by defining a manifest for it:
+
+```typescript
+{
+ "type": "section",
+ "alias": "My.Section",
+ "name": "My Section",
+ "meta": {
+ "label": "My.Section",
+ "pathname": "my-section"
+ }
+}
+```
+
+Once registered, you will be able to select this action for your User Group Permissions. Once that is permitted, you can view your section.
+
+
Section
+
+#### **Extend with Sidebar, Dashboards and more**
+
+Once a section is registered, it can be extended like any other section.
+
+Here is a list of appropriate extensions to append to your section:
+
+* [Creating a Custom Dashboard](../../../tutorials/creating-a-custom-dashboard/)
+* [Section Sidebar](section-sidebar.md)
+* [Section View](section-view.md)
+
+#### **Manifest with empty element**
+
+If you prefer full control over the content of your section you can choose to define an element for the content of your section.
+
+{% hint style="warning" %}
+This is not recommended as it limits the content of your section to this element. Instead, it is recommended to use a single Dashboard or Section View.
+{% endhint %}
+
+If you like to have full control, you can define an element like this:
+
+```typescript
+const section : ManifestSection = {
+ type: "section",
+ alias: "Empty.Section",
+ name : 'Empty Section',
+ element : () => import('./empty-section.element.js'),
+ meta : {
+ label : 'Empty Section',
+ pathname : 'empty-section'
+ }
+}
+```
+
+The element file must have an `element` or `default` export, or specify the element name in the `elementName` field.
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/tree.md b/15/umbraco-cms/customizing/extending-overview/extension-types/tree.md
new file mode 100644
index 00000000000..705fe19ac59
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/tree.md
@@ -0,0 +1,141 @@
+---
+description: A guide to creating a custom tree in Umbraco
+---
+
+# Trees
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The tree is a hierarchical structure of nodes and is registered in the Backoffice extension registry. A tree can be rendered anywhere in the Backoffice with the help of the umb-tree element.
+
+## Creating trees
+
+To Create a Tree in a section of the Umbraco backoffice, you need to take multiple steps:
+
+### Registering a tree
+
+The backoffice comes with two different tree item kinds out of the box: entity and fileSystem.
+
+Tree Manifest:
+
+```typescript
+// TODO: add interface
+{
+ "type": "tree",
+ "alias": "My.Tree.Alias",
+ "name": "My Tree",
+ "meta": {
+ "repositoryAlias": "My.Repository.Alias"
+ }
+},
+{
+ "type": "treeItem",
+ "kind": "entity",
+ "alias": "My.TreeItem.Alias",
+ "name": "My Tree Item",
+ "conditions": {
+ "entityType": "my-entity-type",
+ },
+}
+```
+
+### Rendering a tree
+
+```typescript
+
+```
+
+### Render a Custom Tree Item
+
+#### **The Tree Item Manifest**
+
+```typescript
+{
+ "type": "treeItem",
+ "alias": "Umb.TreeItem.Alias",
+ "name": "My Tree Item",
+ "element": "./my-tree-item.element.js",
+ "conditions": {
+ "entityType": "my-entity-type",
+ },
+};
+```
+
+#### The Tree Item Element
+
+```typescript
+import { css, html, nothing } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
+import { UmbMyTreeItemContext, MyTreeItemDataModel } from './my-tree-item.context';
+
+@customElement('my-tree-item')
+export class MyTreeItemElement extends UmbElementMixin(LitElement) {
+ private _item?: MyTreeItemDataModel;
+ @property({ type: Object, attribute: false })
+ public get item() {
+ return this._item;
+ }
+ public set item(value: MyTreeItemDataModel | undefined) {
+ this._item = value;
+ this.#context.setTreeItem(value);
+ }
+
+ #context = new UmbMyTreeItemContext(this);
+
+ render() {
+ if (!this.item) return nothing;
+ return html` Some custom markup `;
+ }
+}
+
+export default MyTreeItemElement;
+```
+
+#### The Tree Item Context
+
+```typescript
+// TODO: auto-generate this from the interface
+export interface UmbTreeItemContext {
+ host: UmbControllerHostElement;
+ unique?: string;
+ type?: string;
+
+ treeItem: Observable;
+ hasChildren: Observable;
+ isLoading: Observable;
+ isSelectable: Observable;
+ isSelected: Observable;
+ isActive: Observable;
+ hasActions: Observable;
+ path: Observable;
+
+ setTreeItem(treeItem: T | undefined): void;
+
+ requestChildren(): Promise<{
+ data: PagedResponse | undefined;
+ error: ProblemDetails | undefined;
+ asObservable?: () => Observable;
+ }>;
+ toggleContextMenu(): void;
+ select(): void;
+ deselect(): void;
+ constructPath(pathname: string, entityType: string, unique: string): string;
+}
+```
+
+#### Extending the Tree Item Context base
+
+We provide a base class for the tree item context. This class provides some default implementations for the context. You can extend this class to overwrite any of the default implementations.
+
+```typescript
+export class UmbMyTreeItemContext extends UmbTreeItemContextBase {
+ constructor(host: UmbControllerHostElement) {
+ super(host, (x: MyTreeItemDataModel) => x.unique);
+ }
+
+ // overwrite any methods or properties here if needed
+}
+```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/workspace-context.md b/15/umbraco-cms/customizing/extending-overview/extension-types/workspace-context.md
new file mode 100644
index 00000000000..26694f7491d
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/workspace-context.md
@@ -0,0 +1,83 @@
+---
+description: Establish an extension to communicate across the application.
+---
+
+# Workspace Context
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A Workspace context is a container for the data of a workspace. It is a wrapper around the data of the entity that the workspace is working on. It is responsible for loading and saving the data to the server. Workspace Contexts are used to bring additional context alongside the default context of a workspace.
+
+* A workspace context knows about its entity type (for example content, media, member, etc.) and holds its unique string (for example: key).
+* Most workspace contexts hold a draft state of its entity data. It is a copy of the entity data that can be modified at runtime and sent to the server to be saved.
+
+If a workspace wants to utilize Property Editor UIs, then it must provide a variant context for the property editors. The variant-context is the generic interface between workspace and property editors.
+
+```ts
+interface UmbWorkspaceContext {}
+```
+
+## Example of Workspace
+
+## Example of Workspace Context
+
+The API will be initiated with the same host as the default Workspace Context.
+
+```typescript
+{
+ type: 'workspaceContext',
+ alias: 'My.WorkspaceContext.Counter',
+ name: 'My Counter Context',
+ api: 'my-workspace-counter.context.js',
+ conditions: [
+ {
+ alias: 'Umb.Condition.WorkspaceAlias',
+ match: 'Umb.Workspace.Document',
+ }
+ ]
+}
+```
+
+The code of such an API file could look like this:
+
+```typescript
+import {
+ UmbController,
+ UmbControllerHost,
+} from "@umbraco-cms/backoffice/controller-api";
+import { UmbContextToken } from "@umbraco-cms/backoffice/context-api";
+import { UmbNumberState } from "@umbraco-cms/backoffice/observable-api";
+
+export class MyContextApi extends UmbController {
+ #counter = new UmbNumberState(0);
+ readonly counter = this.#counter.asObservable();
+
+ constructor(host: UmbControllerHost) {
+ super(host);
+ this.provideContext(UMB_APP_CONTEXT, this);
+ }
+
+ increment() {
+ this.#counter.next(this.#counter.value + 1);
+ }
+}
+
+export const api = MyContextCounterApi;
+```
+
+{% hint style="info" %}
+Context APIs have to be self-providing. To do so it has to be an Umbraco Controller.
+{% endhint %}
+
+A Context Token for a Workspace Context Extension should look like this:
+
+```typescript
+export const UMB_APP_CONTEXT = new UmbContextToken(
+ "UmbWorkspaceContext",
+ "My.WorkspaceContext.Counter"
+);
+```
+
+We recommend using `UmbWorkspaceContext` as the Context Alias for your Context Token. This will ensure that the requester only retrieves this Context if it's present at their nearest Workspace Context. Use the Extension Manifest Alias as the API Alias for your Context Token. For more information, see the [Context API](../../../customizing/foundation/working-with-data/context-api.md) article.
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/workspace-editor-actions.md b/15/umbraco-cms/customizing/extending-overview/extension-types/workspace-editor-actions.md
new file mode 100644
index 00000000000..76f77eb08ad
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/workspace-editor-actions.md
@@ -0,0 +1,55 @@
+# Workspace Actions
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Workspace actions are a set of functionalities or operations that can be performed within a workspace. These actions involve creating documents within the workspace, organizing and categorizing documents, publishing content and so on.
+
+Workspace action relates to a workspace alias (Umb.Workspace.Document) and has Access to the workspace context.
+
+
+
+## The Workspace Action Class
+
+As part of the Extension Manifest you can attach a class that will be instantiated as part of the action. It will have access to the host element and the Workspace Context. When the action is clicked the `execute` method on the API class will be run. When the action is completed, an event on the host element will be dispatched to notify any surrounding elements.
+
+```ts
+import { UmbWorkspaceActionBase } from '@umbraco-cms/backoffice/workspace';
+
+export class MyWorkspaceAction extends UmbWorkspaceActionBase {
+ execute() {
+ this.workspaceContext.myAction(this.selection);
+ }
+}
+```
+
+**Default Element**
+
+```typescript
+interface UmbWorkspaceActionElement {}
+```
diff --git a/15/umbraco-cms/customizing/extending-overview/extension-types/workspace-views.md b/15/umbraco-cms/customizing/extending-overview/extension-types/workspace-views.md
new file mode 100644
index 00000000000..6c83bcedff3
--- /dev/null
+++ b/15/umbraco-cms/customizing/extending-overview/extension-types/workspace-views.md
@@ -0,0 +1,100 @@
+---
+description: Append a view to any Workspace
+---
+
+# Workspace Views
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+{% hint style="info" %}
+Workspace Views was previously called Content Apps.
+{% endhint %}
+
+Workspace Views are customizable companion **tabs** with the ability to take place in any workspace.
+
+
Workspace Views
+
+**In Content Section**
+
+With Workspace Views, editors can switch from editing 'Content' to accessing contextual information related to the item they are editing.
+
+The default workspace view is **'Info'** - displaying Links, History and Status of the current content item.
+
+## Example of a Workspace View
+
+1. Follow the [Vite Package Setup](../../../customizing/development-flow/vite-package-setup.md) by creating a new project folder called "`workspaceview`" in `App_Plugins`.
+2. Create a manifest file named `umbraco-package.json` at the root of the `welcome-dashboard` folder. Here we define and configure our dashboard.
+3. Add the following code to `umbraco-package.json`:
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": "My workspace",
+ "version": "0.1.0",
+ "extensions": [
+ {
+ "type": "workspaceView",
+ "alias": "My.WorkspaceView",
+ "name": "My Workspace View",
+ "element": "/App_Plugins/workspaceview/dist/workspaceview.js",
+ "meta": {
+ "label": "My Workspace View",
+ "pathname": "/my-workspace-view",
+ "icon": "icon-add"
+ },
+ "conditions": [
+ {
+ "alias": "Umb.Condition.WorkspaceAlias",
+ "match": "Umb.Workspace.Document"
+ }
+ ]
+ }
+ ]
+}
+```
+{% endcode %}
+
+4. Add the following code to the existing `my-element.ts` from the `src`folder:
+
+{% code title="my-element.ts" lineNumbers="true" %}
+```typescript
+import { LitElement, html, customElement, css } from "@umbraco-cms/backoffice/external/lit";
+import { UmbElementMixin } from "@umbraco-cms/backoffice/element-api";
+
+@customElement('my-workspaceview')
+export default class MyWorspaceViewElement extends UmbElementMixin(LitElement) {
+
+ render() {
+ return html`
+
+ Welcome to my newly created workspace view.
+
+ `
+ }
+
+ static styles = css`
+ uui-box {
+ margin: 20px;
+ }
+ `
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'my-workspaceview': MyWorspaceViewElement
+ }
+}
+
+```
+{% endcode %}
+
+In the `workspaceview` folder run `npm run build` and then run the project. Then in the content section of the Backoffice you will see our new Workspace View:
+
+
Workspace View Example
+
+{% hint style="info" %}
+To see the Workspace View that we have created in the content section, first you will need to have some content created.
+{% endhint %}
diff --git a/15/umbraco-cms/customizing/foundation/README.md b/15/umbraco-cms/customizing/foundation/README.md
index 91b05a286e7..a71168b8642 100644
--- a/15/umbraco-cms/customizing/foundation/README.md
+++ b/15/umbraco-cms/customizing/foundation/README.md
@@ -4,28 +4,32 @@ description: Getting started with backoffice setup and configurations
# Foundation
-In this section you can find the common terms, concepts and guides used to extend the Umbraco backoffice.
+In this section, you can find the common terms, concepts, and guides used to extend the Umbraco backoffice.
{% hint style="warning" %}
This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
{% endhint %}
-## [Working with Data](./working-with-data/README.md)
+## [Working with Bellissima](https://github.com/umbraco/Umbraco.Packages/tree/main/bellissima)
+
+An overview of community articles related to the New backoffice "Bellissima".
+
+## [Working with Data](working-with-data/)
An overview of concepts on how to work with data when extending the backoffice.
-## [Contexts](./contexts/README.md)
+## [Contexts](contexts/)
An overview of concepts on how to work with contexts when extending the backoffice.
-## [Umbraco Element](./umbraco-element/README.md)
+## [Umbraco Element](umbraco-element/)
An overview of concepts on how to work with Umbraco element when extending the backoffice.
-## [Sorting](./sorting.md)
+## [Sorting](sorting.md)
An overview of concepts on how to work with sorting when extending the backoffice.
-## [Routes](./routes.md)
+## [Routes](routes.md)
An overview of concepts on how to work with routes when extending the backoffice.
diff --git a/15/umbraco-cms/customizing/foundation/contexts/README.md b/15/umbraco-cms/customizing/foundation/contexts/README.md
index 071028b2418..fb3d82f8307 100644
--- a/15/umbraco-cms/customizing/foundation/contexts/README.md
+++ b/15/umbraco-cms/customizing/foundation/contexts/README.md
@@ -10,10 +10,6 @@ This page is a work in progress and may undergo further revisions, updates, or a
Below you can find some articles on how you can work with different contexts:
-## [Global Context](global-context.md)
-
-A global context manages the logic code from your Lit Element controllers.
-
-## [Property Dataset Context](variant-context.md)
+## [Property Dataset Context](../../../customize-the-backoffice/foundation/contexts/property-dataset-context.md)
A Dataset Context is the connection point between a Property Editor and a Workspace and covers a set of properties.
diff --git a/15/umbraco-cms/customizing/foundation/contexts/property-dataset-context.md b/15/umbraco-cms/customizing/foundation/contexts/property-dataset-context.md
new file mode 100644
index 00000000000..8fb610ae303
--- /dev/null
+++ b/15/umbraco-cms/customizing/foundation/contexts/property-dataset-context.md
@@ -0,0 +1,25 @@
+---
+description: The Variant Context is a context that holds the data for a set of properties.
+---
+
+# Property Dataset Context
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+Property Editors UIs require the Dataset Context to be present to work. This enables Property Editor UIs to have a generic relation with its ownership.
+
+The Dataset Context holds a name and a set of properties. What makes a property can vary but an alias and a value are required.
+
+### Dataset Context Concerning Property Editors and Workspaces
+
+A Dataset Context is the connection point between a Property Editor and a Workspace.
+
+The hierarchy is as follows:
+
+* Workspace Context
+ * Dataset Context
+ * Property Editor UIs
+
+A dataset context covers a set of properties, in some cases a workspace then needs to have multiple variants. An example of such is Document Workspace. Each variant has its own set of properties and a name.
diff --git a/15/umbraco-cms/customizing/foundation/icons.md b/15/umbraco-cms/customizing/foundation/icons.md
new file mode 100644
index 00000000000..da4e26de647
--- /dev/null
+++ b/15/umbraco-cms/customizing/foundation/icons.md
@@ -0,0 +1,3 @@
+# Icons
+
+The icons from the Umbraco backoffice are based on [Lucide Icons](https://lucide.dev/). The syntax for getting the icons starts with`icon-`. You can find the list of all icons in the [Icon registry list on Github](https://github.com/umbraco/Umbraco.CMS.Backoffice/tree/762e43b2f49ca483df9cfe28de20f31ca07bb22b/src/packages/core/icon-registry/icons).
diff --git a/15/umbraco-cms/customizing/foundation/localization.md b/15/umbraco-cms/customizing/foundation/localization.md
new file mode 100644
index 00000000000..62d263007df
--- /dev/null
+++ b/15/umbraco-cms/customizing/foundation/localization.md
@@ -0,0 +1,167 @@
+---
+description: Learn how to manage and use the Backoffice UI Localization files.
+---
+
+# Backoffice Localization
+
+This article describes how you can translate the Umbraco Backoffice UI into different languages. You can use the existing localizations from Umbraco or register your own localizations. You can also use the localization in your custom elements and controllers.
+
+## Registering Localization
+
+Localizations can be registered via the Extension Registry. [Read more about the Localization Extension Type](../extending-overview/extension-types/localization.md).
+
+### Missing Localization Keys
+
+As Umbraco is an evolving product, new text is regularly added to the English version of these files. Therefore, some of the languages may no longer be up-to-date.
+
+If a key is not found in the current language, the fallback language will be used. The fallback language is **English** with the culture code **en**.
+
+If a translation is missing, the default value within `umb-localize` will be shown in the user interface:
+
+```html
+Default value
+```
+
+Instead of showing the default value we can show the key alias if we set `debug="true"`:
+
+```html
+
+```
+
+## Using the Localizations
+
+### Localize Element
+
+The following example shows how you can display localized text with the `umb-localize` element:
+
+```html
+
+```
+
+{% hint style="info" %}
+You can have a look and try out the element in the [UI API Docs](https://apidocs.umbraco.com/v14/ui/?path=/docs/api-localization-umblocalizeelement--docs).
+{% endhint %}
+
+### **Localize Controller**
+
+In some situations, you need the localization as a variable that can be parsed. In this case, the Localization Controller can be used in your `element.ts` file. This can be setup in two ways:
+
+* Using [Umbraco Element](localization.md#umbraco-element)
+* Using [Umbraco Controller](localization.md#umbraco-controller)
+
+#### Umbraco Element
+
+When using an [**Umbraco Element**](../../customizing/foundation/umbraco-element/)**,** the **Localization Controller** is already initialized on the `localize` property via the `UmbElementMixin`.
+
+```typescript
+import { LitElement, css, html } from "lit";
+import { customElement } from "@umbraco-cms/backoffice/external/lit";
+import { UmbElementMixin } from "@umbraco-cms/backoffice/element-api";
+
+export default class MyElement extends UmbElementMixin(LitElement) {
+ render() {
+ return html`
+ `;
+ }
+}
+```
+
+The arguments will be passed to the function in the localization file if it is a function.
+
+#### Umbraco Controller
+
+If you are working with an Umbraco Controller, then you need to initialize the Localization Controller on your own via the `UmbLocalizationController`:
+
+```typescript
+import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
+import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api';
+
+export class MyController extends UmbControllerBase {
+ // Create a new instance of the controller and attach it to the element
+ #localize = new UmbLocalizationController(this);
+
+ render() {
+ return html` `;
+ }
+}
+```
+
+## Using arguments
+
+Sometimes you need to pass arguments to the localization to return different values based on the arguments. A localization value can be either a string or a function. Given a localization file like this, we can return different values based on the number of items:
+
+```javascript
+export default {
+ section: {
+ numberOfItems: (count) => {
+ count = parseInt(count, 10);
+ if (count === 0) return 'Showing nothing';
+ if (count === 1) return 'Showing only one item';
+ return `Showing ${count} items`;
+ },
+ },
+};
+```
+
+{% hint style="info" %}
+You can try out the arguments feature in the [UI API Docs](https://apidocs.umbraco.com/v14/ui/?path=/story/api-localization-umblocalizeelement--with-arguments).
+{% endhint %}
+
+**Using the Localize Element**
+
+You can pass arguments to the localization by adding them as additional attributes:
+
+```html
+
+Showing items
+```
+
+The arguments will be passed to the function in the localization file if it is a function. The `args` attribute must be JSON-serializable and each array value will be passed to the function as an extra argument.
+
+**Using the Localize Controller**
+
+You can pass arguments to the localization by calling the `term` method with the arguments:
+
+```typescript
+// Outputs: Showing 5 items
+this.localize.term('section_numberOfItems', 5);
+```
+
+The arguments will be passed to the function in the localization file if it is a function. Each argument of `term` will be passed to the function as an extra argument.
+
+### Using placeholders
+
+You can also use placeholders in the localization keys to replace parts of the string with dynamic values. Placeholders are defined by curly braces `{0}` or percentage signs `%0%` in the localization key. The placeholders will be replaced one-to-one with the arguments passed to the localization. It works the same as the arguments feature, except you cannot calculate the value based on the arguments.
+
+Given a localization file like this:
+
+{% code title="en.js" %}
+```javascript
+export default {
+ section: {
+ numberOfItems: 'Showing {0} items',
+ },
+};
+```
+{% endcode %}
+
+You can use the same `args` attribute to pass the arguments:
+
+```html
+
+
+```
+
+## Examples
+
+You can add your own localization keys using the principles you have learned, and apply them in a number of ways:
+
+### Using localization in a custom element
+
+You can find a localization example in the [Adding localization to the dashboard](../../tutorials/creating-a-custom-dashboard/adding-localization-to-the-dashboard.md) article. This will get you started with using localization in your custom elements. You can apply the same principles to all extensions.
+
+### Using localization in property descriptions and labels
+
+Property descriptions and labels can also be localized. They are formatted as Markdown and can contain localization keys using the built-in [Umbraco Flavored Markdown](../../reference/umbraco-flavored-markdown.md) syntax.
diff --git a/15/umbraco-cms/customizing/foundation/routes.md b/15/umbraco-cms/customizing/foundation/routes.md
index 00b0abea142..eff579be84e 100644
--- a/15/umbraco-cms/customizing/foundation/routes.md
+++ b/15/umbraco-cms/customizing/foundation/routes.md
@@ -12,13 +12,13 @@ This page is a work in progress and may undergo further revisions, updates, or a
The routing in the backoffice is flexible and customizable. In this article, you can find a couple of starting points for routing.
-The overall **divider** is the [Section](../section-trees/sections/) which is a `ManifestSection` extension type. It is also used internally by the following sections: Content, Media, Settings, Members, and so on.
+The overall **divider** is the [Section](../../customize-the-backoffice/extending-overview/extension-types/section.md) which is a `ManifestSection` extension type. It is also used internally by the following sections: Content, Media, Settings, Members, and so on.
Depending on which section you are working on, there are different options:
-* **SectionView**: The [Section View](../section-trees/sections/section-view.md) is a view in a section and one of the automatic router extension types. It can be an entry point to a section. If a section has multiple views defined (or both dashboards and views) then the tabs and icons will be rendered. As some examples, you can check the **Packages** and **Member** sections.
-* **Dashboard**: The [Dashboard](../dashboards.md) is an entry point to a section. If there is more than one section view or dashboard then the defined tabs and icons will be rendered to make it possible to navigate.
-* **Workspace**: The [Workspace](../workspaces/) concept has built-in features to facilitate editing of an entity of a certain entity type. It is used by many entities in the backoffice like content, media, content types, data types, dictionaries and so on.
+* **SectionView**: The [Section View](../../customize-the-backoffice/extending-overview/extension-types/section-view.md) is a view in a section and one of the automatic router extension types. It can be an entry point to a section. If a section has multiple views defined (or both dashboards and views) then the tabs and icons will be rendered. As some examples, you can check the **Packages** and **Member** sections.
+* **Dashboard**: The [Dashboard](../../customize-the-backoffice/extending-overview/extension-types/dashboard.md) is an entry point to a section. If there is more than one section view or dashboard then the defined tabs and icons will be rendered to make it possible to navigate.
+* **Workspace**: The [Workspace](../../customize-the-backoffice/workspaces.md) concept has built-in features to facilitate editing of an entity of a certain entity type. It is used by many entities in the backoffice like content, media, content types, data types, dictionaries and so on.
* **Custom element**: A [Custom Element](umbraco-element/) is a section that can be configured to use any web component as the **entry point**. The `element()` can be configured in the manifest. By doing this we'll disable the possibility of using dashboards and section views for the section since they will not be automatically routed/rendered. This option should be used only when necessary.
### Building routing
diff --git a/15/umbraco-cms/customizing/foundation/terminology.md b/15/umbraco-cms/customizing/foundation/terminology.md
new file mode 100644
index 00000000000..b2e3ea9d2d0
--- /dev/null
+++ b/15/umbraco-cms/customizing/foundation/terminology.md
@@ -0,0 +1,23 @@
+---
+description: A list of some of the key concepts with working the Umbraco Backoffice.
+---
+
+# Terminology
+
+Understanding certain key concepts is essential when customizing the backoffice. These terminologies can help you decode the purpose of code effectively:
+
+* **Repository:** An API enables communication with a server.
+* **Store:** An API representing data, generally coming from the server. Most stores would talk with one or more resources. You can read more about this in the [Store](../../customizing/foundation/working-with-data/store.md) article.
+* **State:** A reactive container holding data, when data is changed all its Observables will be notified. You can read more about state and observables in the [States](../../customizing/foundation/working-with-data/states.md) article.
+ * **Observable:** An observable is the hook for others to subscribe to the data of a State.
+ * **Observe:** Observe describes what we do when subscribing to an Observable.
+* **Context-API:** The name used to serve APIs (instances/classes) for a certain context in the DOM. An API that is served via the Context-API is called a Context. You can read more about this in the [Context API](../../customizing/foundation/working-with-data/context-api.md) article.
+ * **Context Provider:** One that provides a class instance as a Context API.
+ * **Context Consumer:** One that consumer subscribes to a class instance as a Context API.
+* **Controller:** An abstract term for a thing that hooks into the lifecycle of an element. Many things in our system are Controllers.
+* **Umbraco Controller:** Enables hosting controllers. Additionally, it provides a few shortcut methods for initializing core Umbraco Controllers. You can read more about this in the [Controllers](../../customizing/foundation/umbraco-element/controllers/) article.
+ * **Controller Host:** A class that can host controllers.
+ * **Controller Host Element:** The element that can host controllers.
+* **Umbraco Element:** The `UmbLitElement` or `UmbElemenMixin` enables hosting controllers. Additionally, it provides a few shortcut methods for initializing core Umbraco Controllers. You can read more about this in the [Umbraco Element](../../customizing/foundation/umbraco-element/) article.
+
+Read more about various ways how to get started with extending the backoffice in the [Backoffice Setup](../../customizing/extending-overview/) article.
diff --git a/15/umbraco-cms/customizing/foundation/working-with-data/context-api.md b/15/umbraco-cms/customizing/foundation/working-with-data/context-api.md
index 77fc0384328..49328c0cb35 100644
--- a/15/umbraco-cms/customizing/foundation/working-with-data/context-api.md
+++ b/15/umbraco-cms/customizing/foundation/working-with-data/context-api.md
@@ -129,7 +129,7 @@ The consumption of the Additional API will never happen as the token uses the sa
This is only relevant if you are going to make multiple context API for the same context. Discriminator only gives value for consumption of Context APIs that have a varying interface. The backoffice uses this for the different types of Workspace Contexts.
{% endhint %}
-In some cases, it is needed to have different APIs for the same context. For example, the [Workspace Contexts](../../workspaces/workspace-context.md).
+In some cases, it is needed to have different APIs for the same context. For example, the [Workspace Contexts](../../../customize-the-backoffice/extending-overview/extension-types/workspace-context.md).
If someone wants the workspace name, they might not care about the specific API of the Workspace Context. These implementations can use a standard Context Token with a type of generic Workspace Context.
diff --git a/15/umbraco-cms/customizing/overview.md b/15/umbraco-cms/customizing/overview.md
new file mode 100644
index 00000000000..2bd618a18e3
--- /dev/null
+++ b/15/umbraco-cms/customizing/overview.md
@@ -0,0 +1,35 @@
+---
+description: >-
+ Get an overview of the different options for extending and customizing the
+ Umbraco CMS backoffice.
+---
+
+# Extend and customize the editing experience
+
+The backoffice is one of the main forces of Umbraco CMS. It is where you build the foundations for the website and where your content editors will work with the content.
+
+{% hint style="info" %}
+Are you looking to **extend and customize the Umbraco CMS**?
+
+Resources are available in the [Extending](../extending/build-on-umbraco-functionality.md) section for when you are looking to extend Umbraco functionality beyond the backoffice.
+{% endhint %}
+
+In this section, you will find all the resources you need to build an intuitive and fluid editor experience for your content editors.
+
+
Dashboards
The dashboard is where all the main functionality of the backoffice will be.
+
+{% content-ref url="../customizing/foundation/" %}
+[foundation](../customizing/foundation/)
+{% endcontent-ref %}
+
+{% content-ref url="../customizing/extending-overview/extension-types/" %}
+[extension-types](../customizing/extending-overview/extension-types/)
+{% endcontent-ref %}
+
+***
+
+## Umbraco Training
+
+Umbraco HQ offers a training course covering extending and customizing the Umbraco Backoffice to enhance the editing experience. The course targets frontend and backend developers familiar with Umbraco who want to extend the UI for editors.
+
+[Explore the Extending the Backoffice Training Course](https://umbraco.com/training/course-details/extending-the-backoffice-details/) to learn more about the topics covered and how it can enhance your Umbraco development skills.
diff --git a/15/umbraco-cms/customizing/project-bellissima.md b/15/umbraco-cms/customizing/project-bellissima.md
index bb2b1f62560..a819247ddd2 100644
--- a/15/umbraco-cms/customizing/project-bellissima.md
+++ b/15/umbraco-cms/customizing/project-bellissima.md
@@ -6,18 +6,10 @@ description: >-
# Project Bellissima
-"Bellissima", the code name for the frontend code of the backoffice, is a re-creation of the backoffice of Umbraco. While replacing the deprecated angular code with [Vite](https://vitejs.dev/), [Lit](https://lit.dev/), and [TypeScript](https://www.typescriptlang.org/), you can customize and extend everything in the backoffice.
+"Bellissima", the code name for the frontend code of the backoffice, is a re-creation of the backoffice of Umbraco. While replacing the deprecated angular code with [Lit](https://lit.dev/) and [TypeScript](https://www.typescriptlang.org/), you can customize and extend everything in the backoffice.
An overview of all the customizable sections and elements in the Umbraco CMS backoffice.
Each block is an extension point that can be extended, customized, replaced, or removed.
You are not limited to the mentioned frameworks. You can use any other framework or library of your choice.
-
-## Resources
-
-{% hint style="info" %}
-You can find a list of other resources related to the new backoffice of Umbraco in the [Umbraco v14 "Bellissima" Resources](https://github.com/umbraco/Umbraco.Packages/tree/main/bellissima) article.
-{% endhint %}
-
-
diff --git a/15/umbraco-cms/customizing/property-editors/README.md b/15/umbraco-cms/customizing/property-editors/README.md
index 219dac00da4..224012211e8 100644
--- a/15/umbraco-cms/customizing/property-editors/README.md
+++ b/15/umbraco-cms/customizing/property-editors/README.md
@@ -18,7 +18,7 @@ This section describes how to work with and create Property Editors. A property
A property editor is an editor used to insert content into Umbraco. A Property Editor is composed of two extensions: Property Editor Schema and Property Editor UI.
-## [Package Manifest](../package-manifest.md)
+## [Package Manifest](../../customize-the-backoffice/umbraco-package.md)
Reference for the package.manifest JSON file format to register one or more property editors for Umbraco.
@@ -34,7 +34,7 @@ Use Property Actions to add additional functionaility to your custom property ed
Learn how to build your own Block Editors.
-## [Tracking References](tracking.md)
+## [Tracking References](broken-reference)
Learn how to extend Property editors to track entity references inside the property editor.
diff --git a/15/umbraco-cms/customizing/property-editors/build-a-block-editor.md b/15/umbraco-cms/customizing/property-editors/build-a-block-editor.md
index c4a0864cec8..a8cf8943b3d 100644
--- a/15/umbraco-cms/customizing/property-editors/build-a-block-editor.md
+++ b/15/umbraco-cms/customizing/property-editors/build-a-block-editor.md
@@ -57,7 +57,7 @@ public class UnicornBlocksConfigurationEditor : ConfigurationEditor {
+ this.#validation.validate().then(() => {
+ console.log('Valid');
+ }, () => {
+ console.log('Invalid');
+ });
+}
+
+render() {
+ return html`
+
+
+
+ Validate
+ `;
+}
+```
+{% endcode %}
+
+## Integrate Umb-Property Elements
+
+The `umb-property` element automatically binds to its nearest validation context.
+
+This is demonstrated in the example below:
+
+{% code %}
+```typescript
+
+#validation = new UmbValidationContext(this);
+
+#validate = () => {
+ this.#validation.validate().then(() => {
+ console.log('Valid');
+ }, () => {
+ console.log('Invalid');
+ });
+}
+
+render() {
+ return html`
+
+
+ Validate
+ `;
+}
+```
+{% endcode %}
+
+## Server Validation and more
+
+This documentation is not available at the moment. For the moment you can find more information in the [Backoffice reposiroty](https://github.com/umbraco/Umbraco.CMS.Backoffice/tree/main/src/packages/core/validation).
diff --git a/15/umbraco-cms/customizing/property-editors/property-dataset.md b/15/umbraco-cms/customizing/property-editors/property-dataset.md
index cb53332d078..c28a50ded44 100644
--- a/15/umbraco-cms/customizing/property-editors/property-dataset.md
+++ b/15/umbraco-cms/customizing/property-editors/property-dataset.md
@@ -2,6 +2,8 @@
A Property Dataset is a Context API that holds the data for a set of properties.
+It is required for the `umb-property` element to have a Property Dataset provided. It can be provided via JavaScript code or an Element as documented below.
+
## Property dataset component
The `umb-property-dataset` component provides a Property Dataset Context for any properties within. This provides a way to implement such purely via Elements.
@@ -32,3 +34,19 @@ In the following example a dataset is implemented by using the `umb-property-dat
property-editor-ui-alias="Umb.PropertyEditorUi.Dropdown">
```
+
+## Consume values
+
+Since a Property Dataset is a Context any descending code can consume it and utilize the values.
+
+Such a case could be a Workspace View that wants to display the value of a specific property.
+
+The following example shows how to consume the Property Dataset and observe the value of a property with the alias of `my-property-alias`.
+
+```typescript
+this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, async (datasetContext) => {
+ this.observe(await datasetContext?.propertyValueByAlias('my-property-alias'), (value) => {
+ console.log('the value of `my-property-alias` is', value)
+ });
+});
+```
diff --git a/15/umbraco-cms/customizing/property-editors/tracking.md b/15/umbraco-cms/customizing/property-editors/tracking.md
index c5cf8971d28..a476528d812 100644
--- a/15/umbraco-cms/customizing/property-editors/tracking.md
+++ b/15/umbraco-cms/customizing/property-editors/tracking.md
@@ -17,25 +17,25 @@ When a content node is saved it will save the entity references as relations.
### For Media Items
1. Go to the **Media** section.
-2. Select a media item and click the **Info** tab.
+2. Select a media item and click the **Info** tab.
- 
+
### For Content Nodes
1. Go to the **Settings** section.
-2. Under the **Relations** from the **Advanced** section, select **Related Document** relations.
+2. Under the **Relations** from the **Advanced** section, select **Related Document** relations.
- 
+
### For Data Types
1. Go to the **Settings** section.
2. Expand the **Data Types** folder.
3. Select the **Data Type** you wish to view the references.
-4. Navigate to the **Info** tab.
+4. Navigate to the **Info** tab.
- 
+
## Example
diff --git a/15/umbraco-cms/customizing/searchable-trees.md b/15/umbraco-cms/customizing/searchable-trees.md
new file mode 100644
index 00000000000..b569a0ef57f
--- /dev/null
+++ b/15/umbraco-cms/customizing/searchable-trees.md
@@ -0,0 +1,165 @@
+# Searchable Trees (ISearchableTree)
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+When you type a search term into the Umbraco backoffice search field, you'll see search results from all the Section Trees that your user account has permission to access:
+
+.png>)
+
+The results are grouped by 'Section Tree' like Content, Media, Document Types. Each 'Tree' has its own associated search mechanism that receives the search term and looks for matches in the tree that is responsible for searching.
+
+You can create your own search mechanisms for your own custom sections or replace the default search implementation for a particular section tree.
+
+## Custom Tree Search
+
+To create a search for your own custom tree you need to create a C# class that implements the interface `Umbraco.Cms.Core.Trees.ISearchableTree`.
+
+### ISearchableTree
+
+```csharp
+using System.Collections.Generic;
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.Models.ContentEditing;
+
+namespace My.Website;
+
+public interface ISearchableTree : IDiscoverable
+{
+ ///
+ /// The alias of the tree that the belongs to
+ ///
+ string TreeAlias { get; }
+
+ ///
+ /// Searches for results based on the entity type
+ ///
+ /// The search term used for finding matching results.
+ /// The number of records to return for a page of results.
+ /// The 0-based index for retrieving a page of search results.
+ /// Populated with the total number of results matching the provided search term.
+ ///
+ /// The starting point for the search, generally a node ID, but for members this is a member type alias.
+ ///
+ ///
+ Task SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null);
+}
+```
+
+Your implementation needs to return an IEnumerable of `SearchResultEntity` items:
+
+```csharp
+public class SearchResultEntity : EntityBasic
+{
+ public SearchResultEntity() {
+ ///
+ /// The score of the search result
+ ///
+ [DataMember(Name = "score")]
+ public float Score { get; set; }
+ };
+
+}
+```
+
+A `SearchResultEntity` consists of a Score (a Float value) identifying its relevance to the search term, and the set of `EntityBasic` properties that all Umbraco objects share: eg Name, Id, Udi, Icon, Trashed, Key, ParentId, Path, Alias, AdditionalData.
+
+#### Example implementation of ISearchableTree
+
+If we have a custom section Tree with the alias 'favouriteThingsAlias' (see the [custom tree example](extending-overview/extension-types/tree.md)) then we could implement searchability by creating the following C# class in our site:
+
+```csharp
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Umbraco.Cms.Core;
+using Umbraco.Cms.Core.Models.ContentEditing;
+using Umbraco.Cms.Core.Trees;
+
+namespace Umbraco.Docs.Samples.Web.Trees;
+
+public class FavouriteThingsSearchableTree : ISearchableTree
+{
+ public string TreeAlias => "favouriteThingsAlias";
+
+ public async Task SearchAsync(string query, int pageSize, long pageIndex, string searchFrom = null)
+ {
+ // your custom search implementation starts here
+ Dictionary favouriteThings = new Dictionary();
+ favouriteThings.Add(1, "Raindrops on Roses");
+ favouriteThings.Add(2, "Whiskers on Kittens");
+ favouriteThings.Add(3, "Skys full of Stars");
+ favouriteThings.Add(4, "Warm Woolen Mittens");
+ favouriteThings.Add(5, "Cream coloured Unicorns");
+ favouriteThings.Add(6, "Schnitzel with Noodles");
+
+ var searchResults = new List();
+
+ var matchingItems = favouriteThings.Where(f => f.Value.StartsWith(query, true, System.Globalization.CultureInfo.CurrentCulture));
+ foreach (var matchingItem in matchingItems)
+ {
+ // Making up the Id/Udi for this example! - these would normally be different for each search result.
+ searchResults.Add(new SearchResultEntity()
+ {
+ Id = 12345,
+ Alias = "favouriteThingItem",
+ Icon = "icon-favorite",
+ Key = new Guid("325746a0-ec1e-44e8-8f7b-6e7c4aab36d1"),
+ Name = matchingItem.Value,
+ ParentId = -1,
+ Path = "-1,12345",
+ Score = 1.0F,
+ Trashed = false,
+ Udi = Udi.Create("document", new Guid("325746a0-ec1e-44e8-8f7b-6e7c4aab36d1"))
+ });
+ }
+ // Set number of search results found
+ var totalFound = matchingItems.Count();
+ // Return your results
+ return new EntitySearchResults(searchResults, totalFound);
+ }
+}
+```
+
+That's all we need, after an application pool recycle, if we now search in the backoffice we'll see matches from our custom 'Favourite Things' tree:
+
+.png>)
+
+Umbraco automatically finds any implementation of `ISearchableTree` in your site and automatically configures it to be used for the custom section mentioned in the TreeAlias property. Be careful not to accidentally have two `ISearchableTree` implementations trying to search the 'same' TreeAlias, it's _one_ `ISearchableTree` per TreeAlias.
+
+## Replacing an existing Section Tree Search
+
+Perhaps you want to change the logic for searching an existing section of the site, (why? - well you might have a 'company name' property on a MemberType in the Member section, and you want searches for that company name to filter the members who work there, the default implementation will only search on Member Name).
+
+Or perhaps you want to replace Examine search in the backoffice with an external Search Service, e.g. Azure Search. In a cloud-hosted implementation you don't need to build the Examine indexes on each new server as your cloud hosting scales out.
+
+### Example
+
+First create your replacement custom `ISearchableTree` implementation, using the same approach as above, but specifying the TreeAlias of the Tree you aim to replace, e.g. 'Member'.
+
+```csharp
+public string TreeAlias => "member";
+```
+
+To avoid your custom implementation clashing with the default `ISearchableTree` for a Tree, you need to remove its `ISearchableTree` implementation from the collection of SearchableTrees using an `IComposer` when Umbraco starts up:
+
+```csharp
+using Umbraco.Cms.Core.Composing;
+using Umbraco.Cms.Core.DependencyInjection;
+using Umbraco.Cms.Web.BackOffice.Trees;
+
+namespace Umbraco.Docs.Samples.Web.Trees;
+
+public class RemoveCoreMemberSearchableTreeComposer : IComposer
+{
+ public void Compose(IUmbracoBuilder builder)
+ {
+ // Remove core MemberTreeController
+ builder.SearchableTrees().Exclude();
+ }
+}
+```
+
+This would then allow your custom implementation of `ISearchableTree` with TreeAlias 'member' to be used when searching the Member Section Tree.
diff --git a/15/umbraco-cms/customizing/section-trees.md b/15/umbraco-cms/customizing/section-trees.md
new file mode 100644
index 00000000000..97da5a467de
--- /dev/null
+++ b/15/umbraco-cms/customizing/section-trees.md
@@ -0,0 +1,29 @@
+---
+description: An explanation on sections and trees in Umbraco
+---
+
+# Sections & Trees
+
+{% hint style="warning" %}
+The Section & Trees articles are a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+The Umbraco backoffice consists of sections (sometimes referred to as applications) which contain Trees.
+
+Each section is identified by its name in the top navigation ribbon of the Umbraco Backoffice.
+
+For example, when you load the backoffice, you'll see that the 'Content' section contains one tree: the content tree. Meanwhile, the 'Settings' section contains a number of trees such as Stylesheets, Document Types, Media Types, etc...
+
+You can create your own sections and trees to extend Umbraco.
+
+## [Sections](extending-overview/extension-types/section.md)
+
+Describes Umbraco Sections, configuration, and APIs.
+
+## [Trees](extending-overview/extension-types/tree.md)
+
+Describes Umbraco Trees, configuration, APIs, and events.
+
+## [Searchable Trees (ISearchableTree)](searchable-trees.md)
+
+Explains how to customize the backoffice search of a Section Tree.
diff --git a/15/umbraco-cms/customizing/ui-library.md b/15/umbraco-cms/customizing/ui-library.md
new file mode 100644
index 00000000000..817046b01d1
--- /dev/null
+++ b/15/umbraco-cms/customizing/ui-library.md
@@ -0,0 +1,50 @@
+---
+description: Find out more about Umbraco UI Library, UI API and Storybook.
+---
+
+# UI Library
+
+## UI Library and UI API
+
+With the UI Library, you get a collection of visual building blocks that consists of pieces to build any UI in Umbraco. Each component is a building block updating its display according to the data passed to it.
+
+{% hint style="info" %}
+**Are you looking for the AngularJS documentation?**
+
+With Umbraco 14 the Umbraco backoffice has been rebuilt using Web Components and TypeScript. This means that AngularJS is no longer being used in Umbraco CMS, hence the removal of the corresponding documentation.
+{% endhint %}
+
+With the UI API, you get a set of collections related to modules export, interfaces, and hierarchy. This includes code examples and much more that you can use to extend the backoffice.
+
+
+
+## UI Library Storybook
+
+The Umbraco UI Library is a set of web components that can be used to build Umbraco User Interfaces. The UI Library separates the user interface from Umbraco’s business logic and creates a unified user experience. This is done with coherent styling and naming, across all the Umbraco platforms and projects including the ones developed by you.
+
+[Storybook](https://uui.umbraco.com/) is an application that gathers all the components together of the UI Library. It holds the documentation for the components and showcases different use case scenarios. You can explore all the components through stories reflecting their use cases.
+
+Each story has interactive controls that allow you to change the state of the component in real time. Every publicly available property is editable in Storybook, so you can test out custom configurations and use cases.
+
+You can also modify the custom properties in the stylesheet to see how the component will look. Every story has a code example that you can copy and paste into your project. This will allow you to implement the components in your own packages and extensions.
+
+### Getting Started with the UI Library
+
+The [Storybook](https://uui.umbraco.com/) is the starting point for working with the Umbraco UI Library. The Storybook contains two tabs:
+
+1. Canvas - The Canvas tab allows to use the interactive controls.
+
+
+2. Docs - Here, you can find code examples for all the stories and use them in your markup. You can look it up by tag name or head to the project repository, where, in the packages folder, you will find all the component packages with all the necessary scripts and examples in the readme files.
+
+
+
+### Import UI Library Components
+
+You can also work with the components on a code level. If you want to do so here is how you import it:
+
+```typescript
+import { UUIButtonElement } from '@umbraco-cms/backoffice/external/uui';
+```
+
+This requires that your Package has the `@umbraco-cms/backoffice` dependency.
diff --git a/15/umbraco-cms/customizing/umbraco-package.md b/15/umbraco-cms/customizing/umbraco-package.md
new file mode 100644
index 00000000000..cbe7e312b4c
--- /dev/null
+++ b/15/umbraco-cms/customizing/umbraco-package.md
@@ -0,0 +1,254 @@
+---
+description: An extension begins with a Package Manifest
+---
+
+# Umbraco Package
+
+A Package is declared via an Umbraco Package Manifest. This describes the Package and declares one or more UI Extensions. The Package Manifest is a JSON file that is stored in the `App_Plugins/{YourPackageName}` folder. The file is named `umbraco-package.json`.
+
+## Sample Manifest
+
+This is a sample manifest. It is always stored in a folder in `App_Plugins/{YourPackageName}`, with the name `umbraco-package.json`. In this example, the package name is `SirTrevor` and is a text box property Data Type.
+
+{% hint style="info" %}
+Before Umbraco 14, the manifest was declared in a `package.manifest` file instead of `umbraco-package.json`. The old format is no longer supported, but you can migrate the contents to the new format.
+{% endhint %}
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "id": "My.Nuget.Package",
+ "name": "Sir Trevor",
+ "version": "1.0.0-beta",
+ "allowPackageTelemetry": true,
+ "extensions": [
+ {
+ "type": "propertyEditorUi",
+ "alias": "Sir.Trevor",
+ "name": "Sir Trevor Property Editor UI",
+ "element": "/App_Plugins/SirTrevor/SirTrevor.js",
+ "meta": {
+ "label": "Sir Trevor",
+ "propertyEditorSchemaAlias": "Umbraco.TextBox",
+ "icon": "icon-code",
+ "group": "Pickers"
+ }
+ }
+ ]
+}
+```
+{% endcode %}
+
+## Root fields
+
+The `umbraco-package` accept these fields:
+
+```json
+{
+ "id": "",
+ "name": "",
+ "version": "",
+ "allowPackageTelemetry": true,
+ "allowPublicAccess": false,
+ "importmap": {
+ "imports": {
+ "": ""
+ },
+ "scopes": {
+ "": ""
+ }
+ },
+ "extensions": []
+}
+```
+
+### Id
+
+The unique identifier for your package. This is used to identify your package and should be unique to your package. If you are creating a package that is distributed via NuGet, you should use the NuGet package ID as the ID for your package.
+
+### Name
+
+Allows you to specify a friendly name for your package that will be used for telemetry. If no name is specified the name of the folder will be used instead.
+
+### Version
+
+The version of your package, if this is not specified there will be no version-specific information for your package. This is used for telemetry and to help users understand what version of your package they are using. It is also used for package migrations. The version should follow the [Semantic Versioning](https://semver.org/) format.
+
+### Allow Package Telemetry
+
+With this field, you can control the telemetry of this package, this will provide Umbraco with the knowledge of how many installations use this package.
+
+Default is `false`.
+
+### Allow Public Access
+
+This field is used to allow public access to the package. If set to `true`, the package will be available for anonymous usage, for example on the login screen. If set to `false`, the package will only be available to logged-in users.
+
+Default is `false`.
+
+### Importmap
+
+The `importmap` field is an object that contains two properties: `imports` and `scopes`. This is used to define the import map for the package. The `imports` property is an object that contains the import map for the package. The `scopes` property is an object that contains the scopes for the package.
+
+**Example**
+
+This example shows how to define an import map for a module exported by a package:
+
+{% code title="umbraco-package.json" lineNumbers="true" %}
+```json
+{
+ "importmap": {
+ "imports": {
+ "mypackage/services": "/App_Plugins/MyPackage/services/index.js",
+ }
+ }
+}
+```
+{% endcode %}
+
+The `imports` object contains the import map for the package. The key is the specifier for the module that is being imported, and the value is the URL of the module.
+
+This allows developers to consume modules that are exported by a package without having to know the exact path to the module:
+
+{% code title="index.js" %}
+```javascript
+import { MyService } from 'mypackage/services';
+```
+{% endcode %}
+
+Umbraco supports the current specification of the property as outlined on MDN Web Docs: [importmap](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap).
+
+### Extensions
+
+The `extensions` field is an array of UI Extension objects. Each object describes a single UI Extension.
+
+There are three generic fields that are common to all UI Extensions:
+
+* `type` - The type of the UI Extension.
+* `alias` - The alias of the UI Extension. This must be unique.
+* `name` - The name of the UI Extension.
+
+These are the current types of UI Extensions:
+
+| Type | Description |
+| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| authProvider | An authentication provider for [external login](../reference/security/external-login-providers.md). |
+| appEntryPoint | An app entry point is a JavaScript module that is executed when any app is loaded (Login, Installer, Upgrader, and Backoffice). It will never be destroyed. Read more about [Entry Points](../customizing/extending-overview/extension-types/backoffice-entry-point.md). |
+| backofficeEntryPoint | A backoffice entry point is a JavaScript module that is executed when the backoffice is loaded. It will be destroyed when the backoffice is closed or logged out. Read more about [Entry Points](../customizing/extending-overview/extension-types/backoffice-entry-point.md). |
+| blockEditorCustomView | A custom view for a block in the block editor. |
+| bundle | A bundle is a collection of other manifests that can be loaded together. You would use this in lieu of a `backofficeEntryPoint` if all you needed was to load extensions through JavaScript. |
+| condition | A condition that can be used to control the visibility of other UI Extensions. Read more about [Conditions](../customizing/extending-overview/extension-types/condition.md). |
+| currentUserAction | A current user action is a button that can be added to the current user view. |
+| dashboard | A dashboard is a view that can be added to any section. It is displayed in the dashboard view with tabs. Read more about [Dashboards](extending-overview/extension-types/dashboard.md). |
+| dashboardCollection | A dashboard collection is a view that can be added to a collection. |
+| dynamicRootOrigin | A dynamic root origin is a dynamic root origin that can be added to the Dynamic Root selector. |
+| dynamicRootQueryStep | A dynamic root query step is a query step that can be added to the Dynamic Root selector. |
+| entityAction | An entity action is a button that can be added to any entity, like a document, media, member, etc. It will be shown in the entity actions menu and in the entity actions menu. |
+| entityBulkAction | An entity bulk action is a button that can be added to the bulk actions menu, which is shown when multiple entities are selected in a collection view. |
+| entryPoint | (Deprecated) Old name for `backofficeEntryPoint`. |
+| globalContext | A global context is a context instance that is available to all components in the Backoffice. It is used to share state between components and to provide a way to communicate between components. Read more about [Global Context](extending-overview/extension-types/global-context.md). |
+| granularUserPermissions | A granular user permission is a permission that can be added to a user. It is used to control access to specific parts of the Backoffice. |
+| headerApp | A header app is a component that can be added to the header such as a button or a link. Read more about [Header Apps](../customizing/extending-overview/extension-types/header-apps.md). |
+| healthCheck | A health check is a check that can be added to the health check dashboard. Read more about the backend side of [Health Checks](../reference/configuration/healthchecks.md). |
+| icons | An icon is a set of icons that can be added to the icon picker. Read more in the [Icons article](../customizing/extending-overview/extension-types/icons.md). |
+| localization | A localization is a set of translations that can be added to the localization service. Read more about [Localization](foundation/localization.md) in the UI. |
+| menu | A menu is a component that can be added to the menu bar. Read more about [Menus](../customizing/extending-overview/extension-types/menu.md). |
+| menuItem | A menu item is a component that can be added to a menu. |
+| mfaLoginProvider | This type of login provider is the UI component of [Two-Factor Authentication](../reference/security/two-factor-authentication.md) used to enable/disable the provider. |
+| modal | A modal dialog. Read more about [Modals](../customizing/extending-overview/extension-types/modals/). |
+| monacoMarkdownEditorAction | A Monaco Markdown Editor action is a button that can be added to the toolbar of the [Markdown Property Editor](../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/markdown-editor.md). |
+| packageView | A package view is an optional view that can be shown in the "Packages" section of the Backoffice. The user can navigate to this view to see more information about the package and to manage it. |
+| previewAppProvider | A preview app provider is a provider that can be used to provide a preview app for the Save and Preview action on a document. |
+| propertyAction | A property action is a button that can be added to the property actions menu. |
+| propertyEditorSchema | A property editor schema is a model that describes a Data Editor and its properties from the backend to the UI. It is used by Property Editor UIs. Read more about [Property Editors](../customizing/property-editors/). |
+| propertyEditorUi | A property editor UI is a UI component that can be added to content types. It is used to render the UI of a Data Editor. Read more about [Property Editors](../customizing/property-editors/). |
+| searchProvider | A search provider is a provider that can be used to provide search results for the search bar in the Backoffice. |
+| searchResultItem | A search result item is a component that can be added to the search results. |
+| theme | A theme is a set of styles that can be added to the Backoffice. The user can select their preferred theme in the current user modal. |
+| tinyMcePlugin | A TinyMCE plugin is a plugin that can be added to the TinyMCE editor. Read more about [TinyMCE Plugins](../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/rich-text-editor/rte-plugins.md). |
+| treeItem | A tree item that can be added to the tree. |
+| tree | A tree that can be added to a section. |
+| ufmComponent | This type of component is a formatter that can be added to the [Umbraco Flavoured Markdown](../reference/umbraco-flavored-markdown.md), which is used in property descriptions and advanced labels. Read more about the [Label Property Configuration](../fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/block-editor/label-property-configuration.md). |
+| userProfileApp | A user profile app is a component that can be added to the current user view. |
+
+**Collections**
+
+| Type | Description |
+| ---------------- | -------------------------------------------------------------------------- |
+| collection | A collection to show a list of entities (documents, media, members, etc.). |
+| collectionAction | A collection action is a button that can be added to a collection view. |
+| collectionView | A collection view is a view that can be added to a collection. |
+
+**Stores and repositories**
+
+| Type | Description |
+| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| repository | A repository is a class that can be used to interact with a data source. It is used either by context classes or elements directly to interact with the data source. It typically holds a `store` instance. Read more about [Repositories](../customizing/foundation/working-with-data/repositories.md). |
+| store | A store is a context instance that is available to repositories. It is used by repositories to store data. Read more about [Stores](../customizing/foundation/working-with-data/store.md). |
+| itemStore | An item store is a store that can be used to store items. It is used by repositories to store items. |
+| treeStore | A tree store is a store that can be used to store tree data. It is used by tree repositories to store tree data. |
+
+**Sections**
+
+| Type | Description |
+| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| section | A section is a section that can be added to the navigation bar of the Backoffice like the "Content" or "Media" sections that are built-in. Read more about [Sections](extending-overview/extension-types/section.md). |
+| sectionRoute | A section route is a route that can be added to a section. It is used to define the URL of the view that is displayed in the main content area of the Backoffice. |
+| sectionSidebarApp | A section sidebar app that can be added to the section sidebar. Read more about [Section Sidebar Apps](extending-overview/extension-types/section-sidebar.md). |
+| sectionView | A section view is a view that can be added to a section. It is displayed in the main content area of the Backoffice. More than one view can be added to a section, and the user can switch between them. In that case, the views are displayed as tabs. Read more about [Section Views](extending-overview/extension-types/section-view.md). |
+
+**Workspaces**
+
+| Type | Description |
+| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| workspace | A workspace is a component that can be added to an entity type. This is the editor you see, when you edit an entity. Read more about [Workspaces](workspaces.md). |
+| workspaceActionMenuItem | A workspace action menu item is a button that can be added to the workspace action menu. |
+| workspaceAction | A workspace action is a button that can be added to the workspace such as the "Save" button. Read more about [Workspace Actions](extending-overview/extension-types/workspace-editor-actions.md). |
+| workspaceContext | A workspace context is a context instance that is available to all components in the workspace. It is used to share state between components and to provide a way to communicate between components. Read more about [Workspace Context](extending-overview/extension-types/workspace-context.md). |
+| workspaceFooterApp | A workspace footer app is a component that can be added to the workspace footer. |
+| workspaceView | A workspace view is a view that can be added to a workspace. It is displayed in the main content area of the workspace. More than one view can be added to a workspace, and the user can switch between them. In that case, the views are displayed as tabs. Read more about [Workspace Views](extending-overview/extension-types/workspace-views.md). |
+
+Read more about [Extension Types](broken-reference) in the Backoffice to get a better understanding of the different types of extensions.
+
+## Package Manifest IntelliSense
+
+Make your IDE be aware about the opportunities of the `umbraco-package.json` by adding a JSON schema. This gives your code editor abilities to autocomplete and knowledge about the format. This helps to avoid mistakes or errors when editing the `umbraco-package.json` file.
+
+### Adding inline schema
+
+Editors like Visual Studio can use the `$schema` notation in your file.
+
+```json
+{
+ "$schema": "../../umbraco-package-schema.json",
+ "name": ""
+}
+```
+
+Hover over any of the properties to see the description of the property. You can also use the `Ctrl + Space` (Windows/Linux) or `CMD + Space` (macOS) shortcut to see the available properties.
+
+## Load Package Manifest files
+
+Umbraco scans the `App_Plugins` folder for `umbraco-package.json` files **two levels deep**. When found, the packages are loaded into the system.
+
+You may need to restart the application, if you add a new file or modify an existing manifest:
+
+If the runtime mode is `Production`, the manifests are cached for 30 days or until the application is restarted to improve performance. In other runtime modes, the cache is cleared every 10 seconds.
+
+{% hint style="info" %}
+You can implement the interface [IPackageManifestReader](https://apidocs.umbraco.com/v14/csharp/api/Umbraco.Cms.Infrastructure.Manifest.IPackageManifestReader.html) to provide your own package manifest reader. This can be useful if you want to load package manifests from a different location or source.
+{% endhint %}
+
+## Razor Class Library
+
+Umbraco also supports [Razor Class Library (RCL)](https://learn.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-8.0\&tabs=visual-studio#create-an-rcl-with-static-assets) projects that contain static web assets. The `umbraco-package.json` file can be placed in the `wwwroot` folder of the RCL project. The package will be loaded when the RCL is referenced by the main project. You must map the web path to `App_Plugins` in your `.csproj` file:
+
+{% code title="MyProject.Assets.csproj" %}
+```xml
+
+ App_Plugins/{YourPackageName}
+
+```
+{% endcode %}
+
+Read more about getting set up for Backoffice development in the [Customize Backoffice](overview.md) section.
diff --git a/15/umbraco-cms/customizing/workspaces.md b/15/umbraco-cms/customizing/workspaces.md
new file mode 100644
index 00000000000..963bdd2e4bc
--- /dev/null
+++ b/15/umbraco-cms/customizing/workspaces.md
@@ -0,0 +1,24 @@
+# Workspaces
+
+{% hint style="warning" %}
+This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+{% endhint %}
+
+A Workspace is the editor for a specific entity type. It can either be a simple view of data or a complex editor with multiple views.
+
+* A workspace is based on an entity type (e.g. content, media, member, etc.) and a unique string (ex: key).
+* Most workspaces hold a draft state of an entity. It is a copy of the entity data that can be modified at runtime and sent to the server to be saved.
+* A workspace can be a single view or consist of multiple views.
+* A workspace should host a workspace context, with which anything within can communicate.
+
+
Workspace
+
+```ts
+interface UmbWorkspaceElement {}
+```
+
+## [Workspace Context](extending-overview/extension-types/workspace-context.md)
+
+## [Workspace Views](extending-overview/extension-types/workspace-views.md)
+
+## [Workspace Actions](extending-overview/extension-types/workspace-editor-actions.md)
diff --git a/15/umbraco-cms/extending/database.md b/15/umbraco-cms/extending/database.md
index c0ad6613eff..423150c9bd5 100644
--- a/15/umbraco-cms/extending/database.md
+++ b/15/umbraco-cms/extending/database.md
@@ -245,16 +245,12 @@ Figuring out how to manage data across multiple environments can be different be
To create, read, update or delete data from your custom database tables, you can use the `IScopeProvider` to get access to the database operations.
-The following example creates an `UmbracoApiController` to be able to fetch and insert blog comments.
+The following example creates a `Controller` that uses `[Route]` annotations to create API endpoints for fetching and inserting blog comments.
{% hint style="info" %}
This example does not use the aforementioned `BlogCommentSchema` class but rather a separate (yet duplicate) class that is not part of the example. Also, be aware that things like error handling and data validation have been omitted for brevity.
{% endhint %}
-{% hint style="warning" %}
-The example below uses UmbracoApiController which is obsolete in Umbraco 14 and will be removed in Umbraco 15.
-{% endhint %}
-
```csharp
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
diff --git a/15/umbraco-cms/reference/language-variation.md b/15/umbraco-cms/reference/language-variation.md
index aa55e90113b..97d34358419 100644
--- a/15/umbraco-cms/reference/language-variation.md
+++ b/15/umbraco-cms/reference/language-variation.md
@@ -1,3 +1,7 @@
+---
+description: Language variants allow you to have different variations of content based on the language culture. Learn how to use them in this section.
+---
+
# Language Variation
Language Variation allows you to have different variations of content based on a language culture. In the documentation there are other useful articles about the feature:
diff --git a/15/umbraco-cms/reference/security/cookies.md b/15/umbraco-cms/reference/security/cookies.md
index 506b831d836..c8e012564c1 100644
--- a/15/umbraco-cms/reference/security/cookies.md
+++ b/15/umbraco-cms/reference/security/cookies.md
@@ -1,3 +1,7 @@
+---
+description: Learn about the cookies required for accessing the Umbraco Backoffice and their purposes.
+---
+
# Cookies
The cookies listed in this article are required only for accessing the Backoffice. You can include these in your own cookie policy, if you wish.
diff --git a/15/umbraco-cms/reference/security/custom-password-check.md b/15/umbraco-cms/reference/security/custom-password-check.md
index 21aa0969c6c..581166a999e 100644
--- a/15/umbraco-cms/reference/security/custom-password-check.md
+++ b/15/umbraco-cms/reference/security/custom-password-check.md
@@ -1,3 +1,7 @@
+---
+description: You can specify your own logic to validate a username and password against a custom data store. Learn more about it in this section.
+---
+
# Replacing the basic username/password check
Having the ability to replace the logic to validate a username and password against a custom data store is important to some developers. Normally in ASP.Net Core Identity this would require you to override the `UmbracoBackOfficeUserManager.CheckPasswordAsync` implementation and then replace the `UmbracoBackOfficeUserManager` with your own class during startup. Since this is a common task we've made this process a lot easier with an interface called `IBackOfficeUserPasswordChecker`.
diff --git a/15/umbraco-cms/reference/security/password-reset.md b/15/umbraco-cms/reference/security/password-reset.md
index 6f28c8817af..7435ef2784e 100644
--- a/15/umbraco-cms/reference/security/password-reset.md
+++ b/15/umbraco-cms/reference/security/password-reset.md
@@ -1,3 +1,7 @@
+---
+description: Learn about the security features put in place to protect Umbraco users from unauthorized access and password breaches.
+---
+
# Password reset
It's impossible to brute force the authentication on the login screen because after `MaxFailedAccessAttemptsBeforeLockout` the account of the user will be locked, and until that account is unlocked in the Users section, no attempt will succeed.
diff --git a/15/umbraco-cms/reference/security/security-hardening.md b/15/umbraco-cms/reference/security/security-hardening.md
index 8e62cf08f40..25587258f45 100644
--- a/15/umbraco-cms/reference/security/security-hardening.md
+++ b/15/umbraco-cms/reference/security/security-hardening.md
@@ -1,3 +1,7 @@
+---
+description: Learn how to strengthen the security of your Umbraco installation, and reduce the risk of unauthorized access.
+---
+
# Umbraco Security Hardening
Here you find some tips and trick for hardening the security of your Umbraco installation.
diff --git a/15/umbraco-cms/release-candidate-guide.md b/15/umbraco-cms/release-candidate-guide.md
index afa9f727aaa..0850c04adda 100644
--- a/15/umbraco-cms/release-candidate-guide.md
+++ b/15/umbraco-cms/release-candidate-guide.md
@@ -63,3 +63,9 @@ Here is a list of all the articles that are new to this version or have been upd
### New articles
* [Tutorial: Extending the Help Menu](tutorials/extending-the-help-menu.md)
+
+### Updated articles
+
+* Changes made based on the removal of the UmbracoAPIController
+ * [Common Pitfalls: Static references to scoped references](reference/common-pitfalls.md#static-references-to-scoped-instances-such-as-umbracohelper)
+ * [Creating a custom database table](extending/database.md)
\ No newline at end of file