Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions source/Handlebars.Test/IteratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,26 @@ public void WithLast()
Assert.Equal("Hello,\n0. Erik (Erik is not last)\n1. Helen (Helen is last)", result);
}

[Fact]
public void WithKey()
{
var source = "Hello,{{#each people}}\n{{@key}}. {{name}}{{/each}}";
var template = Handlebars.Compile(source);
var data = new
{
people = new[]{
new {
name = "Erik"
},
new {
name = "Helen"
}
}
};
var result = template(data);
Assert.Equal("Hello,\n0. Erik\n1. Helen", result);
}

[Fact]
public void Empty()
{
Expand Down
5 changes: 4 additions & 1 deletion source/Handlebars/Configuration/Compatibility.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace HandlebarsDotNet
using System;

namespace HandlebarsDotNet
{
/// <summary>
/// Contains feature flags that breaks compatibility with Handlebarsjs.
Expand All @@ -8,6 +10,7 @@ public class Compatibility
/// <summary>
/// If <see langword="true"/> enables support for <c>@last</c> in object properties iterations.
/// </summary>
[Obsolete("@last is supported on Handlebarsjs, so it is always enabled, and the setting should be removed.")]
public bool SupportLastInObjectIterations { get; set; } = true;

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion source/Handlebars/Iterators/ArrayIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ TemplateDelegate ifEmpty
if (index == 1) iterator.First = BoxedValues.False;
if (index == lastIndex) iterator.Last = BoxedValues.True;

iterator.Index = objectIndex;
iterator.Key = iterator.Index = objectIndex;

blockParamsValues[_0] = value;
blockParamsValues[_1] = objectIndex;
Expand Down
2 changes: 1 addition & 1 deletion source/Handlebars/Iterators/CollectionIterator'2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ TemplateDelegate ifEmpty
if (index == 1) iterator.First = BoxedValues.False;
if (index == lastIndex) iterator.Last = BoxedValues.True;

iterator.Index = objectIndex;
iterator.Key = iterator.Index = objectIndex;

blockParamsValues[_0] = value;
blockParamsValues[_1] = objectIndex;
Expand Down
2 changes: 1 addition & 1 deletion source/Handlebars/Iterators/CollectionIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ TemplateDelegate ifEmpty
if (index == 1) iterator.First = BoxedValues.False;
if (index == lastIndex) iterator.Last = BoxedValues.True;

iterator.Index = objectIndex;
iterator.Key = iterator.Index = objectIndex;

blockParamsValues[_0] = value;
blockParamsValues[_1] = objectIndex;
Expand Down
2 changes: 1 addition & 1 deletion source/Handlebars/Iterators/DictionaryIterator'2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ TemplateDelegate ifEmpty
)
{
using var innerContext = context.CreateFrame();
var iterator = new ObjectIteratorValues(innerContext);
var iterator = new IteratorValues(innerContext);
var blockParamsValues = new BlockParamsValues(innerContext, blockParamsVariables);

blockParamsValues.CreateProperty(0, out var _0);
Expand Down
2 changes: 1 addition & 1 deletion source/Handlebars/Iterators/DictionaryIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ TemplateDelegate ifEmpty
)
{
using var innerContext = context.CreateFrame();
var iterator = new ObjectIteratorValues(innerContext);
var iterator = new IteratorValues(innerContext);
var blockParamsValues = new BlockParamsValues(innerContext, blockParamsVariables);

blockParamsValues.CreateProperty(0, out var _0);
Expand Down
2 changes: 1 addition & 1 deletion source/Handlebars/Iterators/DynamicObjectIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ TemplateDelegate ifEmpty
)
{
using var innerContext = context.CreateFrame();
var iterator = new ObjectIteratorValues(innerContext);
var iterator = new IteratorValues(innerContext);
var blockParamsValues = new BlockParamsValues(innerContext, blockParamsVariables);

blockParamsValues.CreateProperty(0, out var _0);
Expand Down
4 changes: 2 additions & 2 deletions source/Handlebars/Iterators/EnumerableIterator'2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ TemplateDelegate ifEmpty

if (index == 1) iterator.First = BoxedValues.False;
if (current.IsLast) iterator.Last = BoxedValues.True;
iterator.Index = indexObject;

iterator.Key = iterator.Index = indexObject;

blockParamsValues[_0] = value;
blockParamsValues[_1] = indexObject;
Expand Down
4 changes: 2 additions & 2 deletions source/Handlebars/Iterators/EnumerableIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ TemplateDelegate ifEmpty

if (index == 1) iterator.First = BoxedValues.False;
if (current.IsLast) iterator.Last = BoxedValues.True;
iterator.Index = indexObject;

iterator.Key = iterator.Index = indexObject;

blockParamsValues[_0] = value;
blockParamsValues[_1] = indexObject;
Expand Down
4 changes: 2 additions & 2 deletions source/Handlebars/Iterators/ListIterator'2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ TemplateDelegate ifEmpty

if (index == 1) iterator.First = BoxedValues.False;
if (index == lastIndex) iterator.Last = BoxedValues.True;
iterator.Index = objectIndex;

iterator.Key = iterator.Index = objectIndex;

blockParamsValues[_0] = value;
blockParamsValues[_1] = objectIndex;
Expand Down
4 changes: 2 additions & 2 deletions source/Handlebars/Iterators/ListIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ TemplateDelegate ifEmpty

if (index == 1) iterator.First = BoxedValues.False;
if (index == lastIndex) iterator.Last = BoxedValues.True;
iterator.Index = objectIndex;

iterator.Key = iterator.Index = objectIndex;

blockParamsValues[_0] = value;
blockParamsValues[_1] = objectIndex;
Expand Down
2 changes: 1 addition & 1 deletion source/Handlebars/Iterators/ObjectIterator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ TemplateDelegate ifEmpty
)
{
using var innerContext = context.CreateFrame();
var iterator = new ObjectIteratorValues(innerContext);
var iterator = new IteratorValues(innerContext);
var blockParamsValues = new BlockParamsValues(innerContext, blockParamsVariables);

blockParamsValues.CreateProperty(0, out var _0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ TemplateDelegate ifEmpty
if (index == 1) iterator.First = BoxedValues.False;
if (index == lastIndex) iterator.Last = BoxedValues.True;

iterator.Index = objectIndex;
iterator.Key = iterator.Index = objectIndex;

blockParamsValues[_0] = value;
blockParamsValues[_1] = objectIndex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ TemplateDelegate ifEmpty
)
{
using var innerContext = context.CreateFrame();
var iterator = new ObjectIteratorValues(innerContext);
var iterator = new IteratorValues(innerContext);
var blockParamsValues = new BlockParamsValues(innerContext, blockParamsVariables);

blockParamsValues.CreateProperty(0, out var _0);
Expand Down
4 changes: 2 additions & 2 deletions source/Handlebars/Iterators/ReadOnlyListIterator'2.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ TemplateDelegate ifEmpty

if (index == 1) iterator.First = BoxedValues.False;
if (index == lastIndex) iterator.Last = BoxedValues.True;
iterator.Index = objectIndex;

iterator.Key = iterator.Index = objectIndex;

blockParamsValues[_0] = value;
blockParamsValues[_1] = objectIndex;
Expand Down
11 changes: 9 additions & 2 deletions source/Handlebars/ValueProviders/IteratorValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace HandlebarsDotNet.ValueProviders
public readonly ref struct IteratorValues
{
private readonly FixedSizeDictionary<ChainSegment, object, ChainSegment.ChainSegmentEqualityComparer> _data;

private readonly EntryIndex<ChainSegment>[] _wellKnownVariables;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand All @@ -21,8 +21,9 @@ public IteratorValues(BindingContext bindingContext) : this()
_data.AddOrReplace(ChainSegment.First, BoxedValues.True, out _wellKnownVariables[(int) ChainSegment.First.WellKnownVariable]);
_data.AddOrReplace(ChainSegment.Last, BoxedValues.False, out _wellKnownVariables[(int) ChainSegment.Last.WellKnownVariable]);
_data.AddOrReplace(ChainSegment.Index, BoxedValues.Zero, out _wellKnownVariables[(int) ChainSegment.Index.WellKnownVariable]);
_data.AddOrReplace(ChainSegment.Key, null, out _wellKnownVariables[(int)ChainSegment.Key.WellKnownVariable]);
}

public object Value
{
get => _data[_wellKnownVariables[(int) ChainSegment.Value.WellKnownVariable]];
Expand All @@ -41,6 +42,12 @@ public object Index
set => _data[_wellKnownVariables[(int) ChainSegment.Index.WellKnownVariable]] = value;
}

public object Key
{
get => _data[_wellKnownVariables[(int)ChainSegment.Key.WellKnownVariable]];
set => _data[_wellKnownVariables[(int)ChainSegment.Key.WellKnownVariable]] = value;
}

public object Last
{
get => _data[_wellKnownVariables[(int) ChainSegment.Last.WellKnownVariable]];
Expand Down
24 changes: 5 additions & 19 deletions source/Handlebars/ValueProviders/ObjectIteratorValues.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,22 @@
using HandlebarsDotNet.Collections;
using HandlebarsDotNet.PathStructure;
using HandlebarsDotNet.Runtime;
using System;

namespace HandlebarsDotNet.ValueProviders
{
[Obsolete("Use IteratorValues")]
public readonly ref struct ObjectIteratorValues
{
private readonly FixedSizeDictionary<ChainSegment, object, ChainSegment.ChainSegmentEqualityComparer> _data;
private readonly bool _supportLastInObjectIterations;


private readonly EntryIndex<ChainSegment>[] _wellKnownVariables;

public ObjectIteratorValues(BindingContext bindingContext) : this()
{
var configuration = bindingContext.Configuration;

_data = bindingContext.ContextDataObject;
_supportLastInObjectIterations = configuration.Compatibility.SupportLastInObjectIterations;
_wellKnownVariables = bindingContext.WellKnownVariables;
if (!_supportLastInObjectIterations)
{
var undefined = UndefinedBindingResult.Create(ChainSegment.Last);
_data.AddOrReplace(ChainSegment.Last, undefined, out _wellKnownVariables[(int) ChainSegment.Last.WellKnownVariable]);
}
else
{
_data.AddOrReplace(ChainSegment.Last, BoxedValues.False, out _wellKnownVariables[(int) ChainSegment.Last.WellKnownVariable]);
}
_data.AddOrReplace(ChainSegment.Last, BoxedValues.False, out _wellKnownVariables[(int) ChainSegment.Last.WellKnownVariable]);

_data.AddOrReplace(ChainSegment.Key, null, out _wellKnownVariables[(int) ChainSegment.Key.WellKnownVariable]);
_data.AddOrReplace(ChainSegment.Value, null, out _wellKnownVariables[(int) ChainSegment.Value.WellKnownVariable]);
Expand Down Expand Up @@ -61,11 +51,7 @@ public object Index
public object Last
{
get => _data[_wellKnownVariables[(int) ChainSegment.Last.WellKnownVariable]];
set
{
if(!_supportLastInObjectIterations) return;
_data[_wellKnownVariables[(int) ChainSegment.Last.WellKnownVariable]] = value;
}
set => _data[_wellKnownVariables[(int) ChainSegment.Last.WellKnownVariable]] = value;
}
}
}