Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix imports #101

Merged
merged 5 commits into from
Aug 10, 2024
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
35 changes: 34 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,37 @@ tests/basic/test_if
tests/basic/test_if_complex
tests/basic/test_insert
tests/basic/test_simple
tests/basic/test_while
tests/basic/test_while
src/nimja/parser
src/nimja/sharedhelper
tests/basic/NOT_READY_test_raw
tests/basic/test_endless_iterator
tests/basic/test_file_foo_html
tests/basic/test_iterator
tests/basic/test_lexer
tests/basic/test_module_import
tests/basic/test_nimjautils
tests/basic/test_proc
tests/basic/test_proc_import
tests/basic/test_scope
tests/basic/test_self
tests/basic/test_shorhands
tests/basic/test_strparse
tests/basic/test_tmplf_with_context
tests/basic/test_tmpls_with_context
tests/basic/test_tokens_before_extend
tests/basic/test_triple
tests/basic/test_unicode
tests/basic/test_when
tests/basic/test_whitespacecontrol
tests/basic/test_blockInBlock
tests/basic/test_blockNotExtendedMaster
tests/basic/test_blockRenderMasterDirectly
tests/basic/test_case
tests/basic/test_condense_strings
tests/basic/test_double_extend
tests/basic/test_doublicated_blocks
tests/basic/theModule/theModule
tests/bugs/test_nwt_bug4_debug
examples/prologue/serverPrologue
examples/prologue/serverJester
2 changes: 1 addition & 1 deletion examples/fromReadme/server.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ proc renderIndex(title: string, users: seq[User]): string =
## so it can access all variables like `title` and `users`
## the return variable could be `string` or `Rope` or
## anything which has a `&=`(obj: YourObj, str: string) proc.
compileTemplateFile(getScriptDir() / "index.nimja")
compileTemplateFile("index.nimja", baseDir = getScriptDir())

proc main {.async.} =
var server = newAsyncHttpServer()
Expand Down
6 changes: 3 additions & 3 deletions examples/prologue/serverJester.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ const users = @[
]

proc renderIndex(title: string, users: seq[User]): string =
compileTemplateFile(getScriptDir() / "index.nimja")
compileTemplateFile("index.nimja", baseDir = getScriptDir())

proc renderUser(title: string, idx: int, users: seq[User]): string =
let user = users[idx]
compileTemplateFile(getScriptDir() / "user.nimja")
compileTemplateFile("user.nimja", baseDir = getScriptDir())

proc renderError(title: auto, code: HttpCode, users: seq[User]): string =
## title is `auto` here; nim generics work as well!
compileTemplateFile(getScriptDir() / "error.nimja")
compileTemplateFile("error.nimja", baseDir = getScriptDir())

routes:
get "/":
Expand Down
6 changes: 3 additions & 3 deletions examples/prologue/serverPrologue.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ method extend(ctx: Context) =
]

proc renderIndex(title: string, users: seq[User]): string =
compileTemplateFile(getScriptDir() / "index.nimja")
compileTemplateFile("index.nimja", baseDir = getScriptDir())

proc renderUser(title: string, idx: int, users: seq[User]): string =
let user = users[idx]
compileTemplateFile(getScriptDir() / "user.nimja")
compileTemplateFile("user.nimja", baseDir = getScriptDir())

proc renderError(title: auto, code: HttpCode, users: seq[User]): string =
## title is `auto` here; nim generics work as well!
compileTemplateFile(getScriptDir() / "error.nimja")
compileTemplateFile("error.nimja", baseDir = getScriptDir())

proc hello*(ctx: Context) {.async.} =
resp renderIndex("someTitle", UserContext(ctx).users)
Expand Down
2 changes: 1 addition & 1 deletion nimja.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Package

version = "0.8.7"
version = "0.9.0"

author = "David Krause"
description = "typed and compiled template engine inspired by jinja2, twig and onionhammer/nim-templates for Nim."
Expand Down
34 changes: 26 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ proc renderIndex(title: string, users: seq[User]): string =
## so it can access all variables like `title` and `users`
## the return variable could be `string` or `Rope` or
## anything which has a `&=`(obj: YourObj, str: string) proc.
compileTemplateFile(getScriptDir() / "index.nimja")
compileTemplateFile("index.nimja", baseDir = getScriptDir())

proc main {.async.} =
var server = newAsyncHttpServer()
Expand Down Expand Up @@ -258,7 +258,7 @@ you should use it like so:
```nim
import os # for `/`
proc myRenderProc(someParam: string): string =
compileTemplateFile(getScriptDir() / "myFile.html")
compileTemplateFile("myFile.html", baseDir = getScriptDir())

echo myRenderProc("test123")
```
Expand Down Expand Up @@ -379,7 +379,7 @@ situations where you want to inline a render call.
```nim
let leet = 1337
echo tmpls("foo {{leet}}")
echo tmplf(getScriptDir() / "templates" / "myfile.nimja")
echo tmplf("templates" / "myfile.nimja", baseDir = getScriptDir())
```

A context can be supplied to the template, to override variable names:
Expand Down Expand Up @@ -474,6 +474,9 @@ template and therefore can be included.

This way you create reusable template blocks to use all over your webpage.

(Since Nimja 0.9.0) If you import other templates, make sure to use the `baseDir` param with
`tmpls`, `tmplf`, `compileTemplateString` and `compileTemplateFile`.

partials/_user.nimja:
```twig
<div class="col-3">
Expand Down Expand Up @@ -501,6 +504,8 @@ a child template can extend a master template.
So that placeholder blocks in the master are filled
with content from the child.

(Since Nimja 0.9.0) If you extend other templates, make sure to use the `baseDir` param with
`tmpls`, `tmplf`, `compileTemplateString` and `compileTemplateFile`.

partials/_master.nimja
```twig
Expand All @@ -525,7 +530,7 @@ if the child.nimja is compiled then rendered like so:

```nim
proc renderChild(): string =
compileTemplateFile(getScriptDir() / "child.nimja")
compileTemplateFile("child.nimja", baseDir = getScriptDir())

echo renderChild()
```
Expand Down Expand Up @@ -780,7 +785,7 @@ Good for documentation etc..

```nim
proc test(): string =
let path = (getScriptDir() / "tests/basic" / "includeRawT.txt")
let path = ("tests/basic" / "includeRawT.txt", baseDir = getScriptDir())
compileTemplateStr("""pre{{ includeRaw(path) }}suf""")
```

Expand Down Expand Up @@ -1012,10 +1017,10 @@ import os # for `/`

proc index*(): string {.exportc, dynlib.} =
var foos = 1351 # change me i'm dynamic :)
compileTemplateFile(getScriptDir() / "templates/index.nimja")
compileTemplateFile("templates/index.nimja", baseDir = getScriptDir())

proc detail*(id: string): string {.exportc, dynlib.} =
compileTemplateFile(getScriptDir() / "templates/detail.nimja")
compileTemplateFile("templates/detail.nimja", baseDir = getScriptDir())

```

Expand Down Expand Up @@ -1107,9 +1112,22 @@ Changelog
=========

## TODO
- 0.8.?
- 0.?.?
- Added context to `importnimja`
## DONE
- 0.9.0
- BREAKING CHANGE!
- in order to fix #15 & #89 and to enable nimja components imported from other modules,
all proc (`tmpls`, `tmplf`, `compileTemplateString` and `compileTemplateFile`) got a `baseDir` param:
```
compileTemplateStr("""{{importnimja "some/template.nimja"}}""", baseDir = getScriptDir())
tmpls("""{{importnimja "some/template.nimja"}}""", baseDir = getScriptDir())
compileTemplateFile("some/template.nimja", baseDir = getScriptDir())
tmpls("some/template.nimja", baseDir = getScriptDir())
```
The use of `tmplf(getScriptDir() / "foo.nimja")` is discourage, use `tmplf("foo.nimja", baseDir = getScriptDir())` instead.
The old way could still work in some cirumstances though.
But its neccesary if you plan to import your nimja template code into other code.
- 0.8.7
- Removed unused `NImport`.
- Error on uneven `when` blocks.
Expand Down
41 changes: 22 additions & 19 deletions src/nimja/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ var cacheNwtNode {.compileTime.}: Table[string, seq[NwtNode]] ## a cache for ren
var cacheNwtNodeFile {.compileTime.}: Table[Path, string] ## a cache for content of a path
var nwtIter {.compileTime.} = false
var nwtVarname {.compileTime.}: string
var nwtBaseDir {.compileTime.}: string
var blocks {.compileTime.} : Table[string, seq[NwtNode]]
var guessedStringLen {.compileTime.} = 0

Expand Down Expand Up @@ -292,8 +293,7 @@ converter singleNwtNodeToSeq(nwtNode: NwtNode): seq[NwtNode] =
return @[nwtNode]

proc importNimja(nodes: var seq[NwtNode], path: string) =
const basePath = getScriptDir()
var str = read(basePath / path)
var str = read(nwtBaseDir / path)
nodes = compile(str)

proc parseSecondStepOne(fsTokens: seq[FSNode], pos: var int): seq[NwtNode] =
Expand Down Expand Up @@ -665,20 +665,20 @@ proc loadCacheFile(path: Path): string =
## The second time the same file should be read
## it is returned from the cache
when defined(nwtCacheOff):
return read(path)
return read(nwtBaseDir / path)
else:
if cacheNwtNodeFile.contains(path):
return cacheNwtNodeFile[path]
if cacheNwtNodeFile.contains(nwtBaseDir / path):
return cacheNwtNodeFile[nwtBaseDir / path]
else:
cacheNwtNodeFile[path] = read(path)
return cacheNwtNodeFile[path]
cacheNwtNodeFile[nwtBaseDir / path] = read(nwtBaseDir / path)
return cacheNwtNodeFile[nwtBaseDir / path]

proc extend(str: string, templateCache: var Deque[seq[NwtNode]]) =
var secondsStepTokens = loadCache(str)
let foundExtendAt = validExtend(secondsStepTokens)
if foundExtendAt > -1:
templateCache.addFirst secondsStepTokens
let ext = loadCacheFile(getScriptDir() / secondsStepTokens[foundExtendAt].extendsPath)
let ext = loadCacheFile(secondsStepTokens[foundExtendAt].extendsPath)
extend(ext, templateCache)
else:
templateCache.addFirst secondsStepTokens
Expand Down Expand Up @@ -784,7 +784,7 @@ template tmplsMacroImpl() =
alias.add body
result.add alias

macro compileTemplateStr*(str: typed, iter: static bool = false,
macro compileTemplateStr*(str: typed, baseDir: static string = "", iter: static bool = false,
varname: static string = "result", context: untyped = nil): untyped =
## Compiles a Nimja template from a string.
##
Expand Down Expand Up @@ -825,11 +825,13 @@ macro compileTemplateStr*(str: typed, iter: static bool = false,
# Please note, currently the context **cannot be** procs/funcs etc.
nwtVarname = varname
nwtIter = iter
nwtBaseDir = baseDir
echo "inCompileTemplateStr: ", nwtBaseDir
tmplsMacroImpl()
doCompile(str.strVal, result)

macro compileTemplateFile*(path: static string, iter: static bool = false,
varname: static string = "result", context: untyped = nil): untyped =
macro compileTemplateFile*(path: static string, baseDir: static string = "", iter: static bool = false,
varname: static string = "result", context: untyped = nil): untyped =
## Compiles a Nimja template from a file.
##
## .. code-block:: nim
Expand Down Expand Up @@ -866,16 +868,17 @@ macro compileTemplateFile*(path: static string, iter: static bool = false,
##
nwtVarname = varname
nwtIter = iter
nwtBaseDir = baseDir
let str = loadCacheFile(path)
tmplsMacroImpl()
doCompile(str, result)

template tmplsImpl(str: static string): string =
template tmplsImpl(str: static string, baseDir: static string): string =
var nimjaTmplsVar: string
compileTemplateStr(str, varname = astToStr nimjaTmplsVar)
compileTemplateStr(str, baseDir, varname = astToStr nimjaTmplsVar)
nimjaTmplsVar

macro tmpls*(str: static string, context: untyped = nil): string =
macro tmpls*(str: static string, baseDir: static string = "", context: untyped = nil): string =
## Compiles a Nimja template string and returns directly.
## Can be used inline, without a wrapper proc.
##
Expand All @@ -895,14 +898,14 @@ macro tmpls*(str: static string, context: untyped = nil): string =
##
tmplsMacroImpl()
result.add quote do:
tmplsImpl(`str`)
tmplsImpl(`str`, `baseDir`)

template tmplfImpl(path: static string): string =
template tmplfImpl(path: static string, baseDir: static string = "",): string =
var nimjaTmplfVar: string
compileTemplateFile(path, varname = astToStr nimjaTmplfVar)
compileTemplateFile(path, baseDir, varname = astToStr nimjaTmplfVar)
nimjaTmplfVar

macro tmplf*(str: static string, context: untyped = nil): string =
macro tmplf*(str: static string, baseDir: static string = "", context: untyped = nil): string =
## Compiles a Nimja template file and returns directly.
## Can be used inline, without a wrapper proc.
##
Expand All @@ -921,4 +924,4 @@ macro tmplf*(str: static string, context: untyped = nil): string =
##
tmplsMacroImpl()
result.add quote do:
tmplfImpl(`str`)
tmplfImpl(`str`, `baseDir`)
3 changes: 2 additions & 1 deletion src/nimja/sharedhelper.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ template read*(path: untyped): untyped =
staticRead(path)
else:
readFile(path)


template getScriptDir*(): string =
## Helper for staticRead.
##
## returns the absolute path to your project, on compile time.
getProjectPath()
instantiationInfo(-1, true).filename.parentDir()
6 changes: 3 additions & 3 deletions tests/basic/test_block.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import unittest
block:
## Test compileTemplateFile
proc index(title: auto, body: auto): string =
compileTemplateFile("../templates/blockIndex.nimja")
compileTemplateFile("../templates/blockIndex.nimja", baseDir = getScriptDir())

proc master(): string =
compileTemplateFile("../templates/blockMaster.nimja")
compileTemplateFile("../templates/blockMaster.nimja", baseDir = getScriptDir())

check index("title", "FOO") == "<html><title>title</title><body>FOO</body></html>"
check index("", "") == "<html><title></title><body></body></html>"
Expand All @@ -23,4 +23,4 @@ block:
compileTemplateStr("""{%extends "../templates/blockMaster.nimja"%}{%block mytitle%}{{title}}{%endblock%}{%block mybody%}{{body}}{%endblock%}""")
check index("title", "FOO") == "<html><title>title</title><body>FOO</body></html>"
check index("", "") == "<html><title></title><body></body></html>"
check index(1, 2) == "<html><title>1</title><body>2</body></html>"
check index(1, 2) == "<html><title>1</title><body>2</body></html>"
6 changes: 3 additions & 3 deletions tests/basic/test_blockInBlock.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import unittest
test "one block":
block:
proc child1(): string =
compileTemplateStr("{% extends test_block_in_block/master.nimja %}{%block inner%}newinner{%endblock%}")
compileTemplateStr("{% extends test_block_in_block/master.nimja %}{%block inner%}newinner{%endblock%}", baseDir = getScriptDir())
check child1() == "outer1newinnerouter2"

test "two blocks":
block:
proc child2(): string =
compileTemplateStr("{% extends test_block_in_block/master.nimja %}{%block outer%}newouter{%endblock%}")
check child2() == "newouter"
compileTemplateStr("{% extends test_block_in_block/master.nimja %}{%block outer%}newouter{%endblock%}", baseDir = getScriptDir())
check child2() == "newouter"
2 changes: 1 addition & 1 deletion tests/basic/test_blockRenderMasterDirectly.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ import ../../src/nimja
block:
## Render Master directly
proc master(): string =
compileTemplateFile("../templates/blockMasterWithContent.nimja")
compileTemplateFile("../templates/blockMasterWithContent.nimja", baseDir = getScriptDir())
echo master()
assert master() == """<html><title>TITLE</title><body>BODY</body></html>"""
Loading
Loading