|
@@ -28,6 +28,7 @@ Type
|
|
TMustacheString = UTF8String;
|
|
TMustacheString = UTF8String;
|
|
TMustacheChar = AnsiChar;
|
|
TMustacheChar = AnsiChar;
|
|
TMustacheContext = class;
|
|
TMustacheContext = class;
|
|
|
|
+ TMustacheBlockOverrideList = class;
|
|
|
|
|
|
TMustacheOutput = Class(TObject)
|
|
TMustacheOutput = Class(TObject)
|
|
Public
|
|
Public
|
|
@@ -51,7 +52,7 @@ Type
|
|
|
|
|
|
{ TMustacheElement }
|
|
{ TMustacheElement }
|
|
|
|
|
|
- TMustacheElementType = (metRoot,metComment,metText,metVariable,metSection,metInvertedSection,metPartial);
|
|
|
|
|
|
+ TMustacheElementType = (metRoot,metComment,metText,metVariable,metSection,metInvertedSection,metPartial,metParametricPartial,metBlock);
|
|
|
|
|
|
TMustacheElement = Class(TObject)
|
|
TMustacheElement = Class(TObject)
|
|
private
|
|
private
|
|
@@ -71,7 +72,7 @@ Type
|
|
// Add a child. Parent always owns child
|
|
// Add a child. Parent always owns child
|
|
Procedure AddChild(aChild : TMustacheElement); virtual;
|
|
Procedure AddChild(aChild : TMustacheElement); virtual;
|
|
// Render the text for this element
|
|
// Render the text for this element
|
|
- Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; const aPrefix : String = ''; aLast : Boolean = False); virtual; abstract;
|
|
|
|
|
|
+ Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil; const aPrefix : String = ''; aLast : Boolean = False); virtual; abstract;
|
|
// Position in template
|
|
// Position in template
|
|
Property Position : Integer Read FPosition;
|
|
Property Position : Integer Read FPosition;
|
|
// Parent element
|
|
// Parent element
|
|
@@ -118,9 +119,15 @@ Type
|
|
Public
|
|
Public
|
|
Destructor Destroy; override;
|
|
Destructor Destroy; override;
|
|
Procedure AddChild(aChild : TMustacheElement); override;
|
|
Procedure AddChild(aChild : TMustacheElement); override;
|
|
- Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
|
|
|
|
+ Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ { TMustacheBlockElement }
|
|
|
|
+
|
|
|
|
+ TMustacheBlockElement = Class(TMustacheParentElement)
|
|
|
|
+ Public
|
|
|
|
+ Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
|
|
+ end;
|
|
|
|
|
|
{ TMustacheTextElement }
|
|
{ TMustacheTextElement }
|
|
|
|
|
|
@@ -131,7 +138,7 @@ Type
|
|
Procedure SetData(Const aData : TMustacheString) ; override;
|
|
Procedure SetData(Const aData : TMustacheString) ; override;
|
|
Function GetData : TMustacheString; override;
|
|
Function GetData : TMustacheString; override;
|
|
Public
|
|
Public
|
|
- Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
|
|
|
|
+ Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TMustacheVariableElement }
|
|
{ TMustacheVariableElement }
|
|
@@ -142,7 +149,7 @@ Type
|
|
Protected
|
|
Protected
|
|
Procedure SetData(Const aData : TMustacheString); override;
|
|
Procedure SetData(Const aData : TMustacheString); override;
|
|
Public
|
|
Public
|
|
- Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
|
|
|
|
+ Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
Property NoUnescape : Boolean Read FNoUnescape;
|
|
Property NoUnescape : Boolean Read FNoUnescape;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -150,12 +157,12 @@ Type
|
|
|
|
|
|
TMustacheSectionElement = Class(TMustacheParentElement)
|
|
TMustacheSectionElement = Class(TMustacheParentElement)
|
|
Public
|
|
Public
|
|
- Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
|
|
|
|
+ Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TMustachePartialElement }
|
|
{ TMustachePartialElement }
|
|
|
|
|
|
- TMustachePartialElement = Class(TMustacheElement)
|
|
|
|
|
|
+ TMustachePartialElement = Class(TMustacheParentElement)
|
|
Private
|
|
Private
|
|
FPrefix : TMustacheString;
|
|
FPrefix : TMustacheString;
|
|
FPartialName : TMustacheString;
|
|
FPartialName : TMustacheString;
|
|
@@ -169,7 +176,7 @@ Type
|
|
Public
|
|
Public
|
|
Destructor Destroy; override;
|
|
Destructor Destroy; override;
|
|
Procedure AddChild(aChild: TMustacheElement); override;
|
|
Procedure AddChild(aChild: TMustacheElement); override;
|
|
- Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
|
|
|
|
+ Procedure Render(aContext : TMustacheContext; aOutput : TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil; const aPrefix : String = ''; aLast : Boolean = False); override;
|
|
Property Partial : TMustacheElement Read FPartial;
|
|
Property Partial : TMustacheElement Read FPartial;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -180,6 +187,18 @@ Type
|
|
Function FindPartial(aName : TMustacheString) : TMustacheElement;
|
|
Function FindPartial(aName : TMustacheString) : TMustacheElement;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ { TMustacheBlockOverrideList }
|
|
|
|
+
|
|
|
|
+ TMustacheBlockOverrideList = Class
|
|
|
|
+ Private
|
|
|
|
+ FBlocks: TMustacheElementArray;
|
|
|
|
+ FCount: Integer;
|
|
|
|
+ Public
|
|
|
|
+ Procedure Push(aBlock: TMustacheElement);
|
|
|
|
+ Procedure Pop;
|
|
|
|
+ Function FindFirst(aBlockName: TMustacheString): TMustacheElement;
|
|
|
|
+ end;
|
|
|
|
+
|
|
{ TMustacheParser }
|
|
{ TMustacheParser }
|
|
TGetTextValueEvent = Procedure (Const aName : TMustacheString; var aHandled : Boolean; var aValue : TMustacheString) of Object;
|
|
TGetTextValueEvent = Procedure (Const aName : TMustacheString; var aHandled : Boolean; var aValue : TMustacheString) of Object;
|
|
|
|
|
|
@@ -330,6 +349,7 @@ Resourcestring
|
|
SErrInvalidDelimiter = 'Invalid set delimiter: %s';
|
|
SErrInvalidDelimiter = 'Invalid set delimiter: %s';
|
|
SErrInvalidDelimiterValue = 'Invalid set delimiter %s value: %s in "%s"';
|
|
SErrInvalidDelimiterValue = 'Invalid set delimiter %s value: %s in "%s"';
|
|
SErrNoPartials = 'No partials list';
|
|
SErrNoPartials = 'No partials list';
|
|
|
|
+ SErrNotABlockType = 'Class %s is not a block type.';
|
|
|
|
|
|
// SErrPartialNotFound = 'Partial "%s" not found.';
|
|
// SErrPartialNotFound = 'Partial "%s" not found.';
|
|
SStartTag = 'Start';
|
|
SStartTag = 'Start';
|
|
@@ -354,6 +374,40 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+{ TMustacheBlockOverrideList }
|
|
|
|
+
|
|
|
|
+procedure TMustacheBlockOverrideList.Push(aBlock: TMustacheElement);
|
|
|
|
+var
|
|
|
|
+ Len: Integer;
|
|
|
|
+begin
|
|
|
|
+ if aBlock.ElementType <> metBlock then
|
|
|
|
+ Raise EMustache.CreateFmt(SErrNotABlockType, [aBlock.ClassName]);
|
|
|
|
+ Len := Length(FBlocks);
|
|
|
|
+ if (FCount >= Len) then
|
|
|
|
+ SetLength(FBlocks, Len + ListGrowCount);
|
|
|
|
+ FBlocks[FCount] := aBlock;
|
|
|
|
+ Inc(FCount);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TMustacheBlockOverrideList.Pop;
|
|
|
|
+begin
|
|
|
|
+ Dec(FCount);
|
|
|
|
+ FBlocks[FCount] := nil; // do not free; does not own blocks
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+function TMustacheBlockOverrideList.FindFirst(aBlockName: TMustacheString): TMustacheElement;
|
|
|
|
+var
|
|
|
|
+ I: Integer;
|
|
|
|
+begin
|
|
|
|
+ Result := nil;
|
|
|
|
+ for I:=0 to FCount-1 do
|
|
|
|
+ if FBlocks[I].Data = aBlockName then
|
|
|
|
+ begin
|
|
|
|
+ Result := FBlocks[I];
|
|
|
|
+ Break;
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
{ TMustachePartialElement }
|
|
{ TMustachePartialElement }
|
|
|
|
|
|
function TMustachePartialElement.GetData: TMustacheString;
|
|
function TMustachePartialElement.GetData: TMustacheString;
|
|
@@ -368,17 +422,21 @@ end;
|
|
|
|
|
|
procedure TMustachePartialElement.AddChild(aChild: TMustacheElement);
|
|
procedure TMustachePartialElement.AddChild(aChild: TMustacheElement);
|
|
begin
|
|
begin
|
|
- If (FPartial<>Nil) and (aChild<>Nil) then
|
|
|
|
- Raise EMustache.Create('Cannot set partial twice');
|
|
|
|
- FPartial:=aChild;
|
|
|
|
|
|
+ if FPartial = nil then
|
|
|
|
+ FPartial := aChild
|
|
|
|
+ else
|
|
|
|
+ inherited AddChild(aChild);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TMustachePartialElement.Dump(aList: Tstrings;
|
|
procedure TMustachePartialElement.Dump(aList: Tstrings;
|
|
aIndent: TMustacheString; aDumpChildren: Boolean);
|
|
aIndent: TMustacheString; aDumpChildren: Boolean);
|
|
|
|
+var
|
|
|
|
+ PartialIndex: Integer;
|
|
begin
|
|
begin
|
|
|
|
+ PartialIndex := aList.Count; // save index, because inherited Dump may dump children
|
|
inherited Dump(aList, aIndent, aDumpChildren);
|
|
inherited Dump(aList, aIndent, aDumpChildren);
|
|
if Prefix<>'' then
|
|
if Prefix<>'' then
|
|
- aList[aList.Count-1]:=aList[aList.Count-1]+' Prefix: "'+Prefix+'"';
|
|
|
|
|
|
+ aList[PartialIndex]:=aList[PartialIndex]+' Prefix: "'+Prefix+'"';
|
|
end;
|
|
end;
|
|
|
|
|
|
function TMustachePartialElement.GetPrefix: TMustacheString;
|
|
function TMustachePartialElement.GetPrefix: TMustacheString;
|
|
@@ -392,10 +450,31 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TMustachePartialElement.Render(aContext: TMustacheContext;
|
|
procedure TMustachePartialElement.Render(aContext: TMustacheContext;
|
|
- aOutput: TMustacheOutput; const aPrefix : String = ''; aLast : Boolean = False);
|
|
|
|
|
|
+ aOutput: TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil;
|
|
|
|
+ const aPrefix : String = ''; aLast : Boolean = False);
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ I,
|
|
|
|
+ OverrideCount: Integer;
|
|
|
|
|
|
begin
|
|
begin
|
|
- FPartial.Render(aContext,aOutput,Prefix);
|
|
|
|
|
|
+ OverrideCount := 0;
|
|
|
|
+ if ElementType = metParametricPartial then
|
|
|
|
+ begin
|
|
|
|
+ if aBlockOverrides = Nil then
|
|
|
|
+ raise EMustache.Create('Parametric Partial elements need an instance of TMustacheBlockOverrideList');
|
|
|
|
+ for I:=0 to ChildCount-1 do
|
|
|
|
+ if Children[I].ElementType = metBlock then
|
|
|
|
+ begin
|
|
|
|
+ aBlockOverrides.Push(Children[I]);
|
|
|
|
+ Inc(OverrideCount);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ FPartial.Render(aContext,aOutput,aBlockOverrides,Prefix);
|
|
|
|
+
|
|
|
|
+ for I:=1 to OverrideCount do
|
|
|
|
+ aBlockOverrides.Pop;
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TMustachePartialElement.Destroy;
|
|
destructor TMustachePartialElement.Destroy;
|
|
@@ -403,7 +482,6 @@ begin
|
|
inherited Destroy;
|
|
inherited Destroy;
|
|
end;
|
|
end;
|
|
|
|
|
|
-
|
|
|
|
{ TMustache }
|
|
{ TMustache }
|
|
|
|
|
|
function TMustache.CreateParser(aTemplate : TMustacheString): TMustacheParser;
|
|
function TMustache.CreateParser(aTemplate : TMustacheString): TMustacheParser;
|
|
@@ -478,10 +556,18 @@ end;
|
|
|
|
|
|
procedure TMustache.Render(aContext: TMustacheContext; aOutput: TMustacheOutput);
|
|
procedure TMustache.Render(aContext: TMustacheContext; aOutput: TMustacheOutput);
|
|
|
|
|
|
|
|
+Var
|
|
|
|
+ BlockOverrides: TMustacheBlockOverrideList;
|
|
|
|
+
|
|
begin
|
|
begin
|
|
if not Assigned(Compiled) then
|
|
if not Assigned(Compiled) then
|
|
Compile;
|
|
Compile;
|
|
- Compiled.Render(aContext,aOutput);
|
|
|
|
|
|
+ BlockOverrides := TMustacheBlockOverrideList.Create;
|
|
|
|
+ try
|
|
|
|
+ Compiled.Render(aContext,aOutput,BlockOverrides);
|
|
|
|
+ finally
|
|
|
|
+ BlockOverrides.Free;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
function TMustache.Render(aContext: TMustacheContext): TMustacheString;
|
|
function TMustache.Render(aContext: TMustacheContext): TMustacheString;
|
|
@@ -701,7 +787,8 @@ end;
|
|
{ TMustacheSectionElement }
|
|
{ TMustacheSectionElement }
|
|
|
|
|
|
procedure TMustacheSectionElement.Render(aContext: TMustacheContext;
|
|
procedure TMustacheSectionElement.Render(aContext: TMustacheContext;
|
|
- aOutput: TMustacheOutput; const aPrefix: String; aLast : Boolean = False);
|
|
|
|
|
|
+ aOutput: TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil;
|
|
|
|
+ const aPrefix: String = ''; aLast : Boolean = False);
|
|
|
|
|
|
Var
|
|
Var
|
|
L : TMustacheSectionType;
|
|
L : TMustacheSectionType;
|
|
@@ -711,15 +798,15 @@ begin
|
|
if ElementType=metInvertedSection then
|
|
if ElementType=metInvertedSection then
|
|
begin
|
|
begin
|
|
if L=mstNone then
|
|
if L=mstNone then
|
|
- inherited Render(aContext, aOutput,aPrefix);
|
|
|
|
|
|
+ inherited Render(aContext, aOutput, aBlockOverrides, aPrefix);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
Case L of
|
|
Case L of
|
|
mstSingle :
|
|
mstSingle :
|
|
- inherited Render(aContext, aOutput);
|
|
|
|
|
|
+ inherited Render(aContext, aOutput, aBlockOverrides);
|
|
mstList :
|
|
mstList :
|
|
while aContext.MoveNextSectionItem(Name) do
|
|
while aContext.MoveNextSectionItem(Name) do
|
|
- inherited Render(aContext, aOutput,aPrefix);
|
|
|
|
|
|
+ inherited Render(aContext, aOutput, aBlockOverrides, aPrefix);
|
|
end;
|
|
end;
|
|
if L<>mstNone then
|
|
if L<>mstNone then
|
|
aContext.PopSection(Name);
|
|
aContext.PopSection(Name);
|
|
@@ -819,7 +906,8 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TMustacheTextElement.Render(aContext: TMustacheContext;
|
|
procedure TMustacheTextElement.Render(aContext: TMustacheContext;
|
|
- aOutput: TMustacheOutput; const aPrefix: String; aLast : Boolean = False);
|
|
|
|
|
|
+ aOutput: TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil;
|
|
|
|
+ const aPrefix: String = ''; aLast : Boolean = False);
|
|
|
|
|
|
Var
|
|
Var
|
|
S : String;
|
|
S : String;
|
|
@@ -867,7 +955,8 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TMustacheVariableElement.Render(aContext: TMustacheContext;
|
|
procedure TMustacheVariableElement.Render(aContext: TMustacheContext;
|
|
- aOutput: TMustacheOutput; const aPrefix: String; aLast : Boolean = False);
|
|
|
|
|
|
+ aOutput: TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil;
|
|
|
|
+ const aPrefix: String = ''; aLast : Boolean = False);
|
|
|
|
|
|
Var
|
|
Var
|
|
aValue : TMustacheString;
|
|
aValue : TMustacheString;
|
|
@@ -979,7 +1068,7 @@ Var
|
|
|
|
|
|
function IsPartialTag: Boolean;
|
|
function IsPartialTag: Boolean;
|
|
begin
|
|
begin
|
|
- Result := (NewPos + lStart <= Total) and (aTemplate[NewPos + lStart] = '>');
|
|
|
|
|
|
+ Result := (NewPos + lStart <= Total) and (aTemplate[NewPos + lStart] in ['>','<']);
|
|
end;
|
|
end;
|
|
|
|
|
|
// check if the current tag occurs standalone on a line
|
|
// check if the current tag occurs standalone on a line
|
|
@@ -1006,7 +1095,7 @@ Var
|
|
repeat
|
|
repeat
|
|
pStop := Pos(cStop, aTemplate, I + lStart + 1);
|
|
pStop := Pos(cStop, aTemplate, I + lStart + 1);
|
|
if (Copy(aTemplate, I, lStart) = cStart) and (pStop > 0)
|
|
if (Copy(aTemplate, I, lStart) = cStart) and (pStop > 0)
|
|
- and (aTemplate[I + lStart] in ['=','#','!','^','>','/']) then
|
|
|
|
|
|
+ and (aTemplate[I + lStart] in ['=','#','!','^','>','/','<','$']) then
|
|
I := pStop + lStop
|
|
I := pStop + lStop
|
|
else
|
|
else
|
|
Break;
|
|
Break;
|
|
@@ -1087,7 +1176,7 @@ begin
|
|
if (aName='') then
|
|
if (aName='') then
|
|
Raise EMustache.CreateFmt(SErrEmptyTag,[cStart,Current]);
|
|
Raise EMustache.CreateFmt(SErrEmptyTag,[cStart,Current]);
|
|
C:=aName[1];
|
|
C:=aName[1];
|
|
- if C in ['=','#','^','/','!','>'] then
|
|
|
|
|
|
+ if C in ['=','#','^','/','!','>','<','$'] then
|
|
aName:=Copy(aName,2,Length(aName)-1);
|
|
aName:=Copy(aName,2,Length(aName)-1);
|
|
clStop:=Lstop; // Can change.
|
|
clStop:=Lstop; // Can change.
|
|
case C of
|
|
case C of
|
|
@@ -1122,7 +1211,7 @@ begin
|
|
CurrParent:=CreateElement(metInvertedSection,currParent,Current);
|
|
CurrParent:=CreateElement(metInvertedSection,currParent,Current);
|
|
CurrParent.SetData(aName);
|
|
CurrParent.SetData(aName);
|
|
end;
|
|
end;
|
|
- '>' :
|
|
|
|
|
|
+ '>','<' :
|
|
begin
|
|
begin
|
|
// Find or create compiled partial;
|
|
// Find or create compiled partial;
|
|
aName:=Trim(aName);
|
|
aName:=Trim(aName);
|
|
@@ -1136,16 +1225,32 @@ begin
|
|
DoParse(Partial,GetPartial(aName),FStartTag,FStopTag);
|
|
DoParse(Partial,GetPartial(aName),FStartTag,FStopTag);
|
|
end;
|
|
end;
|
|
// Create reference and insert into current tree
|
|
// Create reference and insert into current tree
|
|
- With CreateElement(metPartial,currParent,Current) do
|
|
|
|
|
|
+ if C='>' then // normal partial, no children, no end tag
|
|
|
|
+ With CreateElement(metPartial,currParent,Current) do
|
|
|
|
+ begin
|
|
|
|
+ AddChild(Partial);
|
|
|
|
+ Data:=aName;
|
|
|
|
+ Prefix := PartialPrefix;
|
|
|
|
+ end
|
|
|
|
+ else // parametric partial, may have children, end tag must follow
|
|
begin
|
|
begin
|
|
- AddChild(Partial);
|
|
|
|
- Data:=aName;
|
|
|
|
- Prefix := PartialPrefix;
|
|
|
|
|
|
+ CurrParent:=CreateElement(metParametricPartial,currParent,Current);
|
|
|
|
+ With CurrParent do
|
|
|
|
+ begin
|
|
|
|
+ AddChild(Partial);
|
|
|
|
+ Data:=aName;
|
|
|
|
+ Prefix := PartialPrefix;
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
+ '$' :
|
|
|
|
+ begin
|
|
|
|
+ CurrParent:=CreateElement(metBlock,currParent,Current);
|
|
|
|
+ CurrParent.SetData(aName);
|
|
|
|
+ end;
|
|
'/' :
|
|
'/' :
|
|
begin
|
|
begin
|
|
- if Not (CurrParent.ElementType in [metSection,metInvertedSection]) then
|
|
|
|
|
|
+ if Not (CurrParent.ElementType in [metSection,metInvertedSection,metParametricPartial,metBlock]) then
|
|
Raise EMustache.CreateFmt(SErrNoSectionToClose,[aName,Current])
|
|
Raise EMustache.CreateFmt(SErrNoSectionToClose,[aName,Current])
|
|
else if (CurrParent.Data<>Trim(aName)) then
|
|
else if (CurrParent.Data<>Trim(aName)) then
|
|
Raise EMustache.CreateFmt(SErrSectionClose,[currParent.Data,CurrParent.Position,aName,Current])
|
|
Raise EMustache.CreateFmt(SErrSectionClose,[currParent.Data,CurrParent.Position,aName,Current])
|
|
@@ -1229,14 +1334,36 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TMustacheParentElement.Render(aContext: TMustacheContext;
|
|
procedure TMustacheParentElement.Render(aContext: TMustacheContext;
|
|
- aOutput: TMustacheOutput; const aPrefix: String; aLast : Boolean = False);
|
|
|
|
|
|
+ aOutput: TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil;
|
|
|
|
+ const aPrefix: String = ''; aLast : Boolean = False);
|
|
|
|
|
|
Var
|
|
Var
|
|
I : integer;
|
|
I : integer;
|
|
|
|
|
|
begin
|
|
begin
|
|
For I:=0 to ChildCount-1 do
|
|
For I:=0 to ChildCount-1 do
|
|
- Children[I].Render(aContext,aOutPut,aPrefix,I=ChildCount-1);
|
|
|
|
|
|
+ Children[I].Render(aContext,aOutPut,aBlockOverrides,aPrefix,I=ChildCount-1);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+{ TMustacheBlockElement }
|
|
|
|
+
|
|
|
|
+procedure TMustacheBlockElement.Render(aContext: TMustacheContext;
|
|
|
|
+ aOutput: TMustacheOutput; aBlockOverrides : TMustacheBlockOverrideList = Nil;
|
|
|
|
+ const aPrefix: String = ''; aLast : Boolean = False);
|
|
|
|
+
|
|
|
|
+Var
|
|
|
|
+ I : integer;
|
|
|
|
+ BlockToRender : TMustacheElement;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ if aBlockOverrides = Nil then
|
|
|
|
+ Raise EMustache.Create('Block elements need an instance of TMustacheBlockOverrideList');
|
|
|
|
+ BlockToRender:=aBlockOverrides.FindFirst(Self.Data);
|
|
|
|
+ if BlockToRender=nil then
|
|
|
|
+ BlockToRender:=Self;
|
|
|
|
+
|
|
|
|
+ For I:=0 to BlockToRender.ChildCount-1 do
|
|
|
|
+ BlockToRender.Children[I].Render(aContext,aOutPut,aBlockOverrides,aPrefix,I=BlockToRender.ChildCount-1);
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TMustacheElement }
|
|
{ TMustacheElement }
|
|
@@ -1310,5 +1437,7 @@ begin
|
|
TMustacheParser.SetDefaultTypeClass(metSection,TMustacheSectionElement);
|
|
TMustacheParser.SetDefaultTypeClass(metSection,TMustacheSectionElement);
|
|
TMustacheParser.SetDefaultTypeClass(metInvertedSection,TMustacheSectionElement);
|
|
TMustacheParser.SetDefaultTypeClass(metInvertedSection,TMustacheSectionElement);
|
|
TMustacheParser.SetDefaultTypeClass(metPartial,TMustachePartialElement);
|
|
TMustacheParser.SetDefaultTypeClass(metPartial,TMustachePartialElement);
|
|
|
|
+ TMustacheParser.SetDefaultTypeClass(metParametricPartial,TMustachePartialElement);
|
|
|
|
+ TMustacheParser.SetDefaultTypeClass(metBlock,TMustacheBlockElement);
|
|
end.
|
|
end.
|
|
|
|
|