Closed matkuki closed 9 months ago
Thanks for trying Tim <3, note that this is still work in progress!
Don't forget to precompile your templates before rendering. Compile with -d:timHotCode
to enable the filesystem monitor
var timThread: Thread[void]
proc precompileEngine() {.thread.} =
{.gcsafe.}:
timl.precompile(
waitThread = true, # optional, keeps thread alive
flush = true, # flush old cache on reboot
)
createThread(timThread, precompileEngine)
Regarding your problem,timl
is a global var, but we can make use of gcsafe
pragma.
proc index_handler(request: Request) =
var headers: HttpHeaders
headers["Content-Type"] = "text/html"
{.gcsafe.}:
let content: string = timl.render("index") # safe for reading
request.respond(200, headers, content) # content is a string, no need for a `$` conversion
Add this JS snippet somewhere in your index
view (js snippets in a layout won't work right now).
@js
{
const watchout = new WebSocket('ws://127.0.0.1:6502/ws');
watchout.addEventListener('message', () => location.reload());
}
@end
Will add a full working example of Mummy + Tim.
Thanks for the quick reply @georgelemon ,
I have tried the modified example:
import
std/os,
mummy,
mummy/routers,
tim
var
timl = newTim(
src = "templates",
output = "storage",
basepath = currentSourcePath(),
minify = true,
indent = 2
)
timThread: Thread[void]
comm_channel: Channel[string]
proc precompileEngine() {.thread.} =
{.gcsafe.}:
timl.precompile(
waitThread = true, # optional, keeps thread alive
flush = true, # flush old cache on reboot
)
# Initialize Tim stuff
createThread(timThread, precompileEngine)
proc index_handler(request: Request) =
var headers: HttpHeaders
headers["Content-Type"] = "text/html"
{.gcsafe.}:
let content: string = timl.render("index")
request.respond(200, headers, content)
proc main() =
var router: Router
router.get("/", index_handler)
let
server = newServer(router)
ip_address = "0.0.0.0"
echo "Serving on http://localhost:8080"
server.serve(Port(8080), address=ip_address)
if is_main_module:
main()
... but now when I connect to the url, the application crashes with:
~/Nim/http_test_server/test$ nim c -r test2.nim
Hint: used config file '/home/user/.choosenim/toolchains/nim-2.0.2/config/nim.cfg' [Conf]
Hint: used config file '/home/user/.choosenim/toolchains/nim-2.0.2/config/config.nims' [Conf]
Hint: used config file '/home/user/Nim/http_test_server/nim.cfg' [Conf]
Hint: used config file '/home/user/Nim/http_test_server/test/nim.cfg' [Conf]
Hint: mm: orc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code)
10127 lines; 0.035s; 10.48MiB peakmem; proj: /home/user/Nim/http_test_server/test/test2.nim; out: /home/user/Nim/http_test_server
/test/test2 [SuccessX]
Hint: /home/user/Nim/http_test_server/test/test2 [Exec]
Serving on http://localhost:8080
Traceback (most recent call last)
/home/user/Nim/http_test_server/deps/mummy/src/mummy.nim(515) workerProc
/home/user/Nim/http_test_server/deps/mummy/src/mummy.nim(449) runTask
/home/user/Nim/http_test_server/deps/mummy/src/mummy/routers.nim(271) :anonymous
/home/user/Nim/http_test_server/test/test2.nim(46) index_handler
/home/user/Nim/http_test_server/deps/tim/src/tim.nim(208) render
/home/user/Nim/http_test_server/deps/tim/src/tim.nim(24) jitCompiler
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(1079) newCompiler
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(994) walkNodes
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(980) htmlElement
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(994) walkNodes
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(980) htmlElement
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(994) walkNodes
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(980) htmlElement
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(994) walkNodes
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(980) htmlElement
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(994) walkNodes
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(980) htmlElement
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(994) walkNodes
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(980) htmlElement
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(1030) walkNodes
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(699) evalConcat
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(523) getValue
/home/user/Nim/http_test_server/deps/tim/src/tim/engine/compilers/html.nim(173) toString
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Segmentation fault (core dumped)
That is because HtmlCompiler is trying to access some data from global storage. I just pushed some fixes (forgot to check for nil
when calling toString
). Reinstalling tim via nimble should do the trick.
Also, if you're using the /example dir, try expose some data to global storage:
import std/json
proc precompileEngine() {.thread.} =
{.gcsafe.}:
timl.precompile(
waitThread = true, # optional, keeps thread alive
flush = true, # flush old cache on reboot
global = %*{"year": 2024}
)
Where year
can be accessed in your timl templates using $app.year
Trying to access an undeclared field should prompt the following error:
Error (13:29) Undeclared field year
/.../example/templates/views/index.timl
Yes, excellent, it works as you described :+1:
Thanks
Hi,
I have tried to get
tim
with (mummy)[], but I cannot getrender
to work in a multi-threaded enivironment. Could you give me a working example of how to usetim
withmummy
? ThanksHere is my attempt: