Skip to content

Instantly share code, notes, and snippets.

@cetver
Created March 24, 2022 14:18
Show Gist options
  • Save cetver/d9cc0f523e37fa28d74951a0448bcf98 to your computer and use it in GitHub Desktop.
Save cetver/d9cc0f523e37fa28d74951a0448bcf98 to your computer and use it in GitHub Desktop.
twigjs: needs_context, needs_environment
// twig/factory.js
'use strict';
const Twig = require('twig');
module.exports = function () {
Twig.extend(twig => {
function parseParams(state, params, context) {
if (params) {
return twig.expression.parseAsync.call(state, params, context);
}
return twig.Promise.resolve(false);
}
// node_modules/twig/src/twig.expression.js -> type: Twig.expression.type._function
twig.expression.extend({
type: twig.expression.type._function,
// Match any letter or _, then any number of letters, numbers, _ or - followed by (
regex: /^([a-zA-Z_]\w*)\s*\(/,
next: twig.expression.type.parameter.start,
validate(match) {
// Make sure this function is not a reserved word
return match[1] && (!twig.expression.reservedWords.includes(match[1]));
},
transform() {
return '(';
},
compile(token, stack, output) {
const fn = token.match[1];
token.fn = fn;
// Cleanup token
delete token.match;
delete token.value;
output.push(token);
},
parse(token, stack, context) {
const state = this;
const {fn} = token;
let value;
return parseParams(state, token.params, context)
.then(params => {
if (Twig.functions[fn]) {
// Get the function from the built-in functions
params = [Twig, context, ...params]; // --------------- MAIN LINE ---------------
value = Twig.functions[fn].apply(state, params);
} else if (typeof context[fn] === 'function') {
// Get the function from the user/context defined functions
value = context[fn](...params);
} else {
throw new Twig.Error(fn + ' function does not exist and is not defined in the context');
}
return value;
})
.then(result => {
stack.push(result);
});
}
});
});
Twig.extendFunction('hello', async function (Twig, context, date) {
const data = 'Hello, {{ name }}! Today is {{ date }}.';
const template = Twig.twig({
data: data,
});
context.date = date;
return template.renderAsync(context);
});
return Twig;
}
// index.js
const Twig = require('./twig/factory')();
const date = new Date().toString();
const template = `{{ hello('${date}') }}`;
const parameters = {
name: 'Cetver'
}
Twig
.twig({data: template})
.renderAsync(parameters)
.then(output => {
console.log(output);
});
/**
node index.js ✘ INT  1m 52s
Hello, Cetver! Today is Thu Mar 24 2022 16:17:28 GMT+0200 (Eastern European Standard Time).
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment