Skip to content

Commit 1e3dd2a

Browse files
committed
Updated TemplatePro
1 parent a752b75 commit 1e3dd2a

File tree

1 file changed

+104
-62
lines changed

1 file changed

+104
-62
lines changed

Diff for: sources/TemplatePro.pas

+104-62
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ TLoopStackItem = class
168168
DataSourceName: String;
169169
LoopExpression: String;
170170
FullPath: String;
171-
IteratorName: String;
172171
IteratorPosition: Integer;
172+
IteratorName: String;
173173
function IncrementIteratorPosition: Integer;
174174
constructor Create(DataSourceName: String; LoopExpression: String; FullPath: String; IteratorName: String);
175175
end;
@@ -199,7 +199,6 @@ TTProCompiledTemplate = class(TInterfacedObject, ITProCompiledTemplate)
199199
function IsTruthy(const Value: TValue): Boolean;
200200
function GetVarAsString(const Name: string): string;
201201
function GetTValueVarAsString(const Value: PValue; const VarName: string = ''): String;
202-
function GetTValueFromPath(const aObject: TObject; FullPropertyPath: String): TValue;
203202
function GetNullableTValueAsTValue(const Value: PValue; const VarName: string = ''): TValue;
204203
function GetVarAsTValue(const aName: string): TValue;
205204
function GetDataSetFieldAsTValue(const aDataSet: TDataSet; const FieldName: String): TValue;
@@ -294,6 +293,7 @@ TTProConfiguration = class sealed
294293
function HTMLEncode(s: string): string;
295294
function HandleTemplateSectionStateMachine(const aTokenValue1: String; var aTemplateSectionType: TTProTemplateSectionType;
296295
out aErrorMessage: String): Boolean;
296+
function GetTValueFromPath(const aObject: TObject; FullPropertyPath: String): TValue;
297297

298298
implementation
299299

