/// <summary> /// Get the root node for an application with multiple trees /// </summary> /// <param name="configTree"></param> /// <param name="queryStrings"></param> /// <returns></returns> private async Task <TreeNode> GetRootForMultipleAppTree(ApplicationTree configTree, FormDataCollection queryStrings) { if (configTree == null) { throw new ArgumentNullException("configTree"); } try { var byControllerAttempt = await configTree.TryGetRootNodeFromControllerTree(queryStrings, ControllerContext); if (byControllerAttempt.Success) { return(byControllerAttempt.Result); } } catch (HttpResponseException) { //if this occurs its because the user isn't authorized to view that tree, in this case since we are loading multiple trees we //will just return null so that it's not added to the list. return(null); } var legacyAttempt = configTree.TryGetRootNodeFromLegacyTree(queryStrings, Url, configTree.ApplicationAlias); if (legacyAttempt.Success) { return(legacyAttempt.Result); } throw new ApplicationException("Could not get root node for tree type " + configTree.Alias); }
private static void OnUpdated(ApplicationTree app, EventArgs args) { if (Updated != null) { Updated(app, args); } }
public TreeNodeCollection GetTreeData(string treeType, string id, FormDataCollection queryStrings) { if (treeType == null) { throw new ArgumentNullException("treeType"); } var configTrees = ApplicationTree.getAll(); //get the configured tree var foundConfigTree = configTrees.FirstOrDefault(x => x.Alias.InvariantEquals(treeType)); if (foundConfigTree == null) { throw new InstanceNotFoundException("Could not find tree of type " + treeType + " in the trees.config"); } var byControllerAttempt = TryLoadFromControllerTree(foundConfigTree, id, queryStrings); if (byControllerAttempt.Success) { return(byControllerAttempt.Result); } var legacyAttempt = TryLoadFromLegacyTree(foundConfigTree, id, queryStrings); if (legacyAttempt.Success) { return(legacyAttempt.Result); } throw new ApplicationException("Could not render a tree for type " + treeType); }
private Attempt <TreeNodeCollection> TryLoadFromLegacyTree(ApplicationTree appTree, string id, FormDataCollection formCollection) { //This is how the legacy trees worked.... var treeDef = TreeDefinitionCollection.Instance.FindTree(appTree.Alias); if (treeDef == null) { return(new Attempt <TreeNodeCollection>(new InstanceNotFoundException("Could not find tree of type " + appTree.Alias))); } var bTree = treeDef.CreateInstance(); var treeParams = new TreeParams(); //we currently only support an integer id or a string id, we'll refactor how this works //later but we'll get this working first int startId; if (int.TryParse(id, out startId)) { treeParams.StartNodeID = startId; } else { treeParams.NodeKey = id; } var xTree = new XmlTree(); bTree.SetTreeParameters(treeParams); bTree.Render(ref xTree); return(new Attempt <TreeNodeCollection>(true, LegacyTreeDataAdapter.ConvertFromLegacy(xTree))); }
private IDictionary <string, TreeSearchResult> GetTreeSearchResultStructure() { Dictionary <string, TreeSearchResult> result = new Dictionary <string, TreeSearchResult>(); string[] allowedSections = Security.CurrentUser.AllowedSections.ToArray(); IReadOnlyDictionary <string, SearchableApplicationTree> searchableTrees = SearchableTreeResolver.Current.GetSearchableTrees(); foreach (var searchableTree in searchableTrees) { if (allowedSections.Contains(searchableTree.Value.AppAlias)) { ApplicationTree tree = Services.ApplicationTreeService.GetByAlias(searchableTree.Key); if (tree == null) { continue; //shouldn't occur } SearchableTreeAttribute searchableTreeAttribute = searchableTree.Value.SearchableTree.GetType().GetCustomAttribute <SearchableTreeAttribute>(false); TreeAttribute treeAttribute = GetTreeAttribute(tree); result[GetRootNodeDisplayName(treeAttribute, Services.TextService)] = new TreeSearchResult { Results = Enumerable.Empty <SearchResultItem>(), TreeAlias = searchableTree.Key, AppAlias = searchableTree.Value.AppAlias, JsFormatterService = searchableTreeAttribute == null ? "" : searchableTreeAttribute.ServiceName, JsFormatterMethod = searchableTreeAttribute == null ? "" : searchableTreeAttribute.MethodName }; } } return(result); }
/// <summary> /// Saves this instance. /// </summary> public void SaveTree(ApplicationTree tree) { LoadXml(doc => { var el = doc.Root.Elements("add").SingleOrDefault(x => x.Attribute("alias").Value == tree.Alias && x.Attribute("application").Value == tree.ApplicationAlias); if (el != null) { el.RemoveAttributes(); el.Add(new XAttribute("initialize", tree.Initialize)); el.Add(new XAttribute("sortOrder", tree.SortOrder)); el.Add(new XAttribute("alias", tree.Alias)); el.Add(new XAttribute("application", tree.ApplicationAlias)); el.Add(new XAttribute("title", tree.Title)); el.Add(new XAttribute("iconClosed", tree.IconClosed)); el.Add(new XAttribute("iconOpen", tree.IconOpened)); el.Add(new XAttribute("type", tree.Type)); } return(true); }, true); OnUpdated(tree, new EventArgs()); }
private static void OnDeleted(ApplicationTree app, EventArgs args) { if (Deleted != null) { Deleted(app, args); } }
private static void OnNew(ApplicationTree app, EventArgs args) { if (New != null) { New(app, args); } }
/// <summary> /// Finds all instances of ITree in loaded assemblies, then finds their associated ApplicationTree and Application objects /// and stores them together in a TreeDefinition class and adds the definition to our list. /// This will also store an instance of each tree object in the TreeDefinition class which should be /// used when referencing all tree classes. /// </summary> private void EnsureTreesRegistered() { if (_ensureTrees == false) { lock (Locker) { if (_ensureTrees == false) { var foundITrees = PluginManager.Current.ResolveTrees(); var objTrees = ApplicationTree.getAll(); var appTrees = new List <ApplicationTree>(); appTrees.AddRange(objTrees); var apps = Application.getAll(); foreach (var type in foundITrees) { //find the Application tree's who's combination of assembly name and tree type is equal to //the Type that was found's full name. //Since a tree can exist in multiple applications we'll need to register them all. //The logic of this has changed in 6.0: http://issues.umbraco.org/issue/U4-1360 // we will support the old legacy way but the normal way is to match on assembly qualified names var appTreesForType = appTrees.FindAll( tree => { //match the type on assembly qualified name if the assembly attribute is empty or if the // tree type contains a comma (meaning it is assembly qualified) if (tree.AssemblyName.IsNullOrWhiteSpace() || tree.Type.Contains(",")) { return(tree.GetRuntimeType() == type); } //otherwise match using legacy match rules return(string.Format("{0}.{1}", tree.AssemblyName, tree.Type).InvariantEquals(type.FullName)); } ); foreach (var appTree in appTreesForType) { //find the Application object whos name is the same as our appTree ApplicationAlias var app = apps.Find( a => (a.alias == appTree.ApplicationAlias) ); var def = new TreeDefinition(type, appTree, app); this.Add(def); } } //sort our trees with the sort order definition this.Sort((t1, t2) => t1.Tree.SortOrder.CompareTo(t2.Tree.SortOrder)); _ensureTrees = true; } } } }
/// <summary> /// Get the root node for an application with one tree /// </summary> /// <param name="configTree"></param> /// <param name="id"></param> /// <param name="queryStrings"></param> /// <returns></returns> private async Task <SectionRootNode> GetRootForSingleAppTree(ApplicationTree configTree, string id, FormDataCollection queryStrings, string application) { var rootId = Constants.System.Root.ToString(CultureInfo.InvariantCulture); if (configTree == null) { throw new ArgumentNullException("configTree"); } var byControllerAttempt = configTree.TryLoadFromControllerTree(id, queryStrings, ControllerContext); if (byControllerAttempt.Success) { var rootNode = await configTree.TryGetRootNodeFromControllerTree(queryStrings, ControllerContext); if (rootNode.Success == false) { //This should really never happen if we've successfully got the children above. throw new InvalidOperationException("Could not create root node for tree " + configTree.Alias); } var sectionRoot = SectionRootNode.CreateSingleTreeSectionRoot( rootId, rootNode.Result.ChildNodesUrl, rootNode.Result.MenuUrl, rootNode.Result.Name, byControllerAttempt.Result); foreach (var d in rootNode.Result.AdditionalData) { sectionRoot.AdditionalData[d.Key] = d.Value; } return(sectionRoot); } var legacyAttempt = configTree.TryLoadFromLegacyTree(id, queryStrings, Url, configTree.ApplicationAlias); if (legacyAttempt.Success) { var sectionRoot = SectionRootNode.CreateSingleTreeSectionRoot( rootId, "", //TODO: I think we'll need this in this situation! Url.GetUmbracoApiService <LegacyTreeController>("GetMenu", rootId) + "&parentId=" + rootId + "&treeType=" + application + "§ion=" + application, "", //TODO: I think we'll need this in this situation! legacyAttempt.Result); sectionRoot.AdditionalData.Add("treeAlias", configTree.Alias); return(sectionRoot); } throw new ApplicationException("Could not render a tree for type " + configTree.Alias); }
/// <summary> /// Finds all instances of ITree in loaded assemblies, then finds their associated ApplicationTree and Application objects /// and stores them together in a TreeDefinition class and adds the definition to our list. /// This will also store an instance of each tree object in the TreeDefinition class which should be /// used when referencing all tree classes. /// </summary> private void RegisterTrees() { if (this.Count > 0) { return; } List <Type> foundITrees = TypeFinder.FindClassesOfType <ITree>(); ApplicationTree[] objTrees = ApplicationTree.getAll(); List <ApplicationTree> appTrees = new List <ApplicationTree>(); appTrees.AddRange(objTrees); List <Application> apps = Application.getAll(); foreach (Type type in foundITrees) { //find the Application tree's who's combination of assembly name and tree type is equal to //the Type that was found's full name. //Since a tree can exist in multiple applications we'll need to register them all. List <ApplicationTree> appTreesForType = appTrees.FindAll( delegate(ApplicationTree tree) { return(string.Format("{0}.{1}", tree.AssemblyName, tree.Type) == type.FullName); } ); if (appTreesForType != null) { foreach (ApplicationTree appTree in appTreesForType) { //find the Application object whos name is the same as our appTree ApplicationAlias Application app = apps.Find( delegate(Application a) { return(a.alias == appTree.ApplicationAlias); } ); TreeDefinition def = new TreeDefinition(type, appTree, app); this.Add(def); } } } //sort our trees with the sort order definition this.Sort(delegate(TreeDefinition t1, TreeDefinition t2) { return(t1.Tree.SortOrder.CompareTo(t2.Tree.SortOrder)); }); }
/// <summary> /// Deletes this instance. /// </summary> public void DeleteTree(ApplicationTree tree) { LoadXml(doc => { doc.Root.Elements("add") .Where(x => x.Attribute("application") != null && x.Attribute("application").Value == tree.ApplicationAlias && x.Attribute("alias") != null && x.Attribute("alias").Value == tree.Alias).Remove(); return(true); }, true); OnDeleted(tree, new EventArgs()); }
/// <summary> /// Finds all instances of ITree in loaded assemblies, then finds their associated ApplicationTree and Application objects /// and stores them together in a TreeDefinition class and adds the definition to our list. /// This will also store an instance of each tree object in the TreeDefinition class which should be /// used when referencing all tree classes. /// </summary> private void EnsureTreesRegistered(bool clearFirst = false) { using (var l = new UpgradeableReadLock(Lock)) { if (clearFirst) { this.Clear(); } //if we already have tree, exit if (this.Count > 0) { return; } l.UpgradeToWriteLock(); var foundITrees = PluginManager.Current.ResolveTrees(); var objTrees = ApplicationTree.getAll(); var appTrees = new List <ApplicationTree>(); appTrees.AddRange(objTrees); var apps = Application.getAll(); foreach (var type in foundITrees) { //find the Application tree's who's combination of assembly name and tree type is equal to //the Type that was found's full name. //Since a tree can exist in multiple applications we'll need to register them all. var appTreesForType = appTrees.FindAll( tree => (string.Format("{0}.{1}", tree.AssemblyName, tree.Type) == type.FullName) ); foreach (var appTree in appTreesForType) { //find the Application object whos name is the same as our appTree ApplicationAlias var app = apps.Find( a => (a.alias == appTree.ApplicationAlias) ); var def = new TreeDefinition(type, appTree, app); this.Add(def); } } //sort our trees with the sort order definition this.Sort((t1, t2) => t1.Tree.SortOrder.CompareTo(t2.Tree.SortOrder)); } }
/// <summary> /// Returns the tree header title. If the alias isn't found in the language files, then it will /// return the title stored in the umbracoAppTree table. /// </summary> /// <param name="alias"></param> /// <returns></returns> public static string GetTreeHeader(string alias) { string treeCaption = ui.Text(alias); //this is a hack. the tree header title should be in the language files, however, if it is not, we're just //going to make it equal to what is specified in the db. if (treeCaption.Length > 0 && treeCaption.Substring(0, 1) == "[") { ApplicationTree tree = ApplicationTree.getByAlias(alias); if (tree != null) { return(tree.Title.SplitPascalCasing().ToFirstUpperInvariant()); } } return(treeCaption); }
private List <ApplicationTree> ReadFromXmlAndSort() { var list = new List <ApplicationTree>(); //read in the xml file containing trees and convert them all to ApplicationTree instances LoadXml(doc => { foreach (var addElement in doc.Root.Elements("add").OrderBy(x => { var sortOrderAttr = x.Attribute("sortOrder"); return(sortOrderAttr != null ? Convert.ToInt32(sortOrderAttr.Value) : 0); })) { var applicationAlias = (string)addElement.Attribute("application"); var type = (string)addElement.Attribute("type"); var clrType = ApplicationTree.TryGetType(type); if (clrType == null) { _logger.Warn <ApplicationTreeService>("The tree definition: " + addElement.ToString() + " could not be resolved to a .Net object type"); continue; } //check if the tree definition (applicationAlias + type + assembly) is already in the list if (list.Any(tree => tree.ApplicationAlias.InvariantEquals(applicationAlias) && tree.GetRuntimeType() == clrType) == false) { list.Add(new ApplicationTree( addElement.Attribute("initialize") == null || Convert.ToBoolean(addElement.Attribute("initialize").Value), addElement.Attribute("sortOrder") != null ? Convert.ToByte(addElement.Attribute("sortOrder").Value) : (byte)0, (string)addElement.Attribute("application"), (string)addElement.Attribute("alias"), (string)addElement.Attribute("title"), (string)addElement.Attribute("iconClosed"), (string)addElement.Attribute("iconOpen"), (string)addElement.Attribute("type"))); } } return(false); }, false); return(list); }
/// <summary> /// Handles the Load event of the Page control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> protected void Page_Load(object sender, EventArgs e) { var filePath = Server.MapPath("~/robots.txt"); var fileContents = string.Empty; if (!IsPostBack) { // HACK: Brute-forces an Umbraco appTree install if (Request.QueryString["action"] == "install") { var appTree = ApplicationTree.getByAlias("robotsTxt"); if (appTree == null) { ApplicationTree.MakeNew(false, true, 6, "developer", "robotsTxt", "Robots.txt", "../../robots-txt/robot.png", "../../robots-txt/robot.png", "Our.Umbraco.Tree.RobotsTxt", "RobotsTxtTree", String.Empty); } } // check if the robots.txt exists if (!File.Exists(filePath)) { // if not, then use the embedded robots.txt var assembly = Assembly.GetExecutingAssembly(); if (assembly != null) { using (var robotsTxt = new StreamReader(assembly.GetManifestResourceStream("Our.Umbraco.Tree.RobotsTxt.robots.txt"))) { fileContents = robotsTxt.ReadToEnd(); } } } else { // otherwise read the contents using (var reader = File.OpenText(filePath)) { fileContents = reader.ReadToEnd(); } } if (!string.IsNullOrEmpty(fileContents)) { this.editorSource.Text = fileContents; } } }
/// <summary> /// Get the root node for an application with one tree /// </summary> /// <param name="configTree"></param> /// <param name="id"></param> /// <param name="queryStrings"></param> /// <param name="application"></param> /// <returns></returns> private async Task <TreeRootNode> GetRootForSingleAppTree(ApplicationTree configTree, string id, FormDataCollection queryStrings, string application) { var rootId = Constants.System.Root.ToString(CultureInfo.InvariantCulture); if (configTree == null) { throw new ArgumentNullException(nameof(configTree)); } var byControllerAttempt = configTree.TryLoadFromControllerTree(id, queryStrings, ControllerContext); if (byControllerAttempt.Success) { var rootNode = await configTree.TryGetRootNodeFromControllerTree(queryStrings, ControllerContext); if (rootNode.Success == false) { //This should really never happen if we've successfully got the children above. throw new InvalidOperationException("Could not create root node for tree " + configTree.Alias); } var treeAttribute = configTree.GetTreeAttribute(); var sectionRoot = TreeRootNode.CreateSingleTreeRoot( rootId, rootNode.Result.ChildNodesUrl, rootNode.Result.MenuUrl, rootNode.Result.Name, byControllerAttempt.Result, treeAttribute.IsSingleNodeTree); //assign the route path based on the root node, this means it will route there when the section is navigated to //and no dashboards will be available for this section sectionRoot.RoutePath = rootNode.Result.RoutePath; foreach (var d in rootNode.Result.AdditionalData) { sectionRoot.AdditionalData[d.Key] = d.Value; } return(sectionRoot); } throw new ApplicationException("Could not render a tree for type " + configTree.Alias); }
/// <summary> /// Get the root node for an application with multiple trees /// </summary> /// <param name="configTree"></param> /// <param name="queryStrings"></param> /// <returns></returns> private async Task <TreeNode> GetRootForMultipleAppTree(ApplicationTree configTree, FormDataCollection queryStrings) { if (configTree == null) { throw new ArgumentNullException("configTree"); } var byControllerAttempt = await configTree.TryGetRootNodeFromControllerTree(queryStrings, ControllerContext); if (byControllerAttempt.Success) { return(byControllerAttempt.Result); } var legacyAttempt = configTree.TryGetRootNodeFromLegacyTree(queryStrings, Url, configTree.ApplicationAlias); if (legacyAttempt.Success) { return(legacyAttempt.Result); } throw new ApplicationException("Could not get root node for tree type " + configTree.Alias); }
public void ApplicationTree_Make_New_Then_Delete_App() { //create new app var name = Guid.NewGuid().ToString("N"); Application.MakeNew(name, name, "icon.jpg"); //check if it exists var app = Application.getByAlias(name); Assert.IsNotNull(app); //create the new app tree assigned to the new app ApplicationTree.MakeNew(false, false, 0, app.alias, name, name, "icon.jpg", "icon.jpg", "nullassembly", "nulltype", string.Empty); var tree = ApplicationTree.getByAlias(name); Assert.IsNotNull(tree); //now delete the app app.Delete(); //check that the tree is gone Assert.AreEqual <int>(0, ApplicationTree.getApplicationTree(name).Count()); }
private Attempt <TreeNodeCollection> TryLoadFromControllerTree(ApplicationTree appTree, string id, FormDataCollection formCollection) { //get reference to all TreeApiControllers var controllerTrees = UmbracoApiControllerResolver.Current.RegisteredUmbracoApiControllers .Where(TypeHelper.IsTypeAssignableFrom <TreeApiController>) .ToArray(); //find the one we're looking for var foundControllerTree = controllerTrees.FirstOrDefault(x => x.GetFullNameWithAssembly() == appTree.Type); if (foundControllerTree == null) { return(new Attempt <TreeNodeCollection>(new InstanceNotFoundException("Could not find tree of type " + appTree.Type + " in any loaded DLLs"))); } //instantiate it, since we are proxying, we need to setup the instance with our current context var instance = (TreeApiController)DependencyResolver.Current.GetService(foundControllerTree); instance.ControllerContext = ControllerContext; instance.Request = Request; //return it's data return(new Attempt <TreeNodeCollection>(true, instance.GetNodes(id, formCollection))); }
private void ApplicationTreeService_Deleted(ApplicationTree sender, EventArgs e) { _distributedCache.RefreshAllApplicationTreeCache(); }
internal static TreeAttribute GetTreeAttribute(ApplicationTree tree) { return(GetTreeAttribute(tree.GetRuntimeType())); }
public IDictionary <string, TreeSearchResult> Search(string query) { IDictionary <string, TreeSearchResult> result = GetTreeSearchResultStructure(); if (string.IsNullOrEmpty(query)) { return(result); } IAzureSearchClient client = AzureSearchContext.Instance.GetSearchClient(); // if the search term contains a space this will be transformed to %20 and no search results returned // so lets decode the query term to turn it back into a proper space // will this mess up any other Url encoded terms? or fix them too? query = HttpUtility.UrlDecode(query); ISearchResult searchResults = client.Term(query + "*").Results(); if (result.Keys.Any(x => x.Equals(Constants.Applications.Content, StringComparison.CurrentCultureIgnoreCase))) { List <SearchResultItem> entities = new List <SearchResultItem>(); foreach (ISearchContent searchResult in searchResults.Content.Where(c => c.IsContent).Take(NumberOfItemsPerSection)) { var entity = SearchContentToEntityBasicMapper.Map(searchResult); entities.Add(entity); } result.First(x => x.Key.Equals(Constants.Applications.Content, StringComparison.CurrentCultureIgnoreCase)) .Value.Results = entities; } if (result.Keys.Any(x => x.Equals(Constants.Applications.Media, StringComparison.CurrentCultureIgnoreCase))) { List <SearchResultItem> entities = new List <SearchResultItem>(); foreach (ISearchContent searchResult in searchResults.Content.Where(c => c.IsMedia).Take(NumberOfItemsPerSection)) { var entity = SearchContentToEntityBasicMapper.Map(searchResult); entities.Add(entity); } result.First(x => x.Key.Equals(Constants.Applications.Media, StringComparison.CurrentCultureIgnoreCase)) .Value.Results = entities; } if (result.Keys.Any(x => x.Equals(Constants.Applications.Members, StringComparison.CurrentCultureIgnoreCase))) { List <SearchResultItem> entities = new List <SearchResultItem>(); ApplicationTree tree = Services.ApplicationTreeService.GetByAlias(Constants.Applications.Members); foreach (ISearchContent searchResult in searchResults.Content.Where(c => c.IsMember).Take(NumberOfItemsPerSection)) { var entity = SearchContentToEntityBasicMapper.Map(searchResult); entities.Add(entity); } result.First(x => x.Key.Equals(Constants.Applications.Members, StringComparison.CurrentCultureIgnoreCase)) .Value.Results = entities; } return(result); }
static void ApplicationTreeDeleted(ApplicationTree sender, System.EventArgs e) { DistributedCache.Instance.RefreshAllApplicationTreeCache(); }
static void ApplicationTreeDeleted(ApplicationTree sender, System.EventArgs e) { DistributedCache.Instance.RefreshAllApplicationTreeCache(); }
/// <summary> /// Saves this instance. /// </summary> public void SaveTree(ApplicationTree tree) { throw new System.NotImplementedException(); }
/// <summary> /// Initializes a new instance of the <see cref="TreeDefinition"/> class. /// </summary> /// <param name="type">The type.</param> /// <param name="tree">The tree.</param> /// <param name="app">The app.</param> public TreeDefinition(Type type, ApplicationTree tree, Application app) { m_treeType = type; m_tree = tree; m_app = app; }
/// <summary> /// Get the root node for an application with one tree /// </summary> /// <param name="configTree"></param> /// <param name="id"></param> /// <param name="queryStrings"></param> /// <param name="application"></param> /// <returns></returns> private async Task <SectionRootNode> GetRootForSingleAppTree(ApplicationTree configTree, string id, FormDataCollection queryStrings, string application) { var rootId = Constants.System.Root.ToString(CultureInfo.InvariantCulture); if (configTree == null) { throw new ArgumentNullException("configTree"); } var byControllerAttempt = configTree.TryLoadFromControllerTree(id, queryStrings, ControllerContext); if (byControllerAttempt.Success) { var rootNode = await configTree.TryGetRootNodeFromControllerTree(queryStrings, ControllerContext); if (rootNode.Success == false) { //This should really never happen if we've successfully got the children above. throw new InvalidOperationException("Could not create root node for tree " + configTree.Alias); } //if the root node has a route path, we cannot create a single root section because by specifying the route path this would //override the dashboard route and that means there can be no dashboard for that section which is a breaking change. if (rootNode.Result.RoutePath.IsNullOrWhiteSpace() == false && rootNode.Result.RoutePath != "#" && rootNode.Result.RoutePath != application) { //null indicates this cannot be converted return(null); } var sectionRoot = SectionRootNode.CreateSingleTreeSectionRoot( rootId, rootNode.Result.ChildNodesUrl, rootNode.Result.MenuUrl, rootNode.Result.Name, byControllerAttempt.Result); //This can't be done currently because the root will default to routing to a dashboard and if we disable dashboards for a section //that is really considered a breaking change. See above. //sectionRoot.RoutePath = rootNode.Result.RoutePath; foreach (var d in rootNode.Result.AdditionalData) { sectionRoot.AdditionalData[d.Key] = d.Value; } return(sectionRoot); } var legacyAttempt = configTree.TryLoadFromLegacyTree(id, queryStrings, Url, configTree.ApplicationAlias); if (legacyAttempt.Success) { var sectionRoot = SectionRootNode.CreateSingleTreeSectionRoot( rootId, "", //TODO: I think we'll need this in this situation! Url.GetUmbracoApiService <LegacyTreeController>("GetMenu", rootId) + "&parentId=" + rootId + "&treeType=" + application + "§ion=" + application, "", //TODO: I think we'll need this in this situation! legacyAttempt.Result); sectionRoot.AdditionalData.Add("treeAlias", configTree.Alias); return(sectionRoot); } throw new ApplicationException("Could not render a tree for type " + configTree.Alias); }