Umbraco UI Builder
CMSCloudHeartcoreDXP
13.latest (LTS)
13.latest (LTS)
  • Umbraco UI Builder Documentation
  • Known Issues
  • Release Notes
  • Installation
    • Installing Umbraco UI Builder
    • Licensing
  • Upgrading
    • Upgrading Umbraco UI Builder
    • Version Specific Upgrade Notes
    • Migrate from Konstrukt to Umbraco UI Builder
  • Getting Started
    • Overview
    • Configuration
    • User Interface
  • How-to Guides
    • Creating your first integration
  • Areas
    • Overview
    • Sections
      • Summary Dashboards
    • Trees
      • Folders
    • Dashboards
    • Context Apps
  • Collections
    • Overview
    • The Basics
    • List Views
      • Field Views
    • Editors
    • Child Collections
      • Child Collection Groups
      • Retrieve Child Collections
    • Related Collections
    • Entity Identifier Converters
  • Searching
    • Overview
    • Searchable Properties
  • Filtering
    • Overview
    • Global Filters
    • Data Views
      • Data Views Builders
    • Filterable Properties
  • Actions
    • Overview
    • The Basics
    • Action Visibility
    • Inbuilt Actions
  • Cards
    • Overview
    • Count Cards
    • Custom Cards
  • Property Editors
    • Overview
    • Entity Picker
  • Advanced
    • Virtual Sub Trees
    • Encrypted Properties
    • Value Mappers
    • Repositories
    • Events
  • Miscellaneous
    • Conventions
    • Umbraco Aliases
Powered by GitBook
On this page
  • Defining virtual SubTrees
  • AddVirtualSubTree(string sectionAlias, string treeAlias, Lambda visibilityExpression, Lambda virtualSubTreeConfig = null) : VirtualSubTreeConfigBuilder
  • AddVirtualSubTreeBefore(string sectionAlias, string treeAlias, Lambda visibilityExpression, Lambda matchExpression, Lambda virtualSubTreeConfig = null) : VirtualSubTreeConfigBuilder
  • AddVirtualSubTreeAfter(string sectionAlias, string treeAlias, Lambda visibilityExpression, Lambda matchExpression, Lambda virtualSubTreeConfig = null) : VirtualSubTreeConfigBuilder
  • Controlling where to inject the Virtual SubTrees
  • Controlling the position of the injected Virtual SubTrees
  • Configuring a Virtual SubTrees
  • Injecting Virtual SubTrees into 3rd party trees
Edit on GitHub
Export as PDF
  1. Advanced

Virtual Sub Trees

Configuring virtual sub trees in Umbraco UI Builder, the backoffice UI builder for Umbraco.

PreviousEntity PickerNextEncrypted Properties

Last updated 1 year ago

Virtual subtrees are a powerful feature that allows you to inject an Umbraco UI Builder tree structure into another Umbraco tree at a desired location. Thus acting as child nodes to the node chosen as the injection point. With virtual subtrees it allows you to extend built in or even 3rd party package trees with additional features. An example could be developing a "loyalty point" program for your e-commerce site and injecting the related database tables into a Vendr store tree. This allows the management of the program in its most logical location.

Defining virtual SubTrees

AddVirtualSubTree(string sectionAlias, string treeAlias, Lambda visibilityExpression, Lambda virtualSubTreeConfig = null) : VirtualSubTreeConfigBuilder

Adds a virtual subtree to the current tree with its visibility controlled via the visibility expression.

// Example
withTreeConfig.AddVirtualSubTree(ctx => ctx.Source.Id == 1056, contextAppConfig => {
    ...
});

AddVirtualSubTreeBefore(string sectionAlias, string treeAlias, Lambda visibilityExpression, Lambda matchExpression, Lambda virtualSubTreeConfig = null) : VirtualSubTreeConfigBuilder

Adds a virtual subtree to the current tree, before the tree node matches the match expression, with its visibility controlled via the visibility expression.

// Example
withTreeConfig.AddVirtualSubTreeBefore(ctx => ctx.Source.Id == 1056, treeNode => treeNode.Name == "Settings", contextAppConfig => {
    ...
});

AddVirtualSubTreeAfter(string sectionAlias, string treeAlias, Lambda visibilityExpression, Lambda matchExpression, Lambda virtualSubTreeConfig = null) : VirtualSubTreeConfigBuilder

Adds a virtual subtree to the current tree, after the tree node matches the match expression, with its visibility controlled via the visibility expression.

// Example
withTreeConfig.AddVirtualSubTreeAfter(ctx => ctx.Source.Id == 1056, treeNode => treeNode.Name == "Settings", contextAppConfig => {
    ...
});

Controlling where to inject the Virtual SubTrees

Controlling where a virtual subtree is injected is done via the visibility expression passed to one of the AddVirtualSubTree methods on the root UIBuilderConfigBuilder instance. Without a visibility expression, Umbraco UI Builder would inject the virtual subtree under every node in the given tree. This expression can be used to identify the exact location where our tree should go.

To help with this, the visibility expression is passed a single VirtualSubTreeFilterContext argument with relevant contextual information. This information is about the current node being rendered, alongside a list of the current user's user groups for permission-based visibility control. It also includes access to an IServiceProvider in case you need to resolve a service to determine the correct node to inject below.

public class VirtualSubTreeFilterContext
{
    public NodeContext Source { get; }
    public IEnumerable<IReadOnlyUserGroup> UserGroups { get; }
    public IServiceProvider ServiceProvider { get; }
}

public class NodeContext
{
    public string Id { get; }
    public string TreeAlias { get; }
    public string SectionAlias { get; }
    public FormCollection QueryString { get; }
}

Below you can find an example of a more complex filter expression where injection is based on the Document Type of a content node:

withTreeConfig.AddVirtualSubTree(ctx => 
    {
        using var umbracoContextRef = ctx.ServiceProvider.GetRequiredService<IUmbracoContextFactory>().EnsureUmbracoContext();
        
        if (!int.TryParse(ctx.Source.Id, out int id)) 
            return false;

        return (umbracoContextRef.UmbracoContext.Content.GetById(id)?.ContentType.Alias ?? "") == "textPage";
    }, 
    virtualNodeConfig => virtualNodeConfig
        ...
);

Controlling the position of the injected Virtual SubTrees

The position of a virtual subtree within the child nodes of the injection node is controlled by using one of the AddVirtualSubTreeBefore or AddVirtualSubTreeAfter methods. These methods need to be on the root level UIBuilderConfigBuilder instance and pass a match expression used to identify the tree node to insert before/after. This expression is passed a single TreeNode argument to determine the position. It also requires a boolean return value to indicate the relevant location has been found.

public class TreeNode
{
    public object Id { get; }
    public object ParentId { get; }
    public string Alias { get; }
    public string Name { get; }
    public string NodeType { get; }
    public string Path { get; }
    public string RoutePath { get; }
    public IDictionary<string, object> AdditionalData { get; }
    ...
}

Below you can find an example of positioning a subtree after a node with the alias "settings":

treeNode => treeNode.alias == "settings"

Configuring a Virtual SubTrees

Injecting Virtual SubTrees into 3rd party trees

public interface ITreeHelper
{
    string TreeAlias { get; }
    string GetUniqueId(string nodeId, FormCollection queryString);
    object GetEntityId(string uniqueId);
    string GetPath(string uniqueId);
}

Once you have defined a tree helper, you can register the DI container in your startup class.

builder.Services.AddSingleton<ITreeHelper, MyCustomTreeHelper>();

Once registered any virtual subtrees registered against the given helpers tree alias will then use your tree helper to locate the required information.

You define a virtual subtree by calling one of the AddVirtualSubTree methods of a instance.

Virtual subtrees share the same API as the Tree config builder API including support for folders and collections. There is an exception when adding collections to a subtree where you will have an additional foreign key expression parameter to define. The foreign key expression links the entities of the collection to the parent node of the subtree. For more information check the .

Out of the box, Umbraco UI Builder supports injecting subtrees into the core content, media, members, and member group trees. It also includes 3rd party support for settings and commerce trees. In order to support additional trees to inject into, you must implement an ITreeHelper which is used to extract the required information. The tree helper consists of a tree alias for which the tree helper is. It includes methods to correctly identify the full parent path, a unique ID for a given node ID, and to resolve the actual entity ID. The entity ID should be used for the foreign key collection values.

Core Trees Documentation
Umbraco Commerce
Example virtual sub tree injected into a Vendr store tree
WithTreeConfigBuilder