diff --git a/src/Umbraco.Core/Constants-Content.cs b/src/Umbraco.Core/Constants-Content.cs
index 4b8c383e6f..b9d0691454 100644
--- a/src/Umbraco.Core/Constants-Content.cs
+++ b/src/Umbraco.Core/Constants-Content.cs
@@ -11,11 +11,27 @@
/// Defines core supported content fall-back options when retrieving content property values.
/// Defined as constants rather than enum to allow solution or package defined fall-back methods.
///
- public static class FallbackMethods
+ public static class ValueFallback
{
- public const int None = 0;
- public const int RecursiveTree = 1;
- public const int FallbackLanguage = 2;
+ ///
+ /// No fallback at all.
+ ///
+ public const int None = -1;
+
+ ///
+ /// Default fallback.
+ ///
+ public const int Default = 0;
+
+ ///
+ /// Recurse up the tree.
+ ///
+ public const int Recurse = 1;
+
+ ///
+ /// Fallback to other languages.
+ ///
+ public const int Language = 2;
}
}
}
diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs
index 59442e20bb..96a6c144fa 100644
--- a/src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedValueFallback.cs
@@ -1,15 +1,44 @@
-using System.Collections.Generic;
-
-namespace Umbraco.Core.Models.PublishedContent
+namespace Umbraco.Core.Models.PublishedContent
{
///
/// Provides a fallback strategy for getting values.
///
- // fixme - IPublishedValueFallback is still WorkInProgress
- // todo - properly document methods, etc
- // todo - understand caching vs fallback (recurse etc)
public interface IPublishedValueFallback
{
+ // fixme discussions & challenges
+ //
+ // - what's with visitedLanguage? should be internal to fallback implementation
+ // so that should be the case now, with latest changes
+ //
+ // - should be as simple as
+ // model.Value("price", fallback: ValueFallback.Language);
+ // model.Value("name", fallback: ValueFallback.Recurse);
+ //
+ // so chaining things through an array of ints is not... convenient
+ // it feels like ppl could have ValueFallback.LanguageAndRecurse or something?
+ //
+ // - the fallback: parameter value must be open, so about anything can be passed to the IPublishedValueFallback
+ // we have it now, it's an integer + constants, cool
+ //
+ // - we need to be able to configure (via code for now) a default fallback policy?
+ // not! the default value of the fallback: parameter is 'default', not 'none', and if people
+ // want to implement a different default behavior, they have to override the fallback provider
+ //
+ // - currently, no policies on IPublishedProperty nor IPublishedElement, but some may apply (language)
+ // todo: implement
+ //
+ // - general defaultValue discussion:
+ // when HasValue is false, the converter may return something, eg an empty enumerable, even though
+ // defaultValue is null, so should we respect defaultValue only when it is not 'default'?
+ // todo: when defaultValue==default, and HasValue is false, still return GetValue to ensure this
+ //
+ // - (and...)
+ // ModelsBuilder model.Value(x => x.Price, ...) extensions need to be adjusted too
+ //
+ // - cache & perfs
+ // soon as ppl implement custom fallbacks, caching is a problem, so better just not cache
+ // OTOH we need to implement the readonly thing for languages
+
///
/// Gets a fallback value for a property.
///
@@ -25,7 +54,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// At property level, property.GetValue() does *not* implement fallback, and one has to
/// get property.Value() or property.Value{T}() to trigger fallback.
///
- object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue, ICollection visitedLanguages);
+ object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue);
///
/// Gets a fallback value for a property.
@@ -43,7 +72,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// At property level, property.GetValue() does *not* implement fallback, and one has to
/// get property.Value() or property.Value{T}() to trigger fallback.
///
- T GetValue(IPublishedProperty property, string culture, string segment, T defaultValue, ICollection visitedLanguages);
+ T GetValue(IPublishedProperty property, string culture, string segment, T defaultValue);
///
/// Gets a fallback value for a published element property.
@@ -59,7 +88,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// segment, either returned no property at all, or a property with HasValue(culture, segment) being false.
/// It can only fallback at element level (no recurse).
///
- object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue, ICollection visitedLanguages);
+ object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue);
///
/// Gets a fallback value for a published element property.
@@ -76,7 +105,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// segment, either returned no property at all, or a property with HasValue(culture, segment) being false.
/// It can only fallback at element level (no recurse).
///
- T GetValue(IPublishedElement content, string alias, string culture, string segment, T defaultValue, ICollection visitedLanguages);
+ T GetValue(IPublishedElement content, string alias, string culture, string segment, T defaultValue);
///
/// Gets a fallback value for a published content property.
@@ -92,7 +121,7 @@ namespace Umbraco.Core.Models.PublishedContent
/// segment, either returned no property at all, or a property with HasValue(culture, segment) being false.
/// fixme explain & document priority + merge w/recurse?
///
- object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, IEnumerable fallbackMethods, ICollection visitedLanguages);
+ object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, int fallback);
///
/// Gets a fallback value for a published content property.
@@ -109,6 +138,6 @@ namespace Umbraco.Core.Models.PublishedContent
/// segment, either returned no property at all, or a property with HasValue(culture, segment) being false.
/// fixme explain & document priority + merge w/recurse?
///
- T GetValue(IPublishedContent content, string alias, string culture, string segment, T defaultValue, IEnumerable fallbackMethods, ICollection visitedLanguages);
+ T GetValue(IPublishedContent content, string alias, string culture, string segment, T defaultValue, int fallback);
}
}
diff --git a/src/Umbraco.Core/Models/PublishedContent/NoopPublishedValueFallback.cs b/src/Umbraco.Core/Models/PublishedContent/NoopPublishedValueFallback.cs
index a8d55176a3..9d74c4d8a2 100644
--- a/src/Umbraco.Core/Models/PublishedContent/NoopPublishedValueFallback.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/NoopPublishedValueFallback.cs
@@ -1,6 +1,4 @@
-using System.Collections.Generic;
-
-namespace Umbraco.Core.Models.PublishedContent
+namespace Umbraco.Core.Models.PublishedContent
{
///
/// Provides a noop implementation for .
@@ -11,21 +9,21 @@ namespace Umbraco.Core.Models.PublishedContent
public class NoopPublishedValueFallback : IPublishedValueFallback
{
///
- public object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue, ICollection visitedLanguages) => defaultValue;
+ public object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue) => defaultValue;
///
- public T GetValue(IPublishedProperty property, string culture, string segment, T defaultValue, ICollection visitedLanguages) => defaultValue;
+ public T GetValue(IPublishedProperty property, string culture, string segment, T defaultValue) => defaultValue;
///
- public object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue, ICollection visitedLanguages) => defaultValue;
+ public object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue) => defaultValue;
///
- public T GetValue(IPublishedElement content, string alias, string culture, string segment, T defaultValue, ICollection visitedLanguages) => defaultValue;
+ public T GetValue(IPublishedElement content, string alias, string culture, string segment, T defaultValue) => defaultValue;
///
- public object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, IEnumerable fallbackMethods, ICollection visitedLanguages) => defaultValue;
+ public object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, int fallback) => defaultValue;
///
- public T GetValue(IPublishedContent content, string alias, string culture, string segment, T defaultValue, IEnumerable fallbackMethods, ICollection visitedLanguages) => defaultValue;
+ public T GetValue(IPublishedContent content, string alias, string culture, string segment, T defaultValue, int fallback) => defaultValue;
}
}
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs
index 7108824602..0b0f4dea51 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentLanguageVariantTests.cs
@@ -167,7 +167,7 @@ namespace Umbraco.Tests.PublishedContent
public void Can_Get_Content_For_Unpopulated_Requested_Language_With_Fallback()
{
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
- var value = content.Value("welcomeText", "es", fallbackMethods: new[] { Core.Constants.Content.FallbackMethods.FallbackLanguage });
+ var value = content.Value("welcomeText", "es", fallback: Core.Constants.Content.ValueFallback.Language);
Assert.AreEqual("Welcome", value);
}
@@ -175,7 +175,7 @@ namespace Umbraco.Tests.PublishedContent
public void Can_Get_Content_For_Unpopulated_Requested_Language_With_Fallback_Over_Two_Levels()
{
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
- var value = content.Value("welcomeText", "it", fallbackMethods: new[] { Core.Constants.Content.FallbackMethods.FallbackLanguage });
+ var value = content.Value("welcomeText", "it", fallback: Core.Constants.Content.ValueFallback.Language);
Assert.AreEqual("Welcome", value);
}
@@ -183,7 +183,7 @@ namespace Umbraco.Tests.PublishedContent
public void Do_Not_GetContent_For_Unpopulated_Requested_Language_With_Fallback_Over_That_Loops()
{
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First();
- var value = content.Value("welcomeText", "no", fallbackMethods: new[] { Core.Constants.Content.FallbackMethods.FallbackLanguage });
+ var value = content.Value("welcomeText", "no", fallback: Core.Constants.Content.ValueFallback.Language);
Assert.IsNull(value);
}
@@ -199,27 +199,7 @@ namespace Umbraco.Tests.PublishedContent
public void Can_Get_Content_Recursively()
{
var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
- var value = content.Value("welcomeText2", fallbackMethods: new[] { Core.Constants.Content.FallbackMethods.RecursiveTree });
- Assert.AreEqual("Welcome", value);
- }
-
- [Test]
- public void Can_Get_Content_With_Recursive_Priority()
- {
- var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
- var value = content.Value("welcomeText", "nl", fallbackMethods: new[] { Core.Constants.Content.FallbackMethods.RecursiveTree, Core.Constants.Content.FallbackMethods.FallbackLanguage });
-
- // No Dutch value is directly assigned. Check has fallen back to Dutch value from parent.
- Assert.AreEqual("Welkom", value);
- }
-
- [Test]
- public void Can_Get_Content_With_Fallback_Language_Priority()
- {
- var content = UmbracoContext.Current.ContentCache.GetAtRoot().First().Children.First();
- var value = content.Value("welcomeText", "nl", fallbackMethods: new[] { Core.Constants.Content.FallbackMethods.FallbackLanguage, Core.Constants.Content.FallbackMethods.RecursiveTree });
-
- // No Dutch value is directly assigned. Check has fallen back to English value from language variant.
+ var value = content.Value("welcomeText2", fallback: Core.Constants.Content.ValueFallback.Recurse);
Assert.AreEqual("Welcome", value);
}
}
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
index 950bbf2283..93f4f3f242 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs
@@ -34,7 +34,7 @@ namespace Umbraco.Tests.PublishedContent
Container.RegisterSingleton(f => new PublishedModelFactory(f.GetInstance().GetTypes()));
Container.RegisterSingleton();
- Container.RegisterSingleton();
+ Container.RegisterSingleton();
var logger = Mock.Of();
var dataTypeService = new TestObjects.TestDataTypeService(
@@ -336,8 +336,8 @@ namespace Umbraco.Tests.PublishedContent
public void Get_Property_Value_Recursive()
{
var doc = GetNode(1174);
- var rVal = doc.Value("testRecursive", fallbackMethods: new[] { Constants.Content.FallbackMethods.RecursiveTree } );
- var nullVal = doc.Value("DoNotFindThis", fallbackMethods: new[] { Constants.Content.FallbackMethods.RecursiveTree });
+ var rVal = doc.Value("testRecursive", fallback: Constants.Content.ValueFallback.Recurse);
+ var nullVal = doc.Value("DoNotFindThis", fallback: Constants.Content.ValueFallback.Recurse);
Assert.AreEqual("This is the recursive val", rVal);
Assert.AreEqual(null, nullVal);
}
diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
index 2f7fe8700b..5eea6bcf72 100644
--- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
+++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
@@ -28,7 +28,7 @@ namespace Umbraco.Tests.TestHelpers
{
base.Compose();
- Container.RegisterSingleton();
+ Container.RegisterSingleton();
Container.RegisterSingleton();
}
diff --git a/src/Umbraco.Web/Models/PublishedContent/PublishedValueFallback.cs b/src/Umbraco.Web/Models/PublishedContent/PublishedValueFallback.cs
index 85b10be480..4136be40d8 100644
--- a/src/Umbraco.Web/Models/PublishedContent/PublishedValueFallback.cs
+++ b/src/Umbraco.Web/Models/PublishedContent/PublishedValueFallback.cs
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
+using Umbraco.Core;
using Umbraco.Core.Models.PublishedContent;
+using Umbraco.Core.Services;
+using ValueFallback = Umbraco.Core.Constants.Content.ValueFallback;
namespace Umbraco.Web.Models.PublishedContent
{
@@ -9,90 +12,72 @@ namespace Umbraco.Web.Models.PublishedContent
///
public class PublishedValueFallback : IPublishedValueFallback
{
- // kinda reproducing what was available in v7
+ private readonly ILocalizationService _localizationService;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ public PublishedValueFallback(ILocalizationService localizationService)
+ {
+ _localizationService = localizationService;
+ }
///
- public object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue, ICollection visitedLanguages)
+ public object GetValue(IPublishedProperty property, string culture, string segment, object defaultValue)
{
// no fallback here
return defaultValue;
}
///
- public T GetValue(IPublishedProperty property, string culture, string segment, T defaultValue, ICollection visitedLanguages)
+ public T GetValue(IPublishedProperty property, string culture, string segment, T defaultValue)
{
// no fallback here
return defaultValue;
}
///
- public object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue, ICollection visitedLanguages)
+ public object GetValue(IPublishedElement content, string alias, string culture, string segment, object defaultValue)
{
// no fallback here
return defaultValue;
}
///
- public T GetValue(IPublishedElement content, string alias, string culture, string segment, T defaultValue, ICollection visitedLanguages)
+ public T GetValue(IPublishedElement content, string alias, string culture, string segment, T defaultValue)
{
// no fallback here
return defaultValue;
}
///
- public object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, IEnumerable fallbackMethods, ICollection visitedLanguages)
+ public object GetValue(IPublishedContent content, string alias, string culture, string segment, object defaultValue, int fallback)
{
// is that ok?
- return GetValue