Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Umbraco 15.2 release documentation updates #6808

Merged
merged 11 commits into from
Feb 6, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,6 @@ description: Example of how to use a SendingAllowedChildren Notification

# Sending Allowed Children Notification

The `SendingAllowedChildrenNotification` enables you to manipulate the Document Types that will be shown in the create menu when adding new content in the backoffice.
The `SendingAllowedChildrenNotification` is no longer available in Umbraco 14 and no replacement is available for this major version.

## Usage

With the example below we can ensure that a Document Type cannot be selected if the type already exists in the Content tree.

```csharp
using System.Web;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;

namespace Umbraco.Docs.Samples.Web.Notifications;

public class SendingAllowedChildrenNotificationHandler : INotificationHandler<SendingAllowedChildrenNotification>
{
public void Handle(SendingAllowedChildrenNotification notification)
{
const string contentIdKey = "contentId";

// Try get the id from the content item in the backoffice
var queryStringCollection = HttpUtility.ParseQueryString(notification.UmbracoContext.OriginalRequestUrl.Query);

if (!queryStringCollection.ContainsKey(contentIdKey))
{
return;
}

var contentId = queryStringCollection[contentIdKey].TryConvertTo<int>().ResultOr(-1);

if (contentId == -1)
{
return;
}

var content = notification.UmbracoContext.Content?.GetById(true, contentId);

if (content is null)
{
return;
}

// Allowed children as configured in the backoffice
var allowedChildren = notification.Children.ToList();

if (content.ChildrenForAllCultures is not null)
{
// Get all children of current page
var childNodes = content.ChildrenForAllCultures.ToList();

// If there is a Settings page already created, then don't allow it anymore
// You can also use the ModelTypeAlias property from your PublishedModel for comparison,
// like Settings.ModelTypeAlias if you have set models builder to generate SourceCode models
if (childNodes.Any(x => x.ContentType.Alias == "settings"))
{
allowedChildren.RemoveAll(x => x.Alias == "settings");
}
}

// Update the allowed children
notification.Children = allowedChildren;
}
}
```

You also need to register this notification handler. You can achieve this by updating the `Program` class like:

```csharp
builder.CreateUmbracoBuilder()
.AddBackOffice()
.AddWebsite()
.AddDeliveryApi()
.AddComposers()
.AddNotificationHandler<SendingAllowedChildrenNotification, SendingAllowedChildrenNotificationHandler>()
.Build();
```

{% hint style="info" %}
For more information about registering notifications read the [Registering notification handlers](./) article.
{% endhint %}
Please see [content type filters](../../../../15/umbraco-cms/reference/content-type-filters.md) as the supported alternative in Umbraco 15 for use cases that previously relied on this notification.
1 change: 1 addition & 0 deletions 15/umbraco-cms/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@
* [Setup OAuth using Postman](reference/management-api/postman-setup-swagger.md)
* [Custom Swagger API](reference/custom-swagger-api.md)
* [Umbraco Flavored Markdown](reference/umbraco-flavored-markdown.md)
* [Content Type Filters](reference/content-type-filters.md)

