diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs
index 978958413a..2d1c48b854 100644
--- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs
@@ -88,7 +88,7 @@ namespace Umbraco.Core.Models.PublishedContent
///
///
/// For published content items, this is also the date the item was published.
- /// This date is always global to the content item, see GetCulture().Date for the
+ /// This date is always global to the content item, see CultureDate() for the
/// date each culture was published.
///
DateTime UpdateDate { get; }
@@ -104,19 +104,20 @@ namespace Umbraco.Core.Models.PublishedContent
string Url(string culture = null, UrlMode mode = UrlMode.Auto);
///
- /// Gets culture infos for a culture.
+ /// Gets the culture date of the content item.
///
- PublishedCultureInfo GetCulture(string culture = null);
+ /// The specific culture to get the name for. If null is used the current culture is used (Default is null).
+ DateTime CultureDate(string culture = null);
///
- /// Gets culture infos.
+ /// Gets all available cultures.
///
///
/// Contains only those culture that are available. For a published content, these are
/// the cultures that are published. For a draft content, those that are 'available' ie
/// have a non-empty content name.
///
- IReadOnlyDictionary Cultures { get; }
+ IReadOnlyList Cultures { get; }
///
/// Gets a value indicating whether the content is draft.
diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs
index cd92888f7e..9132fb1f85 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs
@@ -97,10 +97,10 @@ namespace Umbraco.Core.Models.PublishedContent
public virtual string Url(string culture = null, UrlMode mode = UrlMode.Auto) => _content.Url(culture, mode);
///
- public PublishedCultureInfo GetCulture(string culture = null) => _content.GetCulture(culture);
+ public DateTime CultureDate(string culture = null) => _content.CultureDate(culture);
///
- public IReadOnlyDictionary Cultures => _content.Cultures;
+ public IReadOnlyList Cultures => _content.Cultures;
///
public virtual bool IsDraft(string culture = null) => _content.IsDraft(culture);
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/DictionaryPublishedContent.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/DictionaryPublishedContent.cs
index 40d7146248..7c6ecf5934 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/DictionaryPublishedContent.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/DictionaryPublishedContent.cs
@@ -153,10 +153,11 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
public override string Name(string culture = null) => _name;
- public override PublishedCultureInfo GetCulture(string culture = null) => null;
+ public override DateTime CultureDate(string culture = null) => UpdateDate;
- private static readonly Lazy> NoCultures = new Lazy>(() => new Dictionary());
- public override IReadOnlyDictionary Cultures => NoCultures.Value;
+ // ReSharper disable once CollectionNeverUpdated.Local
+ private static readonly List EmptyListOfString = new List();
+ public override IReadOnlyList Cultures => EmptyListOfString;
public override string UrlSegment(string culture = null) => _urlName;
diff --git a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedContent.cs b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedContent.cs
index b738b22e2c..a1395b46bc 100644
--- a/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedContent.cs
+++ b/src/Umbraco.Tests/LegacyXmlPublishedCache/XmlPublishedContent.cs
@@ -142,10 +142,11 @@ namespace Umbraco.Tests.LegacyXmlPublishedCache
return _name;
}
- public override PublishedCultureInfo GetCulture(string culture = null) => null;
+ public override DateTime CultureDate(string culture = null) => UpdateDate;
- private static readonly Lazy> NoCultures = new Lazy>(() => new Dictionary());
- public override IReadOnlyDictionary Cultures => NoCultures.Value;
+ // ReSharper disable once CollectionNeverUpdated.Local
+ private static readonly List EmptyListOfString = new List();
+ public override IReadOnlyList Cultures => EmptyListOfString;
public override string WriterName
{
diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs
index e91f456922..b92724b033 100644
--- a/src/Umbraco.Tests/Published/NestedContentTests.cs
+++ b/src/Umbraco.Tests/Published/NestedContentTests.cs
@@ -284,8 +284,8 @@ namespace Umbraco.Tests.Published
public override int? TemplateId { get; }
public override int SortOrder { get; }
public override string Name(string culture = null) => default;
- public override PublishedCultureInfo GetCulture(string culture = ".") => throw new NotSupportedException();
- public override IReadOnlyDictionary Cultures => throw new NotSupportedException();
+ public override DateTime CultureDate(string culture = null) => throw new NotSupportedException();
+ public override IReadOnlyList Cultures => throw new NotSupportedException();
public override string UrlSegment(string culture = null) => default;
public override string WriterName { get; }
public override string CreatorName { get; }
diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs
index 073ebf58ca..7d5fb8e736 100644
--- a/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/NuCacheTests.cs
@@ -223,13 +223,13 @@ namespace Umbraco.Tests.PublishedContent
_variationAccesor.VariationContext = new VariationContext("fr-FR");
Assert.AreEqual("val-fr1", publishedContent.Value("prop"));
Assert.AreEqual("name-fr1", publishedContent.Name());
- Assert.AreEqual(new DateTime(2018, 01, 01, 01, 00, 00), publishedContent.GetCulture().Date);
+ Assert.AreEqual(new DateTime(2018, 01, 01, 01, 00, 00), publishedContent.CultureDate());
// now uk is default
_variationAccesor.VariationContext = new VariationContext("en-UK");
Assert.AreEqual("val-uk1", publishedContent.Value("prop"));
Assert.AreEqual("name-uk1", publishedContent.Name());
- Assert.AreEqual(new DateTime(2018, 01, 02, 01, 00, 00), publishedContent.GetCulture().Date);
+ Assert.AreEqual(new DateTime(2018, 01, 02, 01, 00, 00), publishedContent.CultureDate());
// invariant needs to be retrieved explicitly, when it's not default
Assert.AreEqual("val1", publishedContent.Value("prop", culture: ""));
diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
index 41b5588234..7f3c77cc72 100644
--- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
+++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs
@@ -205,8 +205,8 @@ namespace Umbraco.Tests.PublishedContent
public int SortOrder { get; set; }
public string Name(string culture = null) => _names.TryGetValue(culture ?? "", out var name) ? name : null;
public void SetName(string name, string culture = null) => _names[culture ?? ""] = name;
- public PublishedCultureInfo GetCulture(string culture = null) => throw new NotSupportedException();
- public IReadOnlyDictionary Cultures => throw new NotSupportedException();
+ public DateTime CultureDate(string culture = null) => throw new NotSupportedException();
+ public IReadOnlyList Cultures => throw new NotSupportedException();
public string UrlSegment(string culture = null) => _urlSegments.TryGetValue(culture ?? "", out var urlSegment) ? urlSegment : null;
public void SetUrlSegment(string urlSegment, string culture = null) => _urlSegments[culture ?? ""] = urlSegment;
public string WriterName { get; set; }
diff --git a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
index 77f25c0b0b..22d6fe8ef1 100644
--- a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
+++ b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs
@@ -183,8 +183,8 @@ namespace Umbraco.Tests.PublishedContent
public int SortOrder { get; set; }
public string Name(string culture = null) => _names.TryGetValue(culture ?? "", out var name) ? name : null;
public void SetName(string name, string culture = null) => _names[culture ?? ""] = name;
- public PublishedCultureInfo GetCulture(string culture = null) => throw new NotSupportedException();
- public IReadOnlyDictionary Cultures => throw new NotSupportedException();
+ public DateTime CultureDate(string culture = null) => throw new NotSupportedException();
+ public IReadOnlyList Cultures => throw new NotSupportedException();
public string UrlSegment(string culture = null) => _urlSegments.TryGetValue(culture ?? "", out var urlSegment) ? urlSegment : null;
public void SetUrlSegment(string urlSegment, string culture = null) => _urlSegments[culture ?? ""] = urlSegment;
public string WriterName { get; set; }
diff --git a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs b/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs
index 8a092c3453..6dd25b966e 100644
--- a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs
+++ b/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs
@@ -9,12 +9,13 @@ namespace Umbraco.Tests.TestHelpers.Stubs
{
private readonly Dictionary _names = new Dictionary();
private readonly Dictionary _urlSegments = new Dictionary();
+ private readonly Dictionary _cultures;
- public TestPublishedContent(IPublishedContentType contentType, int id, Guid key, Dictionary values, bool previewing, Dictionary cultures = null)
+ public TestPublishedContent(IPublishedContentType contentType, int id, Guid key, Dictionary values, bool previewing, Dictionary cultures = null)
: base(contentType, key, values, previewing)
{
Id = id;
- Cultures = cultures;
+ _cultures = cultures ?? new Dictionary();
}
public int Id { get; }
@@ -23,19 +24,19 @@ namespace Umbraco.Tests.TestHelpers.Stubs
public string Name(string culture = null) => _names.TryGetValue(culture ?? "", out var name) ? name : null;
public void SetName(string name, string culture = null) => _names[culture ?? ""] = name;
public IVariationContextAccessor VariationContextAccessor { get; set; }
- public PublishedCultureInfo GetCulture(string culture = null)
+ public DateTime CultureDate(string culture = null)
{
// handle context culture
if (culture == null)
culture = VariationContextAccessor?.VariationContext?.Culture;
// no invariant culture infos
- if (culture == "" || Cultures == null) return null;
+ if (culture == "" || Cultures == null) return UpdateDate;
// get
- return Cultures.TryGetValue(culture, out var cultureInfos) ? cultureInfos : null;
+ return _cultures.TryGetValue(culture, out var date) ? date : DateTime.MinValue;
}
- public IReadOnlyDictionary Cultures { get; set; }
+ public IReadOnlyList Cultures { get; set; }
public string UrlSegment(string culture = null) => _urlSegments.TryGetValue(culture ?? "", out var urlSegment) ? urlSegment : null;
public void SetUrlSegment(string urlSegment, string culture = null) => _urlSegments[culture ?? ""] = urlSegment;
public string DocumentTypeAlias => ContentType.Alias;
diff --git a/src/Umbraco.Web/Editors/MacroRenderingController.cs b/src/Umbraco.Web/Editors/MacroRenderingController.cs
index a2bbfe1dfd..64706a7f04 100644
--- a/src/Umbraco.Web/Editors/MacroRenderingController.cs
+++ b/src/Umbraco.Web/Editors/MacroRenderingController.cs
@@ -123,12 +123,22 @@ namespace Umbraco.Web.Editors
// Since a Macro might contain thing thats related to the culture of the "IPublishedContent" (ie Dictionary keys) we want
// to set the current culture to the culture related to the content item. This is hacky but it works.
- var culture = publishedContent.GetCulture();
- _variationContextAccessor.VariationContext = new VariationContext(); //must have an active variation context!
+ // fixme I don't even know how this ever worked?!
+
+ // assume this was some sort of "the culture of the item"
+ // but... with multilingual it does not make any sense?!
+ //var culture = publishedContent.GetCulture();
+
+ string culture = ""; // needs to be eg fr-FR
+
if (culture != null)
{
- Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture.Culture);
- _variationContextAccessor.VariationContext = new VariationContext(Thread.CurrentThread.CurrentCulture.Name);
+ Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
+ _variationContextAccessor.VariationContext = new VariationContext(culture);
+ }
+ else
+ {
+ _variationContextAccessor.VariationContext = new VariationContext(); //must have an active variation context!
}
var result = Request.CreateResponse();
diff --git a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs
index 108f58e929..be7bbc37a8 100644
--- a/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs
+++ b/src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs
@@ -230,32 +230,31 @@ namespace Umbraco.Web.Macros
public string Name(string culture = null) => _inner.GetCultureName(culture);
- public PublishedCultureInfo GetCulture(string culture = null)
+ public DateTime CultureDate(string culture = null)
{
- // handle context culture
+ // invariant has invariant value (whatever the requested culture)
+ if (!ContentType.VariesByCulture())
+ return UpdateDate;
+
+ // handle context culture for variant
if (culture == null)
culture = _variationContextAccessor.VariationContext.Culture;
- // no invariant culture infos
- if (culture == "") return null;
-
// get
- return Cultures.TryGetValue(culture, out var cultureInfos) ? cultureInfos : null;
+ return culture != "" && _inner.PublishCultureInfos.TryGetValue(culture, out var infos) ? infos.Date : DateTime.MinValue;
}
- public IReadOnlyDictionary Cultures
+ // ReSharper disable once CollectionNeverUpdated.Local
+ private static readonly List EmptyListOfString = new List();
+ private IReadOnlyList _cultures;
+
+ public IReadOnlyList Cultures
{
get
{
if (!_inner.ContentType.VariesByCulture())
- return NoCultureInfos;
-
- if (_cultureInfos != null)
- return _cultureInfos;
-
- var urlSegmentProviders = Current.UrlSegmentProviders; // TODO inject
- return _cultureInfos = _inner.PublishCultureInfos.Values
- .ToDictionary(x => x.Culture, x => new PublishedCultureInfo(x.Culture, x.Name, _inner.GetUrlSegment(urlSegmentProviders, x.Culture), x.Date));
+ return EmptyListOfString;
+ return _cultures ?? (_cultures = _inner.PublishCultureInfos.Values.Select(x => x.Culture).ToList());
}
}
diff --git a/src/Umbraco.Web/Models/PublishedContentBase.cs b/src/Umbraco.Web/Models/PublishedContentBase.cs
index 7017e84882..22a76fb907 100644
--- a/src/Umbraco.Web/Models/PublishedContentBase.cs
+++ b/src/Umbraco.Web/Models/PublishedContentBase.cs
@@ -135,10 +135,10 @@ namespace Umbraco.Web.Models
}
///
- public abstract PublishedCultureInfo GetCulture(string culture = null);
+ public abstract DateTime CultureDate(string culture = null);
///
- public abstract IReadOnlyDictionary Cultures { get; }
+ public abstract IReadOnlyList Cultures { get; }
///
public abstract bool IsDraft(string culture = null);
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
index 2e745aacb0..86ed272b13 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs
@@ -196,7 +196,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
culture = VariationContextAccessor?.VariationContext?.Culture ?? "";
// get
- return culture != "" && Cultures.TryGetValue(culture, out var infos) ? infos.Name : null;
+ return culture != "" && ContentData.CultureInfos.TryGetValue(culture, out var infos) ? infos.Name : null;
}
///
@@ -206,12 +206,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
if (!ContentType.VariesByCulture())
return _urlSegment;
- // handle context culture fpr variant
+ // handle context culture for variant
if (culture == null)
culture = VariationContextAccessor?.VariationContext?.Culture ?? "";
// get
- return culture != "" && Cultures.TryGetValue(culture, out var infos) ? infos.UrlSegment : null;
+ return ContentData.CultureInfos.TryGetValue(culture, out var infos) ? infos.UrlSegment : null;
}
///
@@ -244,39 +244,34 @@ namespace Umbraco.Web.PublishedCache.NuCache
///
public override DateTime UpdateDate => ContentData.VersionDate;
- private IReadOnlyDictionary _cultureInfos;
-
- private static readonly IReadOnlyDictionary NoCultureInfos = new Dictionary();
-
///
- public override PublishedCultureInfo GetCulture(string culture = null)
+ public override DateTime CultureDate(string culture = null)
{
- // handle context culture
+ // invariant has invariant value (whatever the requested culture)
+ if (!ContentType.VariesByCulture())
+ return UpdateDate;
+
+ // handle context culture for variant
if (culture == null)
culture = VariationContextAccessor?.VariationContext?.Culture ?? "";
- // no invariant culture infos
- if (culture == "") return null;
-
// get
- return Cultures.TryGetValue(culture, out var cultureInfos) ? cultureInfos : null;
+ return culture != "" && ContentData.CultureInfos.TryGetValue(culture, out var infos) ? infos.Date : DateTime.MinValue;
}
+ // ReSharper disable once CollectionNeverUpdated.Local
+ private static readonly List EmptyListOfString = new List();
+ private IReadOnlyList _cultures;
+
///
- public override IReadOnlyDictionary Cultures
+ public override IReadOnlyList Cultures
{
get
{
if (!ContentType.VariesByCulture())
- return NoCultureInfos;
+ return EmptyListOfString;
- if (_cultureInfos != null) return _cultureInfos;
-
- if (ContentData.CultureInfos == null)
- throw new Exception("oops: _contentDate.CultureInfos is null.");
-
- return _cultureInfos = ContentData.CultureInfos
- .ToDictionary(x => x.Key, x => new PublishedCultureInfo(x.Key, x.Value.Name, x.Value.UrlSegment, x.Value.Date), StringComparer.OrdinalIgnoreCase);
+ return _cultures ?? (_cultures = ContentData.CultureInfos.Keys.ToList());
}
}
diff --git a/src/Umbraco.Web/PublishedCache/PublishedMember.cs b/src/Umbraco.Web/PublishedCache/PublishedMember.cs
index 68b742caa3..46b12b5ca3 100644
--- a/src/Umbraco.Web/PublishedCache/PublishedMember.cs
+++ b/src/Umbraco.Web/PublishedCache/PublishedMember.cs
@@ -140,9 +140,9 @@ namespace Umbraco.Web.PublishedCache
return _member.Name;
}
- public override PublishedCultureInfo GetCulture(string culture = null) => throw new NotSupportedException();
+ public override DateTime CultureDate(string culture = null) => throw new NotSupportedException();
- public override IReadOnlyDictionary Cultures => throw new NotSupportedException();
+ public override IReadOnlyList Cultures => throw new NotSupportedException();
public override string UrlSegment(string culture = null) => throw new NotSupportedException();
diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs
index 7776a7c8ac..d7996034a8 100644
--- a/src/Umbraco.Web/PublishedContentExtensions.cs
+++ b/src/Umbraco.Web/PublishedContentExtensions.cs
@@ -168,7 +168,7 @@ namespace Umbraco.Web
///
/// Culture is case-insensitive.
public static bool HasCulture(this IPublishedContent content, string culture)
- => content.Cultures.ContainsKey(culture ?? string.Empty);
+ => content.Cultures.Contains(culture ?? string.Empty);
///
/// Filters a sequence of to return invariant items, and items that are published for the specified culture.
diff --git a/src/Umbraco.Web/Routing/PublishedRouter.cs b/src/Umbraco.Web/Routing/PublishedRouter.cs
index c93b7c06b2..aeb329a9e9 100644
--- a/src/Umbraco.Web/Routing/PublishedRouter.cs
+++ b/src/Umbraco.Web/Routing/PublishedRouter.cs
@@ -276,7 +276,7 @@ namespace Umbraco.Web.Routing
return true;
// variant, ensure that the culture corresponding to the domain's language is published
- return domainDocument.Cultures.ContainsKey(domain.Culture.Name);
+ return domainDocument.Cultures.Contains(domain.Culture.Name);
}
domains = domains.Where(IsPublishedContentDomain).ToList();
diff --git a/src/Umbraco.Web/Routing/RedirectTrackingComponent.cs b/src/Umbraco.Web/Routing/RedirectTrackingComponent.cs
index 0d82467179..4f9086e50b 100644
--- a/src/Umbraco.Web/Routing/RedirectTrackingComponent.cs
+++ b/src/Umbraco.Web/Routing/RedirectTrackingComponent.cs
@@ -171,12 +171,12 @@ namespace Umbraco.Web.Routing
if (entityContent == null) continue;
// get the default affected cultures by going up the tree until we find the first culture variant entity (default to no cultures)
- var defaultCultures = entityContent.AncestorsOrSelf()?.FirstOrDefault(a => a.Cultures.Any())?.Cultures.Select(c => c.Key).ToArray()
+ var defaultCultures = entityContent.AncestorsOrSelf()?.FirstOrDefault(a => a.Cultures.Any())?.Cultures.ToArray()
?? new[] {(string) null};
foreach (var x in entityContent.DescendantsOrSelf())
{
// if this entity defines specific cultures, use those instead of the default ones
- var cultures = x.Cultures.Any() ? x.Cultures.Select(c => c.Key) : defaultCultures;
+ var cultures = x.Cultures.Any() ? x.Cultures : defaultCultures;
foreach (var culture in cultures)
{