This is the third blog post in a series of posts relating to building plugins for Umbraco v5 (Jupiter).  This post will show you how to get started with building a tree. A more in-depth example including rendering out child nodes, using many of the inbuilt helper/extension methods will come in a future blog, though in the meantime once you’ve read this post if you want to see more in-depth examples you can easily find them in our v5 source code.

Related Posts:

  1. Umbraco Jupiter Plugins – Part 1
  2. Umbraco Jupiter Plugins – Part 2 - Routing

Disclaimer

This post is about developing for Umbraco v5 (Jupiter) which at the time of this post is still under development. The technical details described below may change by the time Umbraco Jupiter is released. If you have feedback on the technical implementation details, please comment below.

Defining a tree

A tree in Umbraco v5 is actually an MVC Controller that returns JSON data. The first step to creating a tree is to create a class for your tree that inherits from the Umbraco base tree controller class: Umbraco.Cms.Web.Trees.TreeController

Important convention: All Tree controller names MUST be suffixed with ‘TreeController’. For example, if you are creating a tree to display system information, you might call your Tree: SystemInfoTreeController. If you don’t follow this convention, your tree controller won’t be routed.

The next step is to register this tree as a tree plugin. To do this you just need to add an attribute to your class such as:

[Tree("A18108B1-9C86-4B47-AC04-A3089FE8D3EA", "My Custom Tree")]

The two parameters passed to this attribute are:

  • The tree plugin ID (this MUST be unique so ensure you generated a new GUID for every single one of your plugins)
  • The tree title. This will be the text rendered for the root node of your tree, however, this can be overridden and you could render out any title that you wish for your root node and it could even be dynamic. Also note that we will be supporting localization for the tree title.

The next thing you’ll need to do to ensure your tree plugin is found and loaded is to ‘advertise’ that your assembly contains a tree plugin. To do this, just edit your assembly’s AssemblyInfo.cs file and add the following attribute:

//mark assembly for export as a tree plugin
[assembly: TreePluginAssembly]
[assembly: AssemblyContainsPlugins]

Creating a tree

Constructor

When inheriting from the base Umbraco.Cms.Web.Trees.TreeController, you will be required to create a constructor accepting an parameter of type: IBackOfficeRequestContext :

[Tree("A18108B1-9C86-4B47-AC04-A3089FE8D3EA", "My Custom Tree")]
public class MyTreeController : TreeController
{
    public MyTreeController(IBackOfficeRequestContext requestContext)
        : base(requestContext)
    {
    }

    //more code will go here....
    
}

The IBackOfficeRequestContext will most likely contain references to everything you’ll need to get the data for your tree. It includes references to:

  • Hive
  • Umbraco settings
  • The TextManager (localization framework)
  • All of the registered plugins in the system
  • … and a whole lot more

However, you’ll be please to know that all plugins including Trees can take part in IoC contructor injection. So, if you want more objects injected into your tree controller you can just add the parameters to your constructor and they’ll be injected so long as they exist in the IoC container.

Overriding methods/properties

There is one property and one method you need to override:

RootNodeId

This property is just a getter and returns the root node id for your tree. Many trees exist at the absolute root of the data which is called the SystemRoot. An example of a tree that exists at the system root would be trees like the: Data Type tree, Macro tree, Packages tree, tc… since they don’t have a heirarchy. Tree’s that have different start node Ids are trees like: Content, Media and Users.  Since each one of those entities share the same data structure, we separate these data structures under different start nodes from the SystemRoot.

For the most part, if you are creating a utility type tree or a custom tree that doesn’t exist under a special hierarchy, the SystemRoot is what you’ll want:

protected override HiveEntityUri RootNodeId
{
    get { return FixedHiveIds.SystemRoot; }
}

GetTreeData

This method is the method that returns the JSON tree data though to make it easy you don’t have to worry about JSON whatsoever. All you need to do is add TreeNode objects to the existing NodeCollection of the tree controller.

As a very simple example, if you wanted to render out one node in your tree you could do this:

protected override UmbracoTreeResult GetTreeData(HiveEntityUri id, FormCollection queryStrings)
{
    NodeCollection.Add(
        CreateTreeNode(id, null, "My only node", string.Empty, false));
    return UmbracoTree();
}

The CreateTreeNode is a helper method which is part of the base TreeController class that has many useful overloads. In this example, we’re giving it an id, not passing in any custom query string parameters, a title, not giving it an editor url and tagging the node as not having any children.

Registering a tree

In order to get your tree to show up in the back office, you need to register the tree in the config file: ~/App_Data/Umbraco/Config/umbraco.cms.trees.config , and here’s all you need to do to put it in the ‘settings’ app (as an example):

<add application="settings" 
     controllerType="MyProject.MyTreeController, MyProject" />

NOTE: At CodeGarden we discussed that you can ship your plugin inside a package and have your own config file deployed which Umbraco will recognize so that you don’t have to edit the already existing file…. This is still true! But we’ll write another blog post about that Smile

More in depth example?

As I mentioned at the start of this post I’ll write another one detailing our many extension and helper methods when rendering out trees, how to add menu items to your nodes, customize your icons, change the editor for particular nodes, etc… In the meantime though, please have a look at the v5 source code, the trees all exist in the project: Umbraco.Cms.Web.Trees