templates: Add {{#let}} block helper.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2021-04-05 13:05:31 -07:00 committed by Tim Abbott
parent e83538167f
commit f81cc16a0f
5 changed files with 46 additions and 0 deletions

View File

@ -28,6 +28,21 @@ run_test("or", () => {
assert.equal(html, "\n<p>last or</p>\n<p>true or</p>\n");
});
run_test("let", () => {
const html = require("./templates/let.hbs")({
outer_var: "hello",
});
assert.equal(
html,
`\
outer_var = hello
keyword_var = &lt;b&gt;escaped&lt;/b&gt;
block_var = <b>unescaped</b> with hello
`,
);
});
run_test("rendered_markdown", () => {
const html = require("./templates/rendered_markdown.hbs")();
const expected_html =

View File

@ -0,0 +1,8 @@
{{#let keyword_var="<b>escaped</b>"}}
{{#*inline "block_var"}}
<b>unescaped</b> with {{outer_var}}
{{/inline}}
outer_var = {{outer_var}}
keyword_var = {{keyword_var}}
block_var = {{block_var}}
{{/let}}

View File

@ -48,6 +48,26 @@ Handlebars.registerHelper({
not(a) {
return !a || Handlebars.Utils.isEmpty(a);
},
["let"](options) {
// Defines locally scoped variables.
// Example usage:
// {{#let name1="value1"}}
// {{#*inline "name2"}}
// value2
// {{/inline}}
// Now {{name1}} and {{name2}} are in scope.
// {{/let}}
return options.fn({
...this,
...options.hash,
...Object.fromEntries(
Object.entries(options.fn.partials ?? {}).map(([name, value]) => [
name,
new Handlebars.SafeString(value(this)),
]),
),
});
},
});
// Note that this i18n caching strategy does not allow us to support

View File

@ -133,6 +133,8 @@ def tokenize(text: str) -> List[Token]:
elif looking_at_handlebars_start():
s = get_handlebars_tag(text, state.i)
tag = s[3:-2].split()[0]
if tag.startswith("*"):
tag = tag[1:]
kind = "handlebars_start"
elif looking_at_handlebars_end():
s = get_handlebars_tag(text, state.i)

View File

@ -148,6 +148,7 @@ export default (_env: unknown, argv: {mode?: string}): webpack.Configuration[] =
"and",
"or",
"not",
"let",
"t",
"tr",
"rendered_markdown",