@@ -701,60 +701,6 @@ function TTProCompiledTemplate.GetPseudoVariable(const VarIterator: Integer; con
701701
end;
702702
end;
703703

704-
function TTProCompiledTemplate.GetTValueFromPath(const aObject: TObject; FullPropertyPath: String): TValue;
705-
var
706-
lObjAsList: ITProWrappedList;
707-
lIdx: Integer;
708-
lPropName: string;
709-
lTmpValue: TValue;
710-
function FetchUpTo(const aChar: Char): String;
711-
var
712-
lFirst: Integer;
713-
begin
714-
lFirst := FullPropertyPath.IndexOf(aChar);
715-
if lFirst = -1 then
716-
begin
717-
Result := FullPropertyPath;
718-
end
719-
else
720-
begin
721-
Result := FullPropertyPath.Substring(0, lFirst);
722-
end;
723-
FullPropertyPath := FullPropertyPath.Substring(Length(Result) + 1);
724-
end;
725-
begin
726-
if FullPropertyPath.StartsWith('[') then //the main object must be a list!
727-
begin
728-
lObjAsList := WrapAsList(aObject);
729-
FullPropertyPath := FullPropertyPath.Remove(0,1);
730-
lIdx := FetchUpTo(']').ToInteger;
731-
if FullPropertyPath.IsEmpty then
732-
begin
733-
raise ETProException.Create('Invalid Path - No property name after index');
734-
end;
735-
Result := GetTValueFromPath(lObjAsList.GetItem(lIdx), FullPropertyPath);
736-
end
737-
else
738-
begin
739-
if FullPropertyPath.StartsWith('.') then
740-
begin
741-
FullPropertyPath := FullPropertyPath.Remove(0,1);
742-
end;
743-
lPropName := FetchUpTo('.');
744-
lTmpValue := TTProRTTIUtils.GetProperty(aObject, lPropName);
745-
if (not FullPropertyPath.IsEmpty) then
746-
begin
747-
if not lTmpValue.IsObject then
748-
raise ETProException.Create('Invalid Path - cannot read property of a non object');
749-
Result := GetTValueFromPath(lTmpValue.AsObject, FullPropertyPath);
750-
end
751-
else
752-
begin
753-
Result := lTmpValue;
754-
end;
755-
end;
756-
end;
757-
758704
function TTProCompiledTemplate.GetTValueVarAsString(const Value: PValue; const VarName: string): String;
759705
var
760706
lIsObject: Boolean;
@@ -2823,6 +2769,9 @@ function TTProCompiledTemplate.Render: String;
28232769
lErrorMessage: String;
28242770
lBlockReturnAddress: Int64;
28252771
lCurrentBlockName: string;
2772+
lObj: TValue;
2773+
lLastOpenBracket: Integer;
2774+
lCount: Integer;
28262775

28272776
begin
28282777
lBlockReturnAddress := -1;
@@ -2848,6 +2797,7 @@ function TTProCompiledTemplate.Render: String;
28482797
the real information about the iterator }
28492798
if WalkThroughLoopStack(lVarName, lBaseVarName, lFullPath) then
28502799
begin
2800+
if not lVarMember.IsEmpty then
28512801
lFullPath := lFullPath + '.' + lVarMember;
28522802
PushLoop(TLoopStackItem.Create(lBaseVarName, fTokens[lIdx].Value1, lFullPath, fTokens[lIdx].Value2));
28532803
end
@@ -2884,16 +2834,18 @@ function TTProCompiledTemplate.Render: String;
28842834
end
28852835
else if viListOfObject in lVariable.VarOption then
28862836
begin
2887-
lWrapped := WrapAsList(lVariable.VarValue.AsObject);
28882837
// if lVariable.VarIterator = lWrapped.Count - 1 then
2889-
if lForLoopItem.IteratorPosition = lWrapped.Count - 1 then
2838+
lObj := GetTValueFromPath(lVariable.VarValue.AsObject, lForLoopItem.FullPath);
2839+
lWrapped := WrapAsList(lObj.AsObject);
2840+
lCount := lWrapped.Count;
2841+
if (lCount = 0) or (lForLoopItem.IteratorPosition = lCount - 1) then
28902842
begin
28912843
lIdx := fTokens[lIdx].Ref1; // skip to endif
28922844
Continue;
28932845
end
28942846
else
28952847
begin
2896-
PeekLoop.IncrementIteratorPosition;
2848+
lForLoopItem.IncrementIteratorPosition;
28972849
// lVariable.VarIterator := lVariable.VarIterator + 1;
28982850
end;
28992851
end
@@ -2980,7 +2932,9 @@ function TTProCompiledTemplate.Render: String;
29802932
end
29812933
else if viListOfObject in lVariable.VarOption then
29822934
begin
2983-
lWrapped := TTProDuckTypedList.Wrap(lVariable.VarValue.AsObject);
2935+
{TODO -oDanieleT -cGeneral : We need only .Count here. Could we use something lighter than WrapAsList?}
2936+
lObj := GetTValueFromPath(lVariable.VarValue.AsObject, lForLoopItem.FullPath);
2937+
lWrapped := WrapAsList(lObj.AsObject);
29842938
if lForLoopItem.IteratorPosition < lWrapped.Count - 1 then
29852939
begin
29862940
lIdx := fTokens[lIdx].Ref1; // skip to loop
@@ -3159,6 +3113,7 @@ function TTProCompiledTemplate.GetVarAsTValue(const aName: string): TValue;
31593113
lHandled: Boolean;
31603114
lFullPath: string;
31613115
lValue: TValue;
3116+
lTmpList: ITProWrappedList;
31623117
begin
31633118
lCurrentIterator := nil;
31643119
SplitVariableName(aName, lVarName, lVarMembers);
@@ -3329,13 +3284,28 @@ function TTProCompiledTemplate.GetVarAsTValue(const aName: string): TValue;
33293284
begin
33303285
lFullPath := lCurrentIterator.FullPath;
33313286
lValue := GetTValueFromPath(lVariable.VarValue.AsObject, lFullPath);
3332-
Result := TTProRTTIUtils.GetProperty(WrapAsList(lValue.AsObject)
3333-
.GetItem(lCurrentIterator.IteratorPosition), lVarMembers)
3287+
lTmpList := WrapAsList(lValue.AsObject);
3288+
if Assigned(lTmpList)then
3289+
Result := TTProRTTIUtils.GetProperty(lTmpList.GetItem(lCurrentIterator.IteratorPosition), lVarMembers)
3290+
else
3291+
Result := TTProRTTIUtils.GetProperty(lValue.AsObject, lVarMembers)
33343292
end;
33353293
end
33363294
else
33373295
begin
3296+
if lCurrentIterator.FullPath.IsEmpty then
3297+
begin
33383298
Result := WrapAsList(lVariable.VarValue.AsObject).GetItem(lCurrentIterator.IteratorPosition);
3299+
end
3300+
else
3301+
begin
3302+
lValue := GetTValueFromPath(lVariable.VarValue.AsObject, lCurrentIterator.FullPath);
3303+
lTmpList := WrapAsList(lValue.AsObject);
3304+
if Assigned(lTmpList)then
3305+
Result := TTProRTTIUtils.GetProperty(lTmpList.GetItem(lCurrentIterator.IteratorPosition), lVarMembers)
3306+
else
3307+
Result := TTProRTTIUtils.GetProperty(lValue.AsObject, lVarMembers)
3308+
end;
33393309
end;
33403310
end
33413311
else
@@ -4119,6 +4089,78 @@ function TTProEqualityComparer.GetHashCode(const Value: String): Integer;
41194089
Result := Length(Value);
41204090
end;
41214091

