From 81b61e43455b18876c30b97881757e8d3bd95eb4 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 20 Aug 2025 11:32:59 +0100 Subject: [PATCH 1/2] Added details of sign providers and backoffice signs --- 16/umbraco-cms/SUMMARY.md | 2 + .../customizing/back-office-signs.md | 23 +++++ 16/umbraco-cms/extending/sign-providers.md | 87 +++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 16/umbraco-cms/customizing/back-office-signs.md create mode 100644 16/umbraco-cms/extending/sign-providers.md diff --git a/16/umbraco-cms/SUMMARY.md b/16/umbraco-cms/SUMMARY.md index 74944bf5458..3b1bcabe1b5 100644 --- a/16/umbraco-cms/SUMMARY.md +++ b/16/umbraco-cms/SUMMARY.md @@ -209,6 +209,7 @@ * [Sections & Trees](customizing/section-trees.md) * [Property Level UI Permissions](customizing/property-level-ui-permissions.md) * [Icons](customizing/foundation/icons.md) +* [BackOffice Signs](customizing/back-office-signs.md) * [Searchable Trees (ISearchableTree)](customizing/searchable-trees.md) * [Property Editors](customizing/property-editors/README.md) * [Property Editor Validation](customizing/property-editors/property-editor-validation.md) @@ -253,6 +254,7 @@ * [Using Azure Blob Storage for Media and ImageSharp Cache](extending/filesystemproviders/azure-blob-storage.md) * [Configuring Azure Key Vault](extending/key-vault.md) * [Server Events From SignalR](extending/server-events.md) +* [Sign Providers](extending/sign-providers.md) * [Packages](extending/packages/README.md) * [Creating a Package](extending/packages/creating-a-package.md) * [Language file for packages](extending/packages/language-files-for-packages.md) diff --git a/16/umbraco-cms/customizing/back-office-signs.md b/16/umbraco-cms/customizing/back-office-signs.md new file mode 100644 index 00000000000..1d7a7badb3c --- /dev/null +++ b/16/umbraco-cms/customizing/back-office-signs.md @@ -0,0 +1,23 @@ +--- +description: Describes how to use sign information provided in management API responses to present additional details to consumers. +--- + +# BackOffice Signs + +When trees, collections and items are presented in the backoffice, additional information can be displayed in the form of signs. Which signs to present will be determined by the management API response, that will be populated with a collection of `signs`. + +For example, a document scheduled for future publishing will have the following as part of the trees, collections and item response: + +```json + "signs": [ + { + "alias": "Umb.ScheduledForPublish" + } + ], +``` + +The server determines which signs are present in the response via the registered collection of [sign providers](../extending/sign-providers.md). A client-side extension point determines how each sign is displayed in the backoffice. + +## Displaying a Sign + +TBC \ No newline at end of file diff --git a/16/umbraco-cms/extending/sign-providers.md b/16/umbraco-cms/extending/sign-providers.md new file mode 100644 index 00000000000..6ee2bef6aa3 --- /dev/null +++ b/16/umbraco-cms/extending/sign-providers.md @@ -0,0 +1,87 @@ +--- +description: Describes how to use provide signs in management API responses for use in presenting additional details to consumers. +--- + +# Sign Providers + +The Umbraco management APIs for trees, collections and items include a `signs` collection for each item. These indicate additional flags of information for the item that can presented to users. + +The Umbraco backoffice will use this information to provide additional overlay icons on tree, collection and item presentations. This core behavior and extension point is described in the article on [backoffice signs](../customizing/back-office-signs.md). + +## Core Sign Providers + +Umbraco ships with four sign providers that will provide indications of the following document or media states: + +- **Is Protected** - indicates the document is not available for public access. +- **Has Pending Changes** - indicates that the document is published but has changes in draft waiting for publication +- **Has Schedule** - indicates that the document is scheduled for publishing in the future +- **Has Collection** - indicates that the document or media is based on a content type that is configured for display as a collection + +For example, an item that is scheduled for publication would contain the following in the tree, collection or item API response: + +```json + "signs": [ + { + "alias": "Umb.ScheduledForPublish" + } + ], +``` + +## Providing a Custom Sign Provider + +If your package or project needs to present additional information for a tree, collection or item value, a custom sign provider can be created. This will be coupled with a presentation extension to determine how the information is interpreted for display as a [backoffice sign](../customizing/back-office-signs.md). + +To create a sign provider, implement the `ISignProvider` interface. There are two methods to implement: + +- `CanProvideSigns` - returns `bool` indicating whether this provider can provide signs for the tree, collection or item view model. +- `PopulateSignsAsync(IEnumerable itemViewModels)` - populates the `Signs` property for the provided collection of view models. + +An illustrative implementation is as follows: + +```csharp +using Umbraco.Cms.Api.Management.ViewModels; +using Umbraco.Cms.Core; + +internal class MyDocumentSignProvider : ISignProvider +{ + private const string Alias = Constants.Conventions.Signs.Prefix + "MyDocumentSign"; + + // Indicate that this sign provider only provides signs for documents. + public bool CanProvideSigns() + where TItem : IHasSigns => + typeof(TItem) == typeof(DocumentTreeItemResponseModel) || + typeof(TItem) == typeof(DocumentCollectionResponseModel) || + typeof(TItem) == typeof(DocumentItemResponseModel); + + public Task PopulateSignsAsync(IEnumerable itemViewModels) + where TItem : IHasSigns + { + foreach (TItem item in itemViewModels) + { + if (ShouldAddSign(item)) + { + item.AddSign(Alias); + } + } + + return Task.CompletedTask; + } + + private bool ShouldAddSign(TItem item) => return true; // Provide custom logic here. +} +``` + +The sign provider needs to be registered with Umbraco in a composer or application startup with: + +```csharp + builder.SignProviders() + .Append(); +``` + +For simple signs, there may be sufficient information on the view models to map whether a sign should be created. + +For an example of this, please see the core sign provider `IsProtectedSignProvider` whose [source code can be found here](https://github.com/umbraco/Umbraco-CMS/blob/main/src/Umbraco.Cms.Api.Management/Services/Signs/IsProtectedSignProvider.cs). + +More complex signs will require additional information, using the identifiers of the view models to retrieve the necessary data. Note here that it's important to try to avoid "N+1" issues, by retrieving all the data needed to populate the signs for the whole collection in one step. + +In core, the sign provider `HasScheduleSignProvider` shows a good example of this. The [source code can be found here](https://github.com/umbraco/Umbraco-CMS/blob/main/src/Umbraco.Cms.Api.Management/Services/Signs/HasScheduleSignProvider.cs). From 65c4eb2a3165290278144f910a25e88ef2ce2044 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 20 Aug 2025 11:41:29 +0100 Subject: [PATCH 2/2] Linting --- 16/umbraco-cms/extending/sign-providers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/16/umbraco-cms/extending/sign-providers.md b/16/umbraco-cms/extending/sign-providers.md index 6ee2bef6aa3..3933c62fc3c 100644 --- a/16/umbraco-cms/extending/sign-providers.md +++ b/16/umbraco-cms/extending/sign-providers.md @@ -78,10 +78,10 @@ The sign provider needs to be registered with Umbraco in a composer or applicati .Append(); ``` -For simple signs, there may be sufficient information on the view models to map whether a sign should be created. +For some signs, there may be sufficient information on the view models to map whether a sign should be created. For an example of this, please see the core sign provider `IsProtectedSignProvider` whose [source code can be found here](https://github.com/umbraco/Umbraco-CMS/blob/main/src/Umbraco.Cms.Api.Management/Services/Signs/IsProtectedSignProvider.cs). -More complex signs will require additional information, using the identifiers of the view models to retrieve the necessary data. Note here that it's important to try to avoid "N+1" issues, by retrieving all the data needed to populate the signs for the whole collection in one step. +More complex signs will require additional information, using the identifiers of the view models to retrieve the necessary data. Note here that it's important to try to avoid "N+1" issues. The aim should be to retrieve all the data needed to populate the signs for the whole collection in one step. In core, the sign provider `HasScheduleSignProvider` shows a good example of this. The [source code can be found here](https://github.com/umbraco/Umbraco-CMS/blob/main/src/Umbraco.Cms.Api.Management/Services/Signs/HasScheduleSignProvider.cs).