Created
August 1, 2020 20:46
-
-
Save little-brother/c06114cf73cddfca1372c04e3e138867 to your computer and use it in GitHub Desktop.
How to use nunjucks in the browser/client-side
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
<!doctype html> | |
<html> | |
<head> | |
<meta charset = "UTF-8"/> | |
<title>Nunjucks example</title> | |
<script type = "module" src = "index.js"></script> | |
</head> | |
<body> | |
<div id = "page-content"></div> | |
</body> | |
</html> |
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
import njk from './njk.js'; | |
window.onload = function() { | |
const $e = document.querySelector('#page-content'); | |
const uri = 'https://quote-garden.herokuapp.com/api/v2/quotes/random'; | |
njk.render('index.njk', {abc: 'world', uri}, (err, html) => $e.innerHTML = err && err.message || html); | |
}; |
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
{# Use GET-extension to obtain data by uri #} | |
{% get req = uri %} | |
<p>Hello {{abc}}!</p> | |
<p>Current time: {{ now() | time }}</p> | |
<i>{{ req.quote.quoteText }}</i> {# print data #} |
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
import './nunjucks.min.js'; | |
const env = nunjucks.configure({autoescape: true, web: {async: true}}); | |
/* | |
With custom loader | |
const MyLoader = nunjucks.Loader.extend({ | |
async: true, | |
getSource: function(path, cb) { | |
fetch(path) // `/templates/${path}.njk` | |
.then(res => res.text()) | |
.then(src => cb(null, {src, path, noCache: false})) | |
.catch(cb); | |
} | |
}); | |
const env = new nunjucks.Environment(new MyLoader(), {autoescape: true}); | |
*/ | |
// Demo async extension to load remote data by url into variable | |
// {% get varname = "url" %} | |
function GetExtension(cb) { | |
this.tags = ['get']; | |
this.parse = function(parser, nodes, lexer) { | |
const tok = parser.nextToken(); | |
const args = parser.parseSignature(null, true); | |
parser.advanceAfterBlockEnd(tok.value); | |
return new nodes.CallExtensionAsync(this, 'run', args, cb); | |
}; | |
this.run = function(context, args, cb) { | |
const ref = args instanceof Object && Object.keys(args).filter(e => e != '__keywords')[0]; | |
const url = encodeURI(args[ref]); | |
const headers = {pragma: 'no-cache', 'cache-control': 'no-cache'} | |
fetch(url, {headers}) | |
.then(res => res.json()) | |
.then(function (res) { | |
if (res.error) | |
console.error(url, res.error); | |
context.ctx[ref] = res.error ? undefined : res; | |
cb && cb(); | |
}) | |
.catch(cb); | |
}; | |
} | |
env.addExtension('GetExtension', new GetExtension()); | |
// Like include-tag but async and passing args | |
// {{ 'another-template.njk' | render({abc: 10}) }} | |
// Don't use in macro because it's async | |
env.addFilter('render', function (template, ctx, cb) { | |
env.render(template, ctx, (err, html) => cb && cb(err, !err ? env.filters.safe(html) : undefined)) | |
}, true); // <-- | |
// Add another filters and global for demo | |
env.addFilter('print', console.log); | |
env.addFilter('time', datetime => new Date(+datetime).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})); | |
env.addGlobal('now', () => Date.now()); | |
export default env; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment