Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Ross Ekberg 124 posts 364 karma points
    Dec 22, 2022 @ 16:03
    Ross Ekberg
    0

    Custom Section Tree in Backoffice

    I am new to MVC. I am trying to create a tree in a custom section. I have created a new custom section in the backoffice and given myself permission to it, so it is visible. I tried following some provided tutorials on the subject, but it starts with "create a tree controller in C#". I loosely understand the concept of a controller, but I don't know where to save the controller or how to structure it. It seems this is a relatively simple thing to do as it is a part of the Umbraco docs. But the instructions are too vague. Can anyone help me out?

  • Huw Reddick 1745 posts 6109 karma points MVP c-trib
    Dec 22, 2022 @ 16:10
    Huw Reddick
    0

    Hi Ross,

    In answer because the web project is a .net library you can create it anyware in the project, but I would suggest creating a subfolder called controllers and create it in there.

    You will need to use visual studio of some description

  • Ross Ekberg 124 posts 364 karma points
    Dec 22, 2022 @ 16:15
    Ross Ekberg
    0

    Ok, so I can just save it in the same folder as the code for the section itself. //App_Plugins/NewSection/. You are saying that's just fine?

    So I save it there. Can you give me an example of the controller code? In the tutorial (https://our.umbraco.com/documentation/extending/section-trees/trees/) it provides the following code to create a tree in a custom section:

    [Tree(SectionAlias = "settings", TreeAlias = "favouriteThingsAlias", TreeTitle = "Favourite Things Name", TreeGroup = "favouritesGroup", SortOrder = 5)]
    public class FavouriteThingsTreeController : TreeController
    { }
    

    How would I implement this? The tutorial doesn't explain.

  • Huw Reddick 1745 posts 6109 karma points MVP c-trib
    Dec 22, 2022 @ 16:27
    Huw Reddick
    0

    No you should create the controllers folder under the project root, app_plugins is a special folder and contains content so will not get built.

    I will ost some code later, not at home currently

  • Ross Ekberg 124 posts 364 karma points
    Dec 30, 2022 @ 21:08
    Ross Ekberg
    0

    Any chance you can share that code?

  • Huw Reddick 1745 posts 6109 karma points MVP c-trib
    Dec 31, 2022 @ 10:24
    Huw Reddick
    0

    Unfortunately I can't currently get access (I'm in Spain and unable to get on my work VPN at the moment, however if you look at the page you linked to, everything you need is there, it is just not all in one place, so you need to read it all to work out what bits go where.

    Basically you need to create the controller something like below (copied from example in the link

    [Tree(SectionAlias = "settings", TreeAlias = "favouriteThingsAlias", TreeTitle = "Favourite Things Name", TreeGroup = "favouritesGroup", SortOrder = 5)]
    [PluginController("favouriteThings")]
    public class FavouriteThingsTreeController : TreeController
    { 
        protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
        {
            var nodes = new TreeNodeCollection();
    
            // check if we're rendering the root node's children
            if (id == Constants.System.Root.ToInvariantString())
            {
                // you can get your custom nodes from anywhere, and they can represent anything...
                Dictionary<int, string> favouriteThings = new Dictionary<int, string>();
                favouriteThings.Add(1, "Raindrops on Roses");
                favouriteThings.Add(2, "Whiskers on Kittens");
                favouriteThings.Add(3, "Skys full of Stars");
                favouriteThings.Add(4, "Warm Woolen Mittens");
                favouriteThings.Add(5, "Cream coloured Unicorns");
                favouriteThings.Add(6, "Schnitzel with Noodles");
    
                // loop through our favourite things and create a tree item for each one
                foreach (var thing in favouriteThings)
                {
                    // add each node to the tree collection using the base CreateTreeNode method
                    // it has several overloads, using here unique Id of tree item, -1 is the Id of the parent node to create, eg the root of this tree is -1 by convention - the querystring collection passed into this route - the name of the tree node -  css class of icon to display for the node - and whether the item has child nodes
                    var node = CreateTreeNode(thing.Key.ToString(), "-1", queryStrings, thing.Value, "icon-presentation", false);
                    nodes.Add(node);
                }
            }
    
            return nodes;
        }
    
        protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
        {
            // create a Menu Item Collection to return so people can interact with the nodes in your tree
            var menu = new MenuItemCollection();
    
            if (id == Constants.System.Root.ToInvariantString())
            {
                // root actions, perhaps users can create new items in this tree, or perhaps it's not a content tree, it might be a read only tree, or each node item might represent something entirely different...
                // add your menu item actions or custom ActionMenuItems
                menu.Items.Add(new CreateChildEntity(Services.TextService));
                // add refresh menu item (note no dialog)
                menu.Items.Add(new RefreshNode(Services.TextService, true));
            }
            else
            {
                // add a delete action to each individual item
                menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
            }
    
            return menu;
        }
    
        protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
        {
            var root = base.CreateRootNode(queryStrings);
    
            // set the icon
            root.Icon = "icon-hearts";
            // could be set to false for a custom tree with a single node.
            root.HasChildren = true;
            //url for menu
            root.MenuUrl = null;
    
            return root;
        }
    
    }
    
  • Ross Ekberg 124 posts 364 karma points
    Jan 03, 2023 @ 17:10
    Ross Ekberg
    0

    I took your code and put it in a controller. Here is the complete code. This is to be put on a section called "Web Subscriptions", with an alias of "WebSubscriptions". I created a file called "WebSubscriptionsTreeController.cs" and put it in "~/controllers" folder. When I run the site and view the section, a blank tree panel flashes for a split second and then disappears. Do I need to register anything for this in the manifest?

    using Bridge.Models;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Umbraco.Web.Mvc;
    
    namespace Bridge.Controllers
    {
    [Tree(SectionAlias = "WebSubscriptions", TreeAlias = "WebSubscriptions", TreeTitle = "Web Subscriptions", TreeGroup = "favouritesGroup", SortOrder = 5)]
    [PluginController("Websubscriptions")]
    public class WebSubscriptionsTreeController : TreeController
    {
        protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
        {
            var nodes = new TreeNodeCollection();
    
            // check if we're rendering the root node's children
            if (id == Constants.System.Root.ToInvariantString())
            {
                // you can get your custom nodes from anywhere, and they can represent anything...
                Dictionary<int, string> favouriteThings = new Dictionary<int, string>();
                favouriteThings.Add(1, "Raindrops on Roses");
                favouriteThings.Add(2, "Whiskers on Kittens");
                favouriteThings.Add(3, "Skys full of Stars");
                favouriteThings.Add(4, "Warm Woolen Mittens");
                favouriteThings.Add(5, "Cream coloured Unicorns");
                favouriteThings.Add(6, "Schnitzel with Noodles");
    
                // loop through our favourite things and create a tree item for each one
                foreach (var thing in favouriteThings)
                {
                    // add each node to the tree collection using the base CreateTreeNode method
                    // it has several overloads, using here unique Id of tree item, -1 is the Id of the parent node to create, eg the root of this tree is -1 by convention - the querystring collection passed into this route - the name of the tree node -  css class of icon to display for the node - and whether the item has child nodes
                    var node = CreateTreeNode(thing.Key.ToString(), "-1", queryStrings, thing.Value, "icon-presentation", false);
                    nodes.Add(node);
                }
            }
    
            return nodes;
        }
    
        protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
        {
            // create a Menu Item Collection to return so people can interact with the nodes in your tree
            var menu = new MenuItemCollection();
    
            if (id == Constants.System.Root.ToInvariantString())
            {
                // root actions, perhaps users can create new items in this tree, or perhaps it's not a content tree, it might be a read only tree, or each node item might represent something entirely different...
                // add your menu item actions or custom ActionMenuItems
                menu.Items.Add(new CreateChildEntity(Services.TextService));
                // add refresh menu item (note no dialog)
                menu.Items.Add(new RefreshNode(Services.TextService, true));
            }
            else
            {
                // add a delete action to each individual item
                menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
            }
    
            return menu;
        }
    
        protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
        {
            var root = base.CreateRootNode(queryStrings);
    
            // set the icon
            root.Icon = "icon-hearts";
            // could be set to false for a custom tree with a single node.
            root.HasChildren = true;
            //url for menu
            root.MenuUrl = null;
    
            return root;
        }
    
    }
    }
    
  • Huw Reddick 1745 posts 6109 karma points MVP c-trib
    Jan 03, 2023 @ 20:46
    Huw Reddick
    0

    This is just a thought as I don't know for sure (I will try out your code tomorrow)

    It could be because your section and tree share the same alias.

  • Ross Ekberg 124 posts 364 karma points
    Dec 22, 2022 @ 16:36
    Ross Ekberg
    0

    Thank you for your help. I really appreciate it.

Please Sign in or register to post replies

Write your reply to:

Draft