diff --git a/src/nimja/parser.nim b/src/nimja/parser.nim index 7ba7d84..501d7e8 100644 --- a/src/nimja/parser.nim +++ b/src/nimja/parser.nim @@ -88,7 +88,7 @@ when defined(dumpNwtAstPretty): proc parseSecondStep(fsTokens: seq[FSNode], pos: var int): seq[NwtNode] proc parseSecondStepOne(fsTokens: seq[FSNode], pos: var int): seq[NwtNode] proc astAst(tokens: seq[NwtNode]): seq[NimNode] -proc compile(str: string): seq[NwtNode] +proc compile(str: string, blockToRender: string = ""): seq[NwtNode] proc astAstOne(token: NwtNode): NimNode func mustStrip(token: Token): tuple[token: Token, stripPre, stripPost: bool] = @@ -294,7 +294,7 @@ converter singleNwtNodeToSeq(nwtNode: NwtNode): seq[NwtNode] = proc importNimja(nodes: var seq[NwtNode], path: string) = var str = read(nwtBaseDir / path) - nodes = compile(str) + nodes = compile(str, blockToRender = "") # TODO proc parseSecondStepOne(fsTokens: seq[FSNode], pos: var int): seq[NwtNode] = let fsToken = fsTokens[pos] @@ -703,14 +703,26 @@ proc fillBlocks(nodes: seq[NwtNode]): seq[NwtNode] = else: result.add node -proc compile(str: string): seq[NwtNode] = +proc compile(str: string, blockToRender: string = ""): seq[NwtNode] = var templateCache = initDeque[seq[NwtNode]]() extend(str, templateCache) for idx, tmp in enumerate(templateCache): for nwtn in tmp.recursiveFindAllBlocks(): + # echo nwtn.blockName ## HERE ## TODO remove blocks[nwtn.blockName] = nwtn.blockBody - var base = templateCache[0] - return fillBlocks(base).condenseStrings() # ast condense after blocks are filled + if blockToRender == "": + var base = templateCache[0] + # return fillBlocks(base).condenseStrings() # ast condense after blocks are filled # TODO remove + result = fillBlocks(base).condenseStrings() # ast condense after blocks are filled + else: + if blocks.contains(blockToRender): + result = blocks[blockToRender].condenseStrings() + else: + # {.error: "Block '" & blockToRender & "' is not known."} + echo "Block '" & blockToRender & "' is not known." # TODO how communicate the error? + # return # TODO should we return here or quit? + quit() + # echo result proc generatePreallocatedStringDef(len: int): NimNode = @@ -739,9 +751,9 @@ proc generatePreallocatedStringDef(len: int): NimNode = ) -template doCompile(str: untyped, res = newStmtList()): untyped = +template doCompile(str: untyped, blockToRender: string = "", res = newStmtList()): untyped = guessedStringLen = 0 - let nwtNodes = compile(str) + let nwtNodes = compile(str, blockToRender) when defined(dumpNwtAst): echo nwtNodes when defined(dumpNwtAstPretty): echo nwtNodes.pretty result = res @@ -785,7 +797,7 @@ template tmplsMacroImpl() = result.add alias macro compileTemplateStr*(str: typed, baseDir: static string = "", iter: static bool = false, - varname: static string = "result", context: untyped = nil): untyped = + varname: static string = "result", blockToRender: static string = "", context: untyped = nil): untyped = ## Compiles a Nimja template from a string. ## ## .. code-block:: Nim @@ -827,10 +839,10 @@ macro compileTemplateStr*(str: typed, baseDir: static string = "", iter: static nwtIter = iter nwtBaseDir = baseDir tmplsMacroImpl() - doCompile(str.strVal, result) + doCompile(str.strVal, blockToRender, result) macro compileTemplateFile*(path: static string, baseDir: static string = "", iter: static bool = false, - varname: static string = "result", context: untyped = nil): untyped = + varname: static string = "result", blockToRender: static string = "", context: untyped = nil): untyped = ## Compiles a Nimja template from a file. ## ## .. code-block:: nim @@ -870,7 +882,7 @@ macro compileTemplateFile*(path: static string, baseDir: static string = "", ite nwtBaseDir = baseDir let str = loadCacheFile(path) tmplsMacroImpl() - doCompile(str, result) + doCompile(str, blockToRender, result) template tmplsImpl(str: static string, baseDir: static string): string = var nimjaTmplsVar: string diff --git a/tests/basic/fragments/base.nimja b/tests/basic/fragments/base.nimja new file mode 100644 index 0000000..6845aa3 --- /dev/null +++ b/tests/basic/fragments/base.nimja @@ -0,0 +1,4 @@ +header +{% block title %}title to replace{% endblock %} +{% block content %}content to replace{% endblock %} +footer diff --git a/tests/basic/fragments/index.nimja b/tests/basic/fragments/index.nimja new file mode 100644 index 0000000..267ed64 --- /dev/null +++ b/tests/basic/fragments/index.nimja @@ -0,0 +1,5 @@ +{% extends fragments/base.nimja %} +{% block title %}title from index{% endblock %} +{% block content %}content from index{% endblock %} + + diff --git a/tests/basic/test_fragments.nim b/tests/basic/test_fragments.nim new file mode 100644 index 0000000..f903970 --- /dev/null +++ b/tests/basic/test_fragments.nim @@ -0,0 +1,61 @@ +discard """ + joinable: false +""" +import ../../src/nimja +import unittest + +suite "fragments": + + test "compileTemplateStr simple": + proc foo(blockToRender: static string): string = + compileTemplateStr(""" + BUG + {% block first %}first block{% endblock %} + {% block second %}second block{% endblock %} + BUG + """, blockToRender = blockToRender) + + check "first block" == foo("first") + check "second block" == foo("second") + + + + test "compileTemplateStr simple with self": + proc foo(blockToRender: static string): string = + compileTemplateStr(""" + BUG + {% block first %}first{{self.inner}}block{% endblock %} + {% block second %}second{{self.inner}}block{% endblock %} + {% block inner %} inner {% endblock %} + BUG + """, blockToRender = blockToRender) + + check "first inner block" == foo("first") + check "second inner block" == foo("second") + + + test "compileTemplateStr simple with var": + proc foo(ii: int, blockToRender: static string): string = + compileTemplateStr(""" + BUG + {% block first %}first{{self.inner}}block{% endblock %} + {% block second %}second{{self.inner}}block{% endblock %} + {% block inner %} {{ii}} {% endblock %} + BUG + """, blockToRender = blockToRender) + + check "first 1337 block" == foo(1337, "first") + check "second 1337 block" == foo(1337, "second") + + + + + test "compileTemplateFile simple": + proc foo(fileToRender: static string, blockToRender: static string): string = + compileTemplateFile(fileToRender, blockToRender = blockToRender, baseDir = getScriptDir()) + check "title from index" == foo("fragments/index.nimja", "title") ## TODO test this error message! + check "content from index" == foo("fragments/index.nimja", "content") ## TODO test this error message! + + check "title to replace" == foo("fragments/base.nimja", "title") ## TODO test this error message! + check "content to replace" == foo("fragments/base.nimja", "content") ## TODO test this error message! +