From 1f950b4de2d329752b7622d5b7fd59d3048b7613 Mon Sep 17 00:00:00 2001 From: kevind7 Date: Mon, 18 Jun 2018 15:10:16 +0800 Subject: [PATCH] Update handling of braces within ExtraHeader block to enable nesting of commands such as @if --- source/RlxRazor.pas | 14 ++--- test/TestRlxRazor.pas | 82 +++++++++++++++++++++++++++++ test/templates/testextraheader.html | 1 + 3 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 test/templates/testextraheader.html diff --git a/source/RlxRazor.pas b/source/RlxRazor.pas index 0ea1215..b95d84a 100755 --- a/source/RlxRazor.pas +++ b/source/RlxRazor.pas @@ -1100,12 +1100,14 @@ function TRlxRazorProcessor.RazorContentFromStream(AStream: TStream): string; end else if SameText (TokenStr, 'ExtraHeader') then begin - // Parser.SkipToToken('{'); - blockAsString := Encoding.GetString - (BytesOf(Parser.SkipToToken('}'))); - Parser.SkipToken(True); - // process the block - ParsedExtraHeader := DoBlock(RawByteString(blockAsString), Encoding); + if Parser.Token = '{' then + begin + blockAsString := FindMatchingClosingBrace; + // process the block + ParsedExtraHeader := DoBlock(RawByteString(blockAsString), Encoding); + end + else + AddWarning('missing { after ExtraHeader'); end else if SameText (TokenStr, 'RenderBody') then begin diff --git a/test/TestRlxRazor.pas b/test/TestRlxRazor.pas index 1547935..32926f9 100644 --- a/test/TestRlxRazor.pas +++ b/test/TestRlxRazor.pas @@ -80,6 +80,10 @@ TestTRlxRazorProcessor = class(TTestCase) procedure TestPermission; procedure TestWrongPermission; + // 7. extraheader + procedure TestExtraHeader; + procedure TestExtraHeaderNestedIf; + procedure TestExtraHeaderNestedIfWithinIf; end; implementation @@ -446,6 +450,84 @@ procedure TestTRlxRazorProcessor.TestWrongPermission; CheckException(RunLoginPermissionScript, ERlxLoginRequired); end; +procedure TestTRlxRazorProcessor.TestExtraHeader; +var + strBlock: string; + ReturnValue: string; + LRlxRazorEngine: TRlxRazorEngine; +begin + LRlxRazorEngine := TRlxRazorEngine.Create(nil); + try + strBlock := '@LayoutPage testextraheader'#13#10'@ExtraHeader {TestExtraHeader}'; + FRlxRazorProcessor.RazorEngine := LRlxRazorEngine; + FRlxRazorProcessor.RazorEngine.TemplatesFolder := '..\..\templates\'; + ReturnValue := FRlxRazorProcessor.DoBlock(strBlock); + CheckEquals (' TestExtraHeader', ReturnValue); + finally + FRlxRazorProcessor.RazorEngine := nil; + LRlxRazorEngine.Free; + end; +end; + +procedure TestTRlxRazorProcessor.TestExtraHeaderNestedIf; +var + strBlock: string; + ReturnValue: string; + LRlxRazorEngine: TRlxRazorEngine; + simpleObj: TSimpleObj; +begin + simpleObj := TSimpleObj.Create; + try + simpleObj.ABool := True; + FRlxRazorProcessor.AddToDictionary(SampleObjectName, SimpleObj, False); + LRlxRazorEngine := TRlxRazorEngine.Create(nil); + try + strBlock := '@LayoutPage testextraheader'#13#10'@ExtraHeader {@if ' + SampleObjectName + '.' + SampleBoolFieldName + + '{TestExtraHeaderNestedIf}}'; + FRlxRazorProcessor.RazorEngine := LRlxRazorEngine; + FRlxRazorProcessor.RazorEngine.TemplatesFolder := '..\..\templates\'; + ReturnValue := FRlxRazorProcessor.DoBlock(strBlock); + FRlxRazorProcessor.DataObjects.Remove(SampleObjectName); + CheckEquals (' TestExtraHeaderNestedIf', ReturnValue); + finally + FRlxRazorProcessor.RazorEngine := nil; + LRlxRazorEngine.Free; + end; + finally + simpleObj.Free; + end; +end; + +procedure TestTRlxRazorProcessor.TestExtraHeaderNestedIfWithinIf; +var + strBlock: string; + ReturnValue: string; + LRlxRazorEngine: TRlxRazorEngine; + simpleObj: TSimpleObj; +begin + simpleObj := TSimpleObj.Create; + try + simpleObj.ABool := True; + FRlxRazorProcessor.AddToDictionary(SampleObjectName, SimpleObj, False); + LRlxRazorEngine := TRlxRazorEngine.Create(nil); + try + strBlock := '@LayoutPage testextraheader'#13#10'@ExtraHeader {@if ' + SampleObjectName + '.' + SampleBoolFieldName + + '{@if ' + SampleObjectName + '.' + SampleBoolFieldName + '{TestExtraHeaderNestedIfWithinIf}}}'; + FRlxRazorProcessor.RazorEngine := LRlxRazorEngine; + FRlxRazorProcessor.RazorEngine.TemplatesFolder := '..\..\templates\'; + ReturnValue := FRlxRazorProcessor.DoBlock(strBlock); + FRlxRazorProcessor.DataObjects.Remove(SampleObjectName); + CheckEquals (' TestExtraHeaderNestedIfWithinIf', ReturnValue); + finally + FRlxRazorProcessor.RazorEngine := nil; + LRlxRazorEngine.Free; + end; + finally + simpleObj.Free; + end; +end; + + { TSimpleObj } procedure TSimpleObj.SetABool(const Value: Boolean); diff --git a/test/templates/testextraheader.html b/test/templates/testextraheader.html new file mode 100644 index 0000000..3d867f1 --- /dev/null +++ b/test/templates/testextraheader.html @@ -0,0 +1 @@ +@RenderHeader \ No newline at end of file