Nano is an eval()
-free template engine.
As with any template processor, the output is rendered by combining a string template and a data object.
import render from 'https://deno.land/x/nano/mod.ts';
const data = {
message: 'Hello',
shout: (value: string) => value + '!!!!',
};
const template = `<div>{shout(message)}</div>`;
const result = await render(template, data);
Result
<div>Hello!!!!</div>
<div>{2 + 2}</div>
<div>{my_variable}</div>
<div>{nested.property}</div>
<div>{nested['property'][0]}</div>
<div>{2 + 2 == 4 ? 'Yes' : 'No'}</div>
<div>{example_function(my_variable)}</div>
<div>{nested.function(other.variable)}</div>
<div>{nested(function(1, true, "foo", my_variable))}</div>
{if condition_1}
<!--foo-->
{else if condition_2}
<!--bar-->
{else}
<!--baz-->
{/if}
{for item in array_like}
<div>{item}</div>
{/for}
{for item, index in array_like}
<div>{item}</div>
{/for}
{for key, value in object_like}
<div>{item}</div>
{/for}
{for character, index in "hello"}
<div>{character}</div>
{/for}
{for number, index in 10}
<div>{number - 1} equals {index}</div>
{/for}
{switch value}
{case "a", "b", "c"}
<!--match if value equals "a" or "b" or "c"-->
{/case}
{case 20 + 5}
<!--or if value equals 20 + 5 (or any other expression)-->
{/case}
{default}
<!--else-->
{/default}
{/switch}
{import 'subfolder/other_file.html'}
The imported module will have access to the same data accessible to the scope it's being imported from:
<!-- list.html -->
{for fruit in fruits}
{import 'list_item.html'}
{/for}
<!-- list_item.html -->
<li>{fruit}</li>
It's also possible to define/rewrite variables using the with
keyword along with a list of (key: value)
pairs
<!-- list.html -->
{for fruit, index in fruits}
{import 'list_item.html' with (number: index + 1, other: "thing")}
{/for}
<!-- list_item.html -->
<li>{fruit} no. {number}</li>
Before reading a file from disk, the renderer will look for a matching template inside the data object first. If an object key matches the import path, the string value will be loaded as a template.
{import 'my_block.html'}
// data
{
'my_block.html': '<div>...</div>'
}
If/for/expression blocks can be flagged with !
or #
(or both) for removing whitespace around HTML tags or escape reserved HTML characters respectively.
In this example (with whitespace added for clarity), the following {for}
{for number in 10} ↩
⇥ <span>{number}</span> ↩
{/for}
will output
↩
⇥ <span>1</span> ↩
⇥ <span>2</span> ↩
⇥ <span>3</span> ↩
⇥ <span>4</span> ↩
however {!for}
{!for number in 10} ↩
⇥ <span>{number}</span> ↩
{/for}
will output
<span>1</span><span>2</span><span>3</span><span>4</span>
Similarly, for a variable named code
with the value
'<script>/* test */</script>';
the tag {code}
will output
<script>/* test */</script>
however {#code}
will output
<script>/* test */</script>