ZTemplate
a simple javascript syntax-friendly template engine (it means in the javascript editor/IDE, it wont show a lexical/syntax error or wrong syntax highlighting, the autocomplete will still works). You can use svelte-mpa if you need reactivity on each page.
Syntax
There's 4 tags:
/*! mapKey */
-- for HTML or CSS
#{mapKey}
-- for HTML, or if quoted can be used for Javascript string
[/* mapKey */]
-- for Javascript array
{/* mapKey */}
-- for Javascript object
You can switch around, it doesn't matter, but it would be better to use each differently so the frontend guy (if not yourself) knows what's the type.
Template Example
<html>
<head>
<title>/*! title */</title>
</head>
<body>
<script>
const a = +'#{ aNumber }';
const b = [/* anArray */];
const c = {/* aMap */};
const d = '#{aString}';
</script>
</body>
</html>
Usage Example
const autoReload = true
const printDebug = true
const fileName = `dummy.html`
tc, err := ParseFile(autoReload, printDebug, fileName)
if L.IsError(err, `filed Z.ParseFile: `+fileName) {
return err
}
buff := bytes.Buffer{}
tc.Render(&buff,M.SX{
`title`: `this is a title`,
`aNumber`: 123,
`anArray`: A.X{1,`b`,`c`,4}, // == []any
`aMap`: M.SX{ // == map[string]any
`a`:1,
`b`:`test`,
`c`:`something`,
},
`aString`: `ayaya`,
})
// buff.String() will contain the output below
Example Output
<html>
<head>
<title>this is a title</title>
</head>
<body>
<script>
const a = +'123';
const b = [1,"b","c",4];
const c = {"a":1,"b":"test","c":"something"};
const d = 'ayaya';
</script>
</body>
</html>
Example from string
note that it's preferable for FromString
to be reused (declared as global or cached) so it doesn't have to parse the template again and again.
const printDebug = true
res := bytes.Buffer{}
FromString(`hi my name #{name}, my age #{age}`,printDebug).Render(&res,M.SX{
`name`: `Tzuyu`,
`age`: 21,
})
res.String() == `hi my name Tzuyu, my age 21`
str := FromString(`i like #{char}`).Str(M.SX{
`char`: `Rem`,
})
str == `i like Rem`
How Fast is it?
Because of limited set of feature compared to Go's standard text/template.
# ~12x faster compared to text/template for parsing and rendering
BenchmarkParseRenderZTemplate-32 1697598 742.1 ns/op
BenchmarkParseRenderGoTemplate-32 152878 9237 ns/op
# ~4.8x faster compared to text/template for rendering only
BenchmarkRenderZTemplate-32 8543964 139.4 ns/op
BenchmarkRenderGoTemplate-32 1736002 678.9 ns/op
- build/load the template once (
Z.ParseFile
or Z.FromString
), call .Render
multiple times
- preallocate
bytes.Buffer
so it won't need to resize, eg. using valyala/bytebufferpool or sync.Pool
- for static values, use another caching library like
bigcache
so no need to call .Render
again and again, the render itself is fast O(n)
where n
is the bytes, but the serialization to JSON string might be slow.