XperienceCommunity.WorkspaceRestrictions 2.1.0

dotnet add package XperienceCommunity.WorkspaceRestrictions --version 2.1.0
                    
NuGet\Install-Package XperienceCommunity.WorkspaceRestrictions -Version 2.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="XperienceCommunity.WorkspaceRestrictions" Version="2.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="XperienceCommunity.WorkspaceRestrictions" Version="2.1.0" />
                    
Directory.Packages.props
<PackageReference Include="XperienceCommunity.WorkspaceRestrictions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add XperienceCommunity.WorkspaceRestrictions --version 2.1.0
                    
#r "nuget: XperienceCommunity.WorkspaceRestrictions, 2.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package XperienceCommunity.WorkspaceRestrictions@2.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=XperienceCommunity.WorkspaceRestrictions&version=2.1.0
                    
Install as a Cake Addin
#tool nuget:?package=XperienceCommunity.WorkspaceRestrictions&version=2.1.0
                    
Install as a Cake Tool

Xperience Community: Workspace Restrictions

NuGet Downloads License CI GitHub stars

Description

Restricts which reusable content types are available when creating content items in a workspace or one of its folders in Xperience by Kentico.

  • Allow list: Only the listed content types appear in the "Create content item" dialog for the workspace.
  • Exclude list: All content types except the listed ones appear in the "Create content item" dialog for the workspace.
  • Folder scopes: Further restrict the content types available in a selected folder using its own allow or exclude list, optionally applying the scope to all nested folders. The available choices are limited to content types permitted by the parent workspace. See Folder Scopes.

The allow list takes precedence over the exclude list. If any allowed content types are configured, the exclude list is ignored for that workspace.

Screenshots

The Allowed content types tab on a workspace builds an allow list:

Allowed content types tab on a workspace in Xperience by Kentico

The Excluded content types tab builds an exclude list:

Excluded content types tab on a workspace in Xperience by Kentico

When an editor creates a content item, the workspace configuration filters the content type picker:

Filtered content type picker when creating a content item in Xperience by Kentico

When an editor moves content items in the Content hub, the package blocks the move if the target workspace or folder doesn't allow an item's content type. A move of several items is all or nothing: if one item isn't allowed, none of them move. The editor sees "The item couldn't be moved. The target workspace or folder might not allow its content type", and the event log names the content types that aren't allowed.

Xperience shows the same message for every failed move, so the package can't name the content type in it. Instead, the package replaces the default English text of Xperience's two move error messages, contenthub.contentitem.movetofolder.error and contenthub.contentitems.movetofolder.error, so they mention restrictions. The new text says "might" because the same message appears when a move fails for another reason. Other admin UI languages keep Xperience's translation. If your project already replaces these strings, check which text the administration shows.

The move check runs only during web requests, such as the administration and the Management API. It doesn't run during CI/CD restore, the migration tool or other processes without a request. Deleting a folder, which moves its items to the workspace root, isn't blocked.

The Create new button of a content item selector, for example in a widget or a content item field, doesn't apply restrictions. Xperience creates the new item in the workspace root and then moves it into the chosen folder, in the same request. The move check skips items created during the request, so it doesn't block that move and leave the new item in the root. Issue #2 tracks restricting this dialog.

Library Version Matrix

Xperience Version Library Version
>= 31.9.3 2.x
>= 31.2.1 1.0.0

Dependencies

Package Installation

Add the package to your Xperience by Kentico admin project using the .NET CLI:

dotnet add package XperienceCommunity.WorkspaceRestrictions

Quick Start

  1. Install the NuGet package above. No service registration is required. The package installs its database tables when the application starts.

  2. In the Xperience administration, go to Content hub → Configuration → Workspaces and open the workspace you want to restrict.

  3. Use the Allowed content types tab to build an allow list, or the Excluded content types tab to build an exclude list.

  4. That's it. Changes take effect immediately, without a restart. Create a content item in the workspace to see the filtered content type picker.

Folder Scopes

  1. Open the workspace's Folder scopes tab.
  2. Select New folder scope, choose a folder in that workspace, optionally enable Apply to child folders, and save.
  3. Configure the scope's Allowed content types or Excluded content types tab, using the same controls as workspace restrictions.
  4. Create a content item from that folder in the Content hub to see the filtered content type picker.

The Folder scopes tab lists the scopes in the workspace:

Folder scopes tab on a workspace in Xperience by Kentico

The scope's Settings page sets its folder and whether it applies to child folders:

Settings page of a folder scope in Xperience by Kentico