## Tutorials

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ The following conditions are available out of the box, for all extension types t
* `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'.
* `Umb.Condition.CurrentUser.IsAdmin` - Requires the current user to be an admin as defined by the backend, such as belonging to the Administrator group.
* `Umb.Condition.CurrentUser.GroupId` - Requires the current user to belong to a specific group by GUID. Accepts `match` (GUID), `oneOf` (array), `allOf` (array), and `noneOf` (array). Example: '8d2b3c4d-4f1f-4b1f-8e3d-4a6b7b8c4f1e'.
* `Umb.Condition.CurrentUser.IsAdmin` - Requires the current user to be an admin as defined by the backend, for example, that they belong to the Administrator group.

## Condition Configuration

Expand Down
10 changes: 10 additions & 0 deletions 15/umbraco-cms/reference/configuration/contentsettings.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ The following snippet will give an overview of the keys and values in the conten
"DisallowedUploadFiles": ["ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd", "xamlx"],
"DisallowedUploadedFileExtensions": ["ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd", "xamlx"],
"Error404Collection": [],
"BackOfficeLogo": "../media/qyci4xti/logo.png",
"HideBackOfficeLogo": false,
"Imaging": {
"ImageFileTypes": ["jpeg", "jpg", "gif", "bmp", "png", "tiff", "tif"],
"AutoFillImageProperties": [
Expand Down Expand Up @@ -127,6 +129,14 @@ If you have multiple sites, with different cultures, setup in your tree then you

If you have more than two sites and forget to add a 404 page and a culture, the default page will act as fallback. Same happens if you for some reason forget to define a hostname on a site.

### Backoffice logo

This setting can be used to set a custom image path to replace the Umbraco logo in the backoffice.

### Hide backoffice logo

This setting can be used to hide the Umbraco logo in backoffice.

### Login background image

You can specify your own background image for the login screen here. The image will automatically get an overlay to match backoffice colors. This path is relative to the `wwwroot/umbraco` path. The default location is: `wwwroot/umbraco/login/login.jpg`.
Expand Down
78 changes: 78 additions & 0 deletions 15/umbraco-cms/reference/content-type-filters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
description: Describes how to use Content Type Filters to restrict the allowed content options available to editors.
---

# Filtering Allowed Content Types

When content editors add new content they are presented with a dialog where they must select the type of content they want to create. The options available are defined when setting up the Document, Media, and Member types in the **Settings** section.

Implementors and package creators can add additional logic to determine which options are available to the editors.

This is possible using Content Type Filters.

{% hint style="info" %}
The use cases supported here are similar to those where the `SendingAllowedChildrenNotification` would be used in Umbraco 13 or earlier.
{% endhint %}

## Implementing a Content Type Filter

To create a Content Type Filter you use a class that implements the `IContentTypeFilter` interface (found in the `Umbraco.Cms.Core.Services.Filters` namespace).

There are two methods you can implement:

* One for filtering the content types allowed at the content root
* One for the content types allowed below a given parent node.

If you don't want to filter using one of the two approaches, you can return the provided collection unmodified.

### Example Use Case

The following example shows a typical use case. Often websites will have a "Home Page" Document Type which is created at the root. Normally, only one of these is required. You can enforce that using the following Content Type Filter.

The code below is querying the existing content available at the root. Normally you can create a "Home Page" here, but if one already exists that option is removed:

```csharp
internal class OneHomePageOnlyContentTypeFilter : IContentTypeFilter
{
private readonly IContentService _contentService;

public OneHomePageOnlyContentTypeFilter(IContentService contentService) => _contentService = contentService;

public Task<IEnumerable<TItem>> FilterAllowedAtRootAsync<TItem>(IEnumerable<TItem> contentTypes)
where TItem : IContentTypeComposition
{
var docTypeAliasesToExclude = new List<string>();

const string HomePageDocTypeAlias = "homePage";
var docTypeAliasesAtRoot = _contentService.GetRootContent()
.Select(x => x.ContentType.Alias)
.Distinct()
.ToList();
if (docTypeAliasesAtRoot.Contains(HomePageDocTypeAlias))
{
docTypeAliasesToExclude.Add(HomePageDocTypeAlias);
}

return Task.FromResult(contentTypes
.Where(x => docTypeAliasesToExclude.Contains(x.Alias) is false));
}

public Task<IEnumerable<ContentTypeSort>> FilterAllowedChildrenAsync(IEnumerable<ContentTypeSort> contentTypes, Guid parentKey)
=> Task.FromResult(contentTypes);
}
```

Content Type Filters are registered as a collection, making it possible to have more than one in the solution or an installed package.

The filters need to be registered in a composer:

```csharp
public class MyComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.ContentTypeFilters()
.Append<OneHomePageOnlyContentTypeFilter>();
}
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,6 @@ description: Example of how to use a SendingAllowedChildren Notification

# Sending Allowed Children Notification

The `SendingAllowedChildrenNotification` enables you to manipulate the Document Types that will be shown in the create menu when adding new content in the backoffice.
The `SendingAllowedChildrenNotification` is no longer available in Umbraco 15.
AndyButland marked this conversation as resolved.
Show resolved Hide resolved

## Usage

With the example below we can ensure that a Document Type cannot be selected if the type already exists in the Content tree.

```csharp
using System.Web;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;

namespace Umbraco.Docs.Samples.Web.Notifications;

public class SendingAllowedChildrenNotificationHandler : INotificationHandler<SendingAllowedChildrenNotification>
{
public void Handle(SendingAllowedChildrenNotification notification)
{
const string contentIdKey = "contentId";

// Try get the id from the content item in the backoffice
var queryStringCollection = HttpUtility.ParseQueryString(notification.UmbracoContext.OriginalRequestUrl.Query);

if (!queryStringCollection.ContainsKey(contentIdKey))
{
return;
}

var contentId = queryStringCollection[contentIdKey].TryConvertTo<int>().ResultOr(-1);

if (contentId == -1)
{
return;
}

var content = notification.UmbracoContext.Content?.GetById(true, contentId);

if (content is null)
{
return;
}

// Allowed children as configured in the backoffice
var allowedChildren = notification.Children.ToList();

if (content.ChildrenForAllCultures is not null)
{
// Get all children of current page
var childNodes = content.ChildrenForAllCultures.ToList();

// If there is a Settings page already created, then don't allow it anymore
// You can also use the ModelTypeAlias property from your PublishedModel for comparison,
// like Settings.ModelTypeAlias if you have set models builder to generate SourceCode models
if (childNodes.Any(x => x.ContentType.Alias == "settings"))
{
allowedChildren.RemoveAll(x => x.Alias == "settings");
}
}

// Update the allowed children
notification.Children = allowedChildren;
}
}
```

You also need to register this notification handler. You can achieve this by updating the `Program` class like:

```csharp
builder.CreateUmbracoBuilder()
.AddBackOffice()
.AddWebsite()
.AddDeliveryApi()
.AddComposers()
.AddNotificationHandler<SendingAllowedChildrenNotification, SendingAllowedChildrenNotificationHandler>()
.Build();
```

{% hint style="info" %}
For more information about registering notifications read the [Registering notification handlers](./) article.
{% endhint %}
Please see [content type filters](../content-type-filters.md) as the supported alternative for use cases that previously relied on this notification.