4092+
4093+
4094+
function GetTValueFromPath(const aObject: TObject; FullPropertyPath: String): TValue;
4095+
var
4096+
lObjAsList: ITProWrappedList;
4097+
lIdx: Integer;
4098+
lPropName: string;
4099+
lTmpValue: TValue;
4100+
function FetchUpTo(const aChar: Char): String;
4101+
var
4102+
lFirst: Integer;
4103+
begin
4104+
lFirst := FullPropertyPath.IndexOf(aChar);
4105+
if lFirst = -1 then
4106+
begin
4107+
Result := FullPropertyPath;
4108+
end
4109+
else
4110+
begin
4111+
Result := FullPropertyPath.Substring(0, lFirst);
4112+
end;
4113+
FullPropertyPath := FullPropertyPath.Substring(Length(Result) + 1);
4114+
end;
4115+
begin
4116+
if FullPropertyPath = '.' then
4117+
begin
4118+
Exit(aObject);
4119+
end;
4120+
4121+
if FullPropertyPath.StartsWith('[') then //the main object must be a list!
4122+
begin
4123+
lObjAsList := WrapAsList(aObject);
4124+
FullPropertyPath := FullPropertyPath.Remove(0,1);
4125+
lIdx := FetchUpTo(']').ToInteger;
4126+
Result := GetTValueFromPath(lObjAsList.GetItem(lIdx), FullPropertyPath);
4127+
end
4128+
else
4129+
begin
4130+
if FullPropertyPath.StartsWith('.') then
4131+
begin
4132+
FullPropertyPath := FullPropertyPath.Remove(0,1);
4133+
end;
4134+
if FullPropertyPath.StartsWith('[') then
4135+
begin
4136+
Result := GetTValueFromPath(aObject, FullPropertyPath);
4137+
end
4138+
else
4139+
begin
4140+
lPropName := FetchUpTo('.');
4141+
if lPropName.IsEmpty then
4142+
begin
4143+
Result := aObject;
4144+
end
4145+
else
4146+
begin
4147+
lTmpValue := TTProRTTIUtils.GetProperty(aObject, lPropName);
4148+
if (not FullPropertyPath.IsEmpty) then
4149+
begin
4150+
if not lTmpValue.IsObject then
4151+
raise ETProException.Create('Invalid Path - cannot read property of a non object');
4152+
Result := GetTValueFromPath(lTmpValue.AsObject, FullPropertyPath);
4153+
end
4154+
else
4155+
begin
4156+
Result := lTmpValue;
4157+
end;
4158+
end;
4159+
end;
4160+
end;
4161+
end;
4162+
4163+
41224164
initialization
41234165

41244166
GlContext := TRttiContext.Create;

0 commit comments

Comments
 (0)