In this example, the workspace excludes Cafe and Contact. The /Coffee scope excludes Event and applies to child folders. The /Coffee/Brazil scope allows Event, Image and Testimonial. The picker for /Coffee/Brazil offers only Image and Testimonial, because the parent scope blocks Event:

Content type picker filtered by folder scopes in Xperience by Kentico

Each folder can have one scope. Apply to child folders is off by default, including for existing scopes after upgrading. When enabled, the scope also applies to all descendants, including folders created later. A folder without its own scope still receives any applicable ancestor scopes; if none apply, it uses the workspace restrictions alone.

The database enforces one scope per workspace/folder, including when users save concurrently. If an older preview contains duplicate scopes, reconcile them before upgrading; installation does not automatically delete or merge conflicting rules.

To edit an existing scope, open it from the listing. It opens on Settings, the first item in the scope navigation, followed by Allowed content types and Excluded content types. Change Folder to another folder in the same workspace or toggle Apply to child folders, then save. Changing the folder preserves the scope's allowed and excluded content type selections. A folder that already has another scope cannot be selected as the destination.

The workspace rules, every applicable ancestor scope, and the folder's own scope are combined. A content type must be permitted by all of them. Within each scope, a non-empty allow list takes precedence over that scope's exclude list. Empty lists add no restrictions. A child scope cannot restore a type blocked by an ancestor, and leaving its Apply to child folders setting off does not stop inheritance from higher ancestors. For example, if a workspace allows Article, Image, and Video, a parent scope can exclude Video for its whole subtree, and a child scope can narrow the choices further to Image.

A folder scope cannot make a workspace-disallowed type available. Changes to workspace restrictions take effect immediately, including for existing scopes. Previously selected types remain visible in the scope's existing bindings so they can be removed, but unavailable types cannot be added. If none of a folder's allowed types remain permitted by the workspace, the picker offers no types.

Delete a scope from the Folder scopes tab to remove its restrictions from the folder and any affected descendants; workspace rules and other applicable scopes remain in effect. Scopes reference folder IDs, so renaming a folder keeps its configuration. Moving a folder changes which ancestor scopes it inherits. Folder scopes apply to ordinary content folders, not smart folders or the All content items view.

Like workspace restrictions, folder scopes filter the administration's content creation picker and block moves into the folder. They don't check content items that are created or imported through the API.

Running the Example Project

The repository includes a Dancing Goat sample site in examples/DancingGoat, generated from the Xperience by Kentico 31.9.3 template. It references the library project, so the module installs when the site starts. To run it locally:

  1. Create the database from the examples/DancingGoat folder. This uses the database manager version pinned in the project's tool manifest, so the schema and sample data match the Xperience version used by the example:

    cd examples/DancingGoat
    dotnet tool restore
    dotnet kentico-xperience-dbmanager -- -s "(localdb)\MSSQLLocalDB" -d "WorkspaceRestrictions-DancingGoat" -a "<admin password>" --hash-string-salt "d52e99dd-0eb1-4ae0-8e67-884901247292" --sample-website-domain "localhost:46629" --license-file "<path to license file>"
    

    The connection string in appsettings.json uses SQL Server LocalDB. Change it if you use a different SQL Server instance. A license key valid for localhost is required for the site to render.

  2. Run the site:

    dotnet run --project examples/DancingGoat/DancingGoat.csproj
    
  3. Sign in to the administration at http://localhost:46629/admin as administrator, and configure a workspace under Content hub → Configuration → Workspaces.

Running the Tests

Run the xUnit tests from the repository root:

dotnet test --configuration Release

The SQL Server integration tests in tests/FolderScopeDatabaseTests.cs are skipped unless the WORKSPACE_RESTRICTIONS_TEST_CONNECTION_STRING environment variable is set. They test the unique index that the installer creates, and saves that happen at the same time. Point the variable at a database where the account can create and drop tables. Each test creates a table with a unique name and drops it afterwards. For example, with SQL Server LocalDB:

$env:WORKSPACE_RESTRICTIONS_TEST_CONNECTION_STRING = 'Server=(localdb)\MSSQLLocalDB;Database=tempdb;Integrated Security=true;TrustServerCertificate=true'
dotnet test --configuration Release

Contributing

Feel free to submit issues or pull requests to the repository, this is a community package and everyone is welcome to support.

License

Distributed under the MIT License. See LICENSE.md for more information.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.0 50 11/5/2026
2.0.0 55 11/4/2026
1.0.0 2,593 3/4/2026
0.1.0-preview.1 90 3/4/2026