Created
February 5, 2022 06:30
-
-
Save reedspool/a0c9efaad855440d29e1ced4c841bbe7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Nunjucks template rendering hyperscript extension | |
* | |
* Adds command `render <expr> [with <namedArgumentList>] [into <expr>]` | |
* | |
* Expression may be an element or a pre-compiled nunjucks template (via `compile template`) | |
* | |
* ex: | |
* `<template id="tmpl-my-template">Hello, {{ hello }}</template>` | |
* `render #tmpl-my-template with (hello: 'world') into <body />` | |
* | |
* ex: | |
* | |
* `<template _="init precompile me into $myTemplate">Hello, {{ hello }}</template>` | |
* `render $myTemplate with (hello: 'world')` | |
* `put the result at the start of <body />` | |
* | |
* Adds command `precompile <expr> #tmpl-my-template [into $myTemplate]` | |
* | |
* @param {HyperscriptObject} _hyperscript | |
*/ | |
const hyperscriptNunjucksExtension = _hyperscript => { | |
_hyperscript.addCommand("render", function(parser, runtime, tokens) { | |
if (!tokens.matchToken("render")) return; | |
var template_ = parser.requireElement("expression", tokens); | |
var templateArgs = {}; | |
if (tokens.matchToken("with")) { | |
templateArgs = parser.parseElement("namedArgumentList", tokens); | |
} | |
if (tokens.matchToken("into")) { | |
var target_ = parser.requireElement("expression", tokens); | |
} | |
return { | |
args: [template_, templateArgs, target_], | |
op: function(ctx, template, templateArgs, target) { | |
if (template.__nunjucks_precompiled) { | |
ctx.result = template.render(templateArgs); | |
} else { | |
if (!(template instanceof Element)) throw new Error(template_.sourceFor() + " is not an element"); | |
ctx.result = nunjucks.renderString(template.innerHTML, templateArgs); | |
} | |
if (target) { | |
if (Array.isArray(target)) target = target[0] | |
if (!(target instanceof Element)) throw new Error(target_.sourceFor() + " is not an element"); | |
target.innerHTML = ctx.result; | |
} | |
return runtime.findNext(this, ctx); | |
}, | |
}; | |
}); | |
_hyperscript.addCommand("precompile", function(parser, runtime, tokens) { | |
if (!tokens.matchToken("precompile")) return; | |
var template_ = parser.requireElement("expression", tokens); | |
if (tokens.matchToken("into")) { | |
var target = parser.requireElement("symbol", tokens); | |
} | |
return { | |
args: [template_], | |
op: function(ctx, template) { | |
if (!(template instanceof Element)) throw new Error(template_.sourceFor() + " is not an element"); | |
ctx.result = nunjucks.compile(template.innerHTML); | |
ctx.result.__nunjucks_precompiled = true; | |
if (target) { | |
runtime.setSymbol(target.name, ctx, target.scope, ctx.result); | |
} | |
return runtime.findNext(this, ctx); | |
}, | |
}; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Will one need to run processNode?