How To Display An MVC View In The Umbraco Backend

It is a fairly common requirement on a project to extend the Umbraco backend and display one or more custom pages.  You may need to implement a custom content approval page, you might be trying to create a custom pack, a URL rewrite page, etc.. the list can go on and on.

When it comes to Umbraco 7+ you have two options when it comes to displaying a custom page within the Umbraco backend.  The new approach is to use angular and HTML to render your page, however, if you're like me, it's often quicker and easier to use a simple MVC controller and view.  In today's guide, I'm going to cover everything you need to make that happen.  

Overview

Displaying a custom MVC view into Umbraco, unfortunately, is not as straightforward as you would first imagine.  To display the page you will need to decide the section and the tree where you want the view to appear in Umbraco.  This can be either a new custom section you define yourself (in code or by config) or one of the defaults Umbraco ones. The second part is a 'tree', which is basically a link within the section that will open up your view. If you're struggling to get your head around the difference between a section and a tree then, hopefully, the diagram below will help:

 

The section is the item that appears in the back menu area within Umbraco.  The tree is the thing on the right.

How To Create A Section

The first thing you will need to do is decide where you want your pages to live.  You can either choose to create a new section within Umbraco (read this guide to find out how), or you can hook into one of the existing Umbraco sections, like 'Settings', or 'Content'.

A quick re-cap of the code required to create a section is shown below:

    [Application("customSection", "Custom Section", "icon-people", 15)]
    public class CustomSection : umbraco.interfaces.IApplication
    {
    }

If you want to use a default Umbraco section you can open 'Config' -> 'applications.config' within your website's webroot, as seen below:

Make a note of the alias as you'll need to use this within your 'tree'.

How To Create A Tree

Next, we will define the code required to create a tree within Umbraco.  The tree will be the right-hand menu displayed with a section, that we will use to open up your MVC view.  The complete code looks like this:

 

    [Tree("customSection", "contentTree", "Content Admin Tools")]
    public class ContentTree : BaseTree
    {
        public ContentTree(string application)
            : base(application)
        {
        }

        protected override void CreateRootNode(ref XmlTreeNode rootNode)
        {
            rootNode.NodeType = "home";
            rootNode.NodeID = "init";
            rootNode.Menu = new List { ActionRefresh.Instance };
        }

        public override void Render(ref XmlTree tree)
        {
            var contentNode = XmlTreeNode.Create(this);
            contentNode.NodeID = "1";
            contentNode.NodeType = string.Empty;
            contentNode.Text = "Name Of Link";
            contentNode.Action = "#";
            contentNode.Action = "javascript:openPage('/umbraco/backoffice/Plugins/admin/index');";
            contentNode.Icon = "../../../App_Plugins/sass-icon-grey.png";
            contentNode.HasChildren = false;
            contentNode.Menu = new List();
            OnBeforeNodeRender(ref tree, ref contentNode, EventArgs.Empty);
            tree.Add(contentNode);
            OnAfterNodeRender(ref tree, ref contentNode, EventArgs.Empty);
        }

        public override void RenderJS(ref StringBuilder Javascript)
        {
            var js = $"function openPage(url){{UmbClientMgr.contentFrame(url);}}";
            Javascript.Append(js);
        }

First, let's break this code down so you can understand what's going on.  The class needs to inherit from 'umbraco.cms.presentation.Trees.BaseTree'. The class will also need to be decorated with the 'tree' attribute in order for you to define where in the Umbraco back-end your view will be displayed.

[Tree("customSection", "contentTree", "Content Admin Tools")]

The first parameter in the tree attribute 'customSection' is the alias of the section, where you want the tree to live.  Be careful when adding this alias as it needs to exactly match the section name (it will probably need to start with a lowercase letter)  If you want to use a default Umbraco section, their alias names can be found following the advice above.  If you have created a custom section, then you will have defined this yourself and you will need to use that.  

The second parameter is the tree content. Tree is probably the least important parameter.  This just defines the name of your section.  In this tutorial, this value won't be displayed or used anywhere else, so you can call it whatever you want.  The last parameter 'Content Admin Tools' is the name that will be shown within Umbraco.  

Now you have defined all the parameters within the tree attribute, the next step is to create a node within the tree that will link to your view.  In this example, I'm only creating one node, but you can create as many as you want. Before you can create a node, you will also need to define a root node.  As you can see from the code, you will need to override two methods from the base class. One that creates the top-level root node:

        protected override void CreateRootNode(ref XmlTreeNode rootNode)
        {
            rootNode.NodeType = "example";
            rootNode.NodeID = "init";
            rootNode.Menu = new List { ActionRefresh.Instance };
        }

The other method is the place where you need to define the node that will link to your controller/view:

        public override void Render(ref XmlTree tree)
        {
            var contentNode = XmlTreeNode.Create(this);
            contentNode.NodeID = "1";
            contentNode.NodeType = string.Empty;
            contentNode.Text = "Name Of Link";
            contentNode.Action = "javascript:openPage('/umbraco/backoffice/Plugins/AdminTask/index');";
            contentNode.Icon = "../../../App_Plugins/icon.png";
            contentNode.HasChildren = false;
            contentNode.Menu = new List();
            OnBeforeNodeRender(ref tree, ref contentNode, EventArgs.Empty);
            tree.Add(contentNode);
            OnAfterNodeRender(ref tree, ref contentNode, EventArgs.Empty);
        }
        

I'll quickly talk you through the interesting bits of the code,  Node Id, sets the sort order, e.g. the order the node will be displayed in the list.  The text is the name of the link that will be displayed within Umbraco.   The action is the link that will call the view.  To make Umbraco call a controller/view we use some Javascript to open it.  

I should also state now, that to work with a custom view within Umbraco backend, it has to be accessible using this route 'umbraco/backoffice/plugin/'.  If you don't do this, you will get permission errors.  

Route Config

When we work with a normal MVC view and controller within Umbraco, whether it be front-end, or backend, we need to create an entry for it within your website's route config.  As mentioned above, your route config needs to include 'Umbraco/back office/Plugins/' within its Url, otherwise you will run into issues.  This bit confused a lot of people, so don't say I didn't warn you.  An example route can look like this:

  RouteTable.Routes.MapRoute(
               "AdminDefaul",
               "umbraco/backoffice/Plugins/AdminTask/{action}/{id}",
               new
               {
                   controller = "MyController",
                   action = "index",
                   id = UrlParameter.Optional
               });

 

MVC Controller

The last bit of the puzzle is the standard MVC stuff.  The controller code looks like this:

    public class MyController : UmbracoAuthorizedController
    {
        public ActionResult Index()
        {
            return View();
        }
    }

The only difference in this controller code compared to a standard MVC one is that you inherit from 'UmbracoAuthorizedController'.  This will ensure that only authorized people who have signed into Umbraco can access your admin pages.  After this, your view and view model will then act and behave the same as normal MVC.

Conclusion

That's it.. you now have all the code you need to display a custom controller/view within the Umbraco backend, enjoy!

 

submit to reddit

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top