Adds Segment to ContentItemDisplay and update Variants to include segmented variants.

This commit is contained in:
Daniël Knippers
2019-08-29 12:05:27 +02:00
parent 45db8fd7c4
commit 74727a179c
4 changed files with 92 additions and 12 deletions

View File

@@ -53,11 +53,21 @@ namespace Umbraco.Web.Models.ContentEditing
[ReadOnly(true)]
public string Culture { get; set; }
/// <summary>
/// The segment of the property
/// </summary>
/// <remarks>
/// The segment value of a property can always be null but can only have a non-null value
/// when the property can be varied by segment.
/// </remarks>
[DataMember(Name = "segment")]
[ReadOnly(true)]
public string Segment { get; set; }
/// <summary>
/// Used internally during model mapping
/// </summary>
[IgnoreDataMember]
internal IDataEditor PropertyEditor { get; set; }
}
}

View File

@@ -70,8 +70,14 @@ namespace Umbraco.Web.Models.Mapping
dest.Culture = culture;
var segment = context.GetSegment();
// The current segment can always be null, even if the propertyType *can* be varied by segment
// so the nullcheck like with culture is not performed here.
dest.Segment = segment;
// if no 'IncludeProperties' were specified or this property is set to be included - we will map the value and return.
dest.Value = editor.GetValueEditor().ToEditor(property, DataTypeService, culture);
dest.Value = editor.GetValueEditor().ToEditor(property, DataTypeService, culture, segment);
}
}
}

View File

@@ -21,27 +21,35 @@ namespace Umbraco.Web.Models.Mapping
public IEnumerable<ContentVariantDisplay> Map(IContent source, MapperContext context)
{
var result = new List<ContentVariantDisplay>();
if (!source.ContentType.VariesByCulture())
var variants = new List<ContentVariantDisplay>();
var variesByCulture = source.ContentType.VariesByCulture();
var variesBySegment = source.ContentType.VariesBySegment();
if (!variesByCulture && !variesBySegment)
{
//this is invariant so just map the IContent instance to ContentVariationDisplay
result.Add(context.Map<ContentVariantDisplay>(source));
variants.Add(context.Map<ContentVariantDisplay>(source));
return variants;
}
else
if (variesByCulture && !variesBySegment)
{
// Culture only
var allLanguages = _localizationService.GetAllLanguages().OrderBy(x => x.Id).ToList();
if (allLanguages.Count == 0) return Enumerable.Empty<ContentVariantDisplay>(); //this should never happen
var langs = context.MapEnumerable<ILanguage, Language>(allLanguages).ToList();
//create a variant for each language, then we'll populate the values
var variants = langs.Select(x =>
variants.AddRange(langs.Select(x =>
{
//We need to set the culture in the mapping context since this is needed to ensure that the correct property values
//are resolved during the mapping
context.SetCulture(x.IsoCode);
return context.Map<ContentVariantDisplay>(source);
}).ToList();
}));
for (int i = 0; i < langs.Count; i++)
{
@@ -63,10 +71,49 @@ namespace Umbraco.Web.Models.Mapping
//Insert the default language as the first item
variants.Insert(0, defaultLang);
return variants;
}
return result;
else if (variesBySegment && !variesByCulture)
{
// Segment only
throw new NotSupportedException("ContentVariantMapper not implemented for segment only!");
}
else
{
// Culture and segment
var allLanguages = _localizationService.GetAllLanguages().OrderBy(x => x.Id).ToList();
if (allLanguages.Count == 0) return Enumerable.Empty<ContentVariantDisplay>(); //this should never happen
var langs = context.MapEnumerable<ILanguage, Language>(allLanguages).ToList();
// All segments, including the unsegmented (= NULL) segment.
// TODO: The NULl segment might have to be changed to be empty string?
var segments = source.Properties
.SelectMany(p => p.Values.Select(v => v.Segment))
.Distinct();
// Add all variants
foreach (var language in langs)
{
foreach (var segment in segments)
{
context.SetCulture(language.IsoCode);
context.SetSegment(segment);
var variantDisplay = context.Map<ContentVariantDisplay>(source);
variantDisplay.Language = language;
variantDisplay.Segment = segment;
variantDisplay.Name = source.GetCultureName(language.IsoCode);
variants.Add(variantDisplay);
}
}
// TODO: Sorting
}
return variants;
}
}
}

View File

@@ -8,6 +8,7 @@ namespace Umbraco.Web.Models.Mapping
internal static class MapperContextExtensions
{
private const string CultureKey = "Map.Culture";
private const string SegmentKey = "Map.Segment";
private const string IncludedPropertiesKey = "Map.IncludedProperties";
/// <summary>
@@ -18,6 +19,14 @@ namespace Umbraco.Web.Models.Mapping
return context.HasItems && context.Items.TryGetValue(CultureKey, out var obj) && obj is string s ? s : null;
}
/// <summary>
/// Gets the context segment.
/// </summary>
public static string GetSegment(this MapperContext context)
{
return context.HasItems && context.Items.TryGetValue(SegmentKey, out var obj) && obj is string s ? s : null;
}
/// <summary>
/// Sets a context culture.
/// </summary>
@@ -26,6 +35,14 @@ namespace Umbraco.Web.Models.Mapping
context.Items[CultureKey] = culture;
}
/// <summary>
/// Sets a context segment.
/// </summary>
public static void SetSegment(this MapperContext context, string segment)
{
context.Items[SegmentKey] = segment;
}
/// <summary>
/// Get included properties.
/// </summary>
@@ -42,4 +59,4 @@ namespace Umbraco.Web.Models.Mapping
context.Items[IncludedPropertiesKey] = properties;
}
}
}
}