How to render the actual document type icons in the tree in Umbraco

Posted written by Paul Seal on December 18, 2019 Umbraco

In the Settings section of Umbraco, in the Document Types tree, we see all document types with the exact same default icon like this.

1

As a developer / architect of an umbraco site it would be so useful to be able to see which icons and colours have been chosen for a document type at the tree level. It would save us clicking through to each document type to see which icon has been chosen for it. Also it would give continuity to what we have with the content type picker, showing the icon and colour.

2

I've also managed to get it to work with the member types in v7 and v8, and the media types in v8.

3

I have submitted a Pull Request to get this added to Umbraco, but in the mean time, if you want to do this on any sites now, here is the code you need to do it. Just create a class in your project like this:

In Umbraco v8

using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Services;
using Umbraco.Web.Trees;

namespace CodeShare.Core.Composing
{
    [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
    public class TreeNodeRenderingComposer : ComponentComposer<TreeNodeRenderingComponent>, IUserComposer
    { }

    public class TreeNodeRenderingComponent : IComponent
    {
        private readonly IContentTypeService _contentTypeService;
        private readonly IMediaTypeService _mediaTypeService;
        private readonly IMemberTypeService _memberTypeService;

        public TreeNodeRenderingComponent(IContentTypeService contentTypeService, 
            IMediaTypeService mediaTypeService, IMemberTypeService memberTypeService)
        {
            _contentTypeService = contentTypeService;
            _mediaTypeService = mediaTypeService;
            _memberTypeService = memberTypeService;
        }

        public void Initialize()
        {
            TreeControllerBase.TreeNodesRendering += TreeControllerBase_TreeNodesRendering;
        }

        public void Terminate()
        { }

        /// <summary>
        /// Checks the tree alias and node alias to see if we should update the icon
        /// Gets the types from the type services and calls the method to update the node icons
        /// </summary>
        /// <param name="sender">Tree controller base</param>
        /// <param name="e">Event args</param>
        private void TreeControllerBase_TreeNodesRendering(TreeControllerBase sender, TreeNodesRenderingEventArgs e)
        {
            switch (sender.TreeAlias)
            {
                case "documentTypes":
                    var contentTypeIcons = _contentTypeService.GetAll().ToDictionary(c => c.Id, c => c.Icon);
                    UpdateNodeIcons(e, contentTypeIcons, "documentTypes");
                    break;
                case "memberTypes":
                    var memberTypeIcons = _memberTypeService.GetAll().ToDictionary(c => c.Id, c => c.Icon);
                    UpdateNodeIcons(e, memberTypeIcons, "memberTypes");
                    break;
                case "mediaTypes":
                    var mediaTypeIcons = _mediaTypeService.GetAll().ToDictionary(c => c.Id, c => c.Icon);
                    UpdateNodeIcons(e, mediaTypeIcons, "mediaTypes");
                    break;
                default:
                    // don't change the icon
                    break;
            }
        }

        /// <summary>
        /// Loops through the nodes and updates the icon to the one from the type service
        /// </summary>
        /// <param name="e">Event args</param>
        /// <param name="nodeIcons">Dictionary of node icons</param>
        /// <param name="nodeTypeAlias">The node type alias we are interested in</param>
        private static void UpdateNodeIcons(TreeNodesRenderingEventArgs e, Dictionary<int,string> nodeIcons, string nodeTypeAlias)
        {
            foreach (var node in e.Nodes)
            {
                if (node.NodeType == nodeTypeAlias)
                {
                    if (int.TryParse(node.Id.ToString(), out var nodeId) &amp;&amp; nodeId > 0)
                    {
                        node.Icon = nodeIcons[nodeId];
                    }
                }
            }
        }
    }
}

In Umbraco v7

using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Web.Trees;

namespace CodeShare.Library.EventHandlers
{
    public class TreeNodeRenderingEventHandler : ApplicationEventHandler
    {
        protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            TreeControllerBase.TreeNodesRendering += TreeControllerBase_TreeNodesRendering;
        }

        /// <summary>
        /// Checks the tree alias and node alias to see if we should update the icon
        /// Gets the types from the type services and calls the method to update the node icons
        /// </summary>
        /// <param name="sender">Tree controller base</param>
        /// <param name="e">Event args</param>
        private void TreeControllerBase_TreeNodesRendering(TreeControllerBase sender, TreeNodesRenderingEventArgs e)
        {
            switch (sender.TreeAlias)
            {
                case "documentTypes":
                    var contentTypeService = ApplicationContext.Current.Services.ContentTypeService;
                    var contentTypeIcons = contentTypeService.GetAllContentTypes().ToDictionary(c => c.Id, c => c.Icon);
                    UpdateNodeIcons(e, contentTypeIcons, "documentTypes");
                    break;
                case "memberTypes":
                    var memberTypeService = ApplicationContext.Current.Services.MemberTypeService;
                    var memberTypeIcons = memberTypeService.GetAll().ToDictionary(c => c.Id, c => c.Icon);
                    UpdateNodeIcons(e, memberTypeIcons, "memberTypes");
                    break;
                default:
                    // don't change the icon
                    break;
            }
        }

        /// <summary>
        /// Loops through the nodes and updates the icon to the one from the type service
        /// </summary>
        /// <param name="e">Event args</param>
        /// <param name="nodeIcons">Dictionary of node icons</param>
        /// <param name="nodeTypeAlias">The node type alias we are interested in</param>
        private static void UpdateNodeIcons(TreeNodesRenderingEventArgs e, Dictionary<int, string> nodeIcons, string nodeTypeAlias)
        {
            foreach (var node in e.Nodes)
            {
                if (node.NodeType == nodeTypeAlias)
                {
                    if (int.TryParse(node.Id.ToString(), out var nodeId) &amp;&amp; nodeId > 0)
                    {
                        node.Icon = nodeIcons[nodeId];
                    }
                }
            }
        }
    }
}

Now you should be able to see the icons you have set from the Document Types tree view.