/// <summary> /// Returns the tree nodes for an application /// </summary> /// <param name="application">The application to load tree for</param> /// <param name="tree">An optional single tree alias, if specified will only load the single tree for the request app</param> /// <param name="queryStrings"></param> /// <param name="onlyInitialized">An optional bool (defaults to true), if set to false it will also load uninitialized trees</param> /// <returns></returns> public async Task <SectionRootNode> GetApplicationTrees(string application, string tree, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormDataCollection queryStrings, bool onlyInitialized = true) { application = application.CleanForXss(); if (string.IsNullOrEmpty(application)) { throw new HttpResponseException(HttpStatusCode.NotFound); } var rootId = Constants.System.Root.ToString(CultureInfo.InvariantCulture); //find all tree definitions that have the current application alias var appTrees = Services.ApplicationTreeService.GetApplicationTrees(application, onlyInitialized).ToArray(); if (string.IsNullOrEmpty(tree) == false || appTrees.Length == 1) { var apptree = string.IsNullOrEmpty(tree) == false ? appTrees.SingleOrDefault(x => x.Alias == tree) : appTrees.SingleOrDefault(); if (apptree == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } var result = await GetRootForSingleAppTree( apptree, Constants.System.Root.ToString(CultureInfo.InvariantCulture), queryStrings, application); //this will be null if it cannot convert to ta single root section if (result != null) { return(result); } } var collection = new TreeNodeCollection(); foreach (var apptree in appTrees) { //return the root nodes for each tree in the app var rootNode = await GetRootForMultipleAppTree(apptree, queryStrings); //This could be null if the tree decides not to return it's root (i.e. the member type tree does this when not in umbraco membership mode) if (rootNode != null) { collection.Add(rootNode); } } var multiTree = SectionRootNode.CreateMultiTreeSectionRoot(rootId, collection); multiTree.Name = ui.Text("sections", application); return(multiTree); }
/// <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> /// 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); }