diff --git a/src/Umbraco.Core/Constants-Applications.cs b/src/Umbraco.Core/Constants-Applications.cs
index 7d8476989a..b23efd6bb8 100644
--- a/src/Umbraco.Core/Constants-Applications.cs
+++ b/src/Umbraco.Core/Constants-Applications.cs
@@ -86,7 +86,7 @@
///
/// alias for the packages tree
///
- public const string Packages = "packager";
+ public const string Packages = "packages";
///
/// alias for the dictionary tree.
diff --git a/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs b/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs
index 58fde70467..e13419f0d6 100644
--- a/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs
+++ b/src/Umbraco.Core/PropertyEditors/ConfigurationEditor.cs
@@ -73,7 +73,10 @@ namespace Umbraco.Core.PropertyEditors
// but only keep entries that have a non-null/empty value
// rest will fall back to default during ToConfigurationEditor()
- var keys = editorValues.Where(x => x.Value == null || x.Value is string stringValue && string.IsNullOrWhiteSpace(stringValue)).Select(x => x.Key);
+ var keys = editorValues.Where(x =>
+ x.Value == null || x.Value is string stringValue && string.IsNullOrWhiteSpace(stringValue))
+ .Select(x => x.Key).ToList();
+
foreach (var key in keys) editorValues.Remove(key);
return editorValues;
diff --git a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
index 9139b28528..75327dcdfd 100644
--- a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
+++ b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
@@ -3,7 +3,6 @@ using Moq;
using NUnit.Framework;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
-using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Web.Routing;
namespace Umbraco.Tests.Routing
@@ -337,7 +336,6 @@ namespace Umbraco.Tests.Routing
Assert.AreEqual(expectedCulture, frequest.Culture.Name);
Assert.AreEqual(frequest.PublishedContent.Id, expectedNode);
}
-
// domains such as "/en" are natively supported, and when instanciating
// DomainAndUri for them, the host will come from the current request
//
@@ -375,7 +373,6 @@ namespace Umbraco.Tests.Routing
var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
SettingsForTests.ConfigureSettings(globalSettings.Object);
-
var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings.Object);
var publishedRouter = CreatePublishedRouter(Container);
var frequest = publishedRouter.CreateRequest(umbracoContext);
@@ -392,43 +389,5 @@ namespace Umbraco.Tests.Routing
Assert.IsTrue(result);
Assert.AreEqual(frequest.PublishedContent.Id, expectedNode);
}
-
- [Test]
- public void WithDefaultCulture()
- {
- SetupDomainServiceMock(new[]
- {
- new UmbracoDomain("localhost:9000/en")
- {
- Id = 1,
- LanguageId = LangEngId,
- RootContentId = 10011,
- LanguageIsoCode = "en-US"
- },
- new UmbracoDomain("localhost:9000/fr")
- {
- Id = 1,
- LanguageId = LangFrId,
- RootContentId = 10012,
- LanguageIsoCode = "fr-FR"
- }
- });
-
- var requestUrl = "http://localhost:9000/fr/1001-2-2";
-
- var defaultCultureAccessor = (TestDefaultCultureAccessor) DefaultCultureAccessor;
- defaultCultureAccessor.DefaultCulture = "en-US";
-
- var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container
- globalSettings.Setup(x => x.HideTopLevelNodeFromPath).Returns(false);
- SettingsForTests.ConfigureSettings(globalSettings.Object);
-
- var umbracoContext = GetUmbracoContext(requestUrl, globalSettings:globalSettings.Object);
- var publishedRouter = CreatePublishedRouter(Container);
- var publishedRequest = publishedRouter.CreateRequest(umbracoContext);
-
- var domain = publishedRouter.FindDomain(publishedRequest);
- Assert.AreEqual("fr-FR", publishedRequest.Culture.Name);
- }
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js
index 8bfcdfcc5a..2b0fd341d3 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/contenttype.resource.js
@@ -166,6 +166,15 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
'Failed to retrieve all content types');
},
+ allowsVariation: function() {
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "contentTypeApiBaseUrl",
+ "AllowsVariation")),
+ 'Failed to retrieve variant content types');
+ },
+
getScaffold: function (parentId) {
return umbRequestHelper.resourcePromise(
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js
index 5c3e6eb4c8..034f2c5a3a 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js
@@ -7,6 +7,10 @@ function contentTypeHelper(contentTypeResource, dataTypeResource, $filter, $inje
var contentTypeHelperService = {
+ allowsVariation: function() {
+ return contentTypeResource.allowsVariation();
+ },
+
createIdArray: function(array) {
var newArray = [];
diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
index 758471061d..d44ef023ec 100644
--- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
@@ -9,7 +9,7 @@
*
* @param {navigationService} navigationService A reference to the navigationService
*/
-function NavigationController($scope, $rootScope, $location, $log, $q, $routeParams, $timeout, treeService, appState, navigationService, keyboardService, dialogService, historyService, eventsService, sectionResource, angularHelper, languageResource) {
+function NavigationController($scope, $rootScope, $location, $log, $q, $routeParams, $timeout, treeService, appState, navigationService, keyboardService, dialogService, historyService, eventsService, sectionResource, angularHelper, languageResource, contentTypeHelper) {
//this is used to trigger the tree to start loading once everything is ready
var treeInitPromise = $q.defer();
@@ -209,18 +209,47 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
$scope.showSearchResults = args.value;
}
+ //load languages if doc types allow variations
+ if ($scope.currentSection === "content") {
+ contentTypeHelper.allowsVariation().then(function (b) {
+ if (b === "true") {
+ //load languages if there are more than 1
+ loadLanguages();
+ } else {
+ $scope.languages = [];
+ init();
+ }
+
+ });
+ }
}));
// Listen for language updates
evts.push(eventsService.on("editors.languages.languageDeleted", function (e, args) {
languageResource.getAll().then(function (languages) {
- $scope.languages = languages;
+ contentTypeHelper.allowsVariation().then(function (b) {
+
+ if (b === "true") {
+ $scope.languages = languages;
+ } else {
+ $scope.languages = [];
+ }
+
+ });
});
}));
evts.push(eventsService.on("editors.languages.languageCreated", function (e, args) {
languageResource.getAll().then(function (languages) {
- $scope.languages = languages;
+ contentTypeHelper.allowsVariation().then(function (b) {
+
+ if (b === "true") {
+ $scope.languages = languages;
+ } else {
+ $scope.languages = [];
+ }
+
+ });
});
}));
@@ -359,7 +388,6 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
});
});
}
-
function nodeExpandedHandler(args) {
//store the reference to the expanded node path
if (args.node) {
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-language-picker.less b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-language-picker.less
index 81eb3ab59d..5cf9ca21b3 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-language-picker.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-language-picker.less
@@ -31,7 +31,7 @@
position: absolute;
border-radius: 0 0 3px 3px;
max-height: 200px;
- overflow: scroll;
+ overflow: auto;
}
.umb-language-picker__dropdown a {
@@ -45,4 +45,4 @@
.umb-language-picker__dropdown a:focus {
background: @gray-10;
text-decoration: none;
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs
index 5ffe68afaa..04065e82ce 100644
--- a/src/Umbraco.Web/Editors/ContentTypeController.cs
+++ b/src/Umbraco.Web/Editors/ContentTypeController.cs
@@ -14,6 +14,7 @@ using Umbraco.Web.WebApi;
using Umbraco.Web.WebApi.Filters;
using Umbraco.Core.Logging;
using Umbraco.Web.Composing;
+using ContentVariation = Umbraco.Core.Models.ContentVariation;
namespace Umbraco.Web.Editors
{
@@ -34,6 +35,12 @@ namespace Umbraco.Web.Editors
{
return Services.ContentTypeService.Count();
}
+ [HttpGet]
+ public bool AllowsVariation()
+ {
+ var contentTypes = Services.ContentTypeService.GetAll();
+ return contentTypes.Any(contentType => contentType.Variations.HasFlag(ContentVariation.CultureNeutral));
+ }
public DocumentTypeDisplay GetById(int id)
{
@@ -169,17 +176,17 @@ namespace Umbraco.Web.Editors
}
public DocumentTypeDisplay PostSave(DocumentTypeSave contentTypeSave)
- {
- //Before we send this model into this saving/mapping pipeline, we need to do some cleanup on variations.
- //If the doc type does not allow content variations, we need to update all of it's property types to not allow this either
- //else we may end up with ysods. I'm unsure if the service level handles this but we'll make sure it is updated here
- if (!contentTypeSave.AllowCultureVariant)
- {
- foreach(var prop in contentTypeSave.Groups.SelectMany(x => x.Properties))
- {
- prop.AllowCultureVariant = false;
- }
- }
+ {
+ //Before we send this model into this saving/mapping pipeline, we need to do some cleanup on variations.
+ //If the doc type does not allow content variations, we need to update all of it's property types to not allow this either
+ //else we may end up with ysods. I'm unsure if the service level handles this but we'll make sure it is updated here
+ if (!contentTypeSave.AllowCultureVariant)
+ {
+ foreach(var prop in contentTypeSave.Groups.SelectMany(x => x.Properties))
+ {
+ prop.AllowCultureVariant = false;
+ }
+ }
var savedCt = PerformPostSave(
contentTypeSave: contentTypeSave,
diff --git a/src/Umbraco.Web/Trees/PackagesTreeController.cs b/src/Umbraco.Web/Trees/PackagesTreeController.cs
index ce95cf4ee0..5553ad00b2 100644
--- a/src/Umbraco.Web/Trees/PackagesTreeController.cs
+++ b/src/Umbraco.Web/Trees/PackagesTreeController.cs
@@ -1,108 +1,108 @@
-using System;
-using System.Linq;
-using System.Net.Http.Formatting;
-using Umbraco.Web.Models.Trees;
-using Umbraco.Web.Mvc;
-using Umbraco.Web.WebApi.Filters;
-using umbraco;
-using umbraco.cms.businesslogic.packager;
-using Umbraco.Core.Services;
-using Umbraco.Web._Legacy.Actions;
-using Constants = Umbraco.Core.Constants;
+//using System;
+//using System.Linq;
+//using System.Net.Http.Formatting;
+//using Umbraco.Web.Models.Trees;
+//using Umbraco.Web.Mvc;
+//using Umbraco.Web.WebApi.Filters;
+//using umbraco;
+//using umbraco.cms.businesslogic.packager;
+//using Umbraco.Core.Services;
+//using Umbraco.Web._Legacy.Actions;
+//using Constants = Umbraco.Core.Constants;
-namespace Umbraco.Web.Trees
-{
- [UmbracoTreeAuthorize(Constants.Trees.Packages)]
- [Tree(Constants.Applications.Developer, Constants.Trees.Packages, null, sortOrder: 0)]
- [PluginController("UmbracoTrees")]
- [CoreTree]
- public class PackagesTreeController : TreeController
- {
- ///
- /// Helper method to create a root model for a tree
- ///
- ///
- protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
- {
- var root = base.CreateRootNode(queryStrings);
+//namespace Umbraco.Web.Trees
+//{
+// [UmbracoTreeAuthorize(Constants.Trees.Packages)]
+// [Tree(Constants.Applications.Developer, Constants.Trees.Packages, null, sortOrder: 0)]
+// [PluginController("UmbracoTrees")]
+// [CoreTree]
+// public class PackagesTreeController : TreeController
+// {
+// ///
+// /// Helper method to create a root model for a tree
+// ///
+// ///
+// protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
+// {
+// var root = base.CreateRootNode(queryStrings);
- //this will load in a custom UI instead of the dashboard for the root node
- root.RoutePath = string.Format("{0}/{1}/{2}", Constants.Applications.Developer, Constants.Trees.Packages, "overview");
- root.Icon = "icon-box";
+// //this will load in a custom UI instead of the dashboard for the root node
+// root.RoutePath = string.Format("{0}/{1}/{2}", Constants.Applications.Developer, Constants.Trees.Packages, "overview");
+// root.Icon = "icon-box";
- return root;
- }
+// return root;
+// }
- protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
- {
- var nodes = new TreeNodeCollection();
+// protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
+// {
+// var nodes = new TreeNodeCollection();
- var createdPackages = CreatedPackage.GetAllCreatedPackages();
+// var createdPackages = CreatedPackage.GetAllCreatedPackages();
- if (id == "created")
- {
- nodes.AddRange(
- createdPackages
- .OrderBy(entity => entity.Data.Name)
- .Select(dt =>
- {
- var node = CreateTreeNode(dt.Data.Id.ToString(), id, queryStrings, dt.Data.Name, "icon-inbox", false,
- string.Format("/{0}/framed/{1}",
- queryStrings.GetValue("application"),
- Uri.EscapeDataString("developer/Packages/EditPackage.aspx?id=" + dt.Data.Id)));
- return node;
- }));
- }
- else
- {
- //must be root
- var node = CreateTreeNode(
- "created",
- id,
- queryStrings,
- Services.TextService.Localize("treeHeaders/createdPackages"),
- "icon-folder",
- createdPackages.Count > 0,
- string.Empty);
+// if (id == "created")
+// {
+// nodes.AddRange(
+// createdPackages
+// .OrderBy(entity => entity.Data.Name)
+// .Select(dt =>
+// {
+// var node = CreateTreeNode(dt.Data.Id.ToString(), id, queryStrings, dt.Data.Name, "icon-inbox", false,
+// string.Format("/{0}/framed/{1}",
+// queryStrings.GetValue("application"),
+// Uri.EscapeDataString("developer/Packages/EditPackage.aspx?id=" + dt.Data.Id)));
+// return node;
+// }));
+// }
+// else
+// {
+// //must be root
+// var node = CreateTreeNode(
+// "created",
+// id,
+// queryStrings,
+// Services.TextService.Localize("treeHeaders/createdPackages"),
+// "icon-folder",
+// createdPackages.Count > 0,
+// string.Empty);
- //TODO: This isn't the best way to ensure a noop process for clicking a node but it works for now.
- node.AdditionalData["jsClickCallback"] = "javascript:void(0);";
+// //TODO: This isn't the best way to ensure a noop process for clicking a node but it works for now.
+// node.AdditionalData["jsClickCallback"] = "javascript:void(0);";
- nodes.Add(node);
- }
+// nodes.Add(node);
+// }
- return nodes;
- }
+// return nodes;
+// }
- protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
- {
- var menu = new MenuItemCollection();
+// protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
+// {
+// var menu = new MenuItemCollection();
- // Root actions
- if (id == "-1")
- {
- menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)))
- .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application"));
- }
- else if (id == "created")
- {
- menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)))
- .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application"));
+// // Root actions
+// if (id == "-1")
+// {
+// menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)))
+// .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application"));
+// }
+// else if (id == "created")
+// {
+// menu.Items.Add(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)))
+// .ConvertLegacyMenuItem(null, Constants.Trees.Packages, queryStrings.GetValue("application"));
- menu.Items.Add(
- Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
- }
- else
- {
- //it's a package node
- menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
- }
+// menu.Items.Add(
+// Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
+// }
+// else
+// {
+// //it's a package node
+// menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias));
+// }
- return menu;
- }
- }
-}
+// return menu;
+// }
+// }
+//}