Open georgelemon opened 7 months ago
Hi I have some questions about this:
To clarify further: if question1's answer is yes, then I think the better approach might be to copy what nimja is doing. Basically nimja templates can invoke any function in the same scope as the template render call(tmplf in the code sample below). Sample code below
$ cat index.nimja
<div>{{printNum1()}}<div/>
#FILE: server.nim
import nimja
proc printNum1(): int = 1
## Route Handlers
proc getLandingPage(): string =
result = tmplf(getScriptDir() & "/index.nimja")
echo getLandingPage() #<div>1<div/>
This approach can easily scale to all the languages Tim wishes to support although am not sure how the syntax or implementation details will work.
if question2's answer is yes, then if I understand correctly Tim users are provided with some extra built-in functions that they can use within their templates just like liquidjs templating engine's filters
. Hence these functions will never have sideffects and will only help to further transform their inputs into strings. In my opinion, the benefit of this approach is that it will be easier for people to find out the expected output of a Tim template because the calleable utilities are finite and can be found by looking in Nim's std lib.
I understand that the answer for both of these questions can be yes. In this case, tim will allow users to call functions/procedures in the same scope as the newEngine
invocation, while simultaenously offering builtin helper functions to users.
Thanks for reading and I look forward to getting a better understanding of this proposal
Well, yes, the main idea around @import
is to be able to expose functions from the host language into Tim templates.
This is going to be the expected behavior when using the S2S compilation via cli app.
So, @import "std/strings"
will be translated into import std/strutils
, when translating Tim code
to Nim via compilers/nimc.nim
. Also, there will be more S2S compilers, like py.nim
, js.nim
and more.
The current std.nim
is pretty experimental, and yes, will make Tim more than just a template engine.
This feature is already available in Tim when used as a Nimble package or Node/Bun environment as native .node
addon (I need to prepare Tim for publishing the npm package).
In addition to S2S compilation feature, the CLI will also provide the option to use Tim as a standalone microservice in background. So, there will be a run
command which basically wraps the current html.nim
engine + std.nim
+ caching + a communication channel powered by ZeroMQ.
Currently, exposing a function is possible by doing this
import pkg/tim
# initialize tim engine
var timEngine* = newTim("templates", "storage", currentSourcePath())
# initialize the local module
# note that `proc hello` is converted into `fn hello` in Tim.
# Also, this is pretty low-level and requires working with Tim's AST structure.
tim.initModule:
block:
proc hello(x: string): string =
# args[0].value is an ast.Node type of ntLitString
result = ast.newNode(ntLitString)
result.sVal = "Hello " & args[0].value.sVal
# ... precompilation and app setup
@import "*" // importing the local module. yes maybe `*` is not very specific
h1: hello("World!")
Obviously this works for Tim when used as a Nimble package.
For the CLI app
--app:lib
Thanks for clarifying, I love the direction you are taking it. I dont fully understand the implications of this
Tim microservice will allow a similar approach via plugins. Basically, we'll be able to expose extra functionality to Tim by compiling Nim code using --app:lib
but I will just observe and learn.
Tim should borrow some callable utilities from Nim's standard library
Tim's standard library in modules:
std/system
,std/strings
,std/arrays
,std/objects
,std/math
andstd/os
(read-only functions)