diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs
index 709c37daaa..7e53eb764a 100644
--- a/src/Umbraco.Core/Models/Property.cs
+++ b/src/Umbraco.Core/Models/Property.cs
@@ -271,6 +271,10 @@ namespace Umbraco.Core.Models
///
public void SetValue(object value, string culture = null, string segment = null)
{
+ if (PropertyType.Variations == ContentVariation.InvariantNeutral)
+ {
+ culture = null;
+ }
PropertyType.ValidateVariation(culture, segment, true);
(var pvalue, var change) = GetPValue(culture, segment, true);
diff --git a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
index a402a7cb0a..9139b28528 100644
--- a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
+++ b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs
@@ -3,6 +3,7 @@ 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
@@ -266,7 +267,7 @@ 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);
+ SettingsForTests.ConfigureSettings(globalSettings.Object);
var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings.Object);
var publishedRouter = CreatePublishedRouter(Container);
@@ -335,10 +336,10 @@ namespace Umbraco.Tests.Routing
Assert.IsTrue(result);
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
+ }
+
+ // domains such as "/en" are natively supported, and when instanciating
+ // DomainAndUri for them, the host will come from the current request
//
private void SetDomains3()
{
@@ -360,12 +361,12 @@ namespace Umbraco.Tests.Routing
}
});
}
-
+
#region Cases
[TestCase("http://domain1.com/en", "en-US", 10011)]
[TestCase("http://domain1.com/en/1001-1-1", "en-US", 100111)]
[TestCase("http://domain1.com/fr", "fr-FR", 10012)]
- [TestCase("http://domain1.com/fr/1001-2-1", "fr-FR", 100121)]
+ [TestCase("http://domain1.com/fr/1001-2-1", "fr-FR", 100121)]
#endregion
public void DomainGeneric(string inputUrl, string expectedCulture, int expectedNode)
{
@@ -380,7 +381,7 @@ namespace Umbraco.Tests.Routing
var frequest = publishedRouter.CreateRequest(umbracoContext);
// lookup domain
- publishedRouter.FindDomain(frequest);
+ publishedRouter.FindDomain(frequest);
Assert.IsNotNull(frequest.Domain);
Assert.AreEqual(expectedCulture, frequest.Culture.Name);
@@ -391,5 +392,43 @@ 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/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
index 63bdb9c92e..080e224b9d 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
@@ -4,7 +4,7 @@
function ContentEditController($rootScope, $scope, $routeParams, $q, $timeout, $window, $location,
appState, contentResource, entityResource, navigationService, notificationsService, angularHelper,
serverValidationManager, contentEditingHelper, treeService, fileManager, formHelper, umbRequestHelper,
- keyboardService, umbModelMapper, editorState, $http, eventsService, relationResource, overlayService) {
+ keyboardService, umbModelMapper, editorState, $http, eventsService, relationResource, overlayService, localizationService) {
var evts = [];
@@ -304,7 +304,7 @@
//before we launch the dialog we want to execute all client side validations first
if (formHelper.submitForm({ scope: $scope, action: "publish" })) {
var dialog = {
- title: "Ready to Publish?", //TODO: localize
+ title: localizationService.localize("content_readyToPublish"),
view: "publish",
variants: $scope.content.variants, //set a model property for the dialog
skipFormValidation: true, //when submitting the overlay form, skip any client side validation
@@ -400,7 +400,7 @@
var target = null;
var error = { headline: "Cannot automatically restore this item", content: "Use the Move menu item to move it manually" };
- if (data.length == 0) {
+ if (data.length === 0) {
notificationsService.error(error.headline, "There is no 'restore' relation found for this node. Use the Move menu item to move it manually.");
$scope.page.buttonRestore = "error";
return;
@@ -408,7 +408,7 @@
relation = data[0];
- if (relation.parentId == -1) {
+ if (relation.parentId === -1) {
target = { id: -1, name: "Root" };
moveNode(content, target);
} else {
@@ -465,7 +465,6 @@
$scope.editors[editorIndex].content = angular.copy($scope.content);
$scope.editors[editorIndex].content.name = "What a variant";
// set selected variant on split view content
- console.log($scope.editors[editorIndex].content.variants);
angular.forEach($scope.editors[editorIndex].content.variants, function (variant) {
if (variant.culture === selectedVariant.culture) {
variant.current = true;
diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
index b8df84ad25..f5b890bd8c 100644
--- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
+++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
@@ -235,7 +235,7 @@
What languages would you like to publish?
No languages available to be published.
Published Languages.
-
+ Ready to Publish?
Create a new Content Template from '%0%'
diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
index 10fec19b38..aec5c375d9 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
@@ -46,12 +46,17 @@ namespace Umbraco.Web.Models.Mapping
editor = _propertyEditors[Constants.PropertyEditors.Aliases.NoEdit];
}
- var culture = context.GetCulture();
+ var culture = context.GetCulture();
if (culture == null && property.PropertyType.Variations == ContentVariation.CultureNeutral)
{
//a language Id needs to be set for a property type that can be varried by language
throw new InvalidOperationException($"No languageId found in mapping operation when one is required for the culture neutral property type {property.PropertyType.Alias}");
+ }
+ if (property.PropertyType.Variations == ContentVariation.InvariantNeutral)
+ {
+ culture = null;
+
}
var result = new TDestination
diff --git a/src/Umbraco.Web/PropertyEditors/EmailAddressConfiguration.cs b/src/Umbraco.Web/PropertyEditors/EmailAddressConfiguration.cs
index de7756266f..4039a0e3a2 100644
--- a/src/Umbraco.Web/PropertyEditors/EmailAddressConfiguration.cs
+++ b/src/Umbraco.Web/PropertyEditors/EmailAddressConfiguration.cs
@@ -7,7 +7,7 @@ namespace Umbraco.Web.PropertyEditors
///
public class EmailAddressConfiguration
{
- [ConfigurationField("Required?", "boolean")]
+ [ConfigurationField("IsRequired", "Required?", "boolean")]
public bool IsRequired { get; set; }
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/Routing/DomainHelper.cs b/src/Umbraco.Web/Routing/DomainHelper.cs
index 14779848bb..e3e214a144 100644
--- a/src/Umbraco.Web/Routing/DomainHelper.cs
+++ b/src/Umbraco.Web/Routing/DomainHelper.cs
@@ -147,8 +147,10 @@ namespace Umbraco.Web.Routing
// else we have a uri,
// try to match that uri, else filter
- // pick domains for cultures
- var cultureDomains = SelectByCulture(domainsAndUris, culture, defaultCulture);
+ // if a culture is specified, then try to get domains for that culture
+ // (else cultureDomains will be null)
+ // do NOT specify a default culture, else it would pick those domains
+ var cultureDomains = SelectByCulture(domainsAndUris, culture, defaultCulture: null);
IReadOnlyCollection considerForBaseDomains = domainsAndUris;
if (cultureDomains != null)
{