Method to get an array of variable names used in a parsed template
amit777 opened this issue · 2 comments
amit777 commented
Hi, we need to do some validation in our code regarding the names of parameters within a liquid template. Ideally I would like to do something like
const { Liquid } = require('liquidjs');
async function main() {
const engine = new Liquid();
const template = `
Hello, {{ name }}! You like {{ pet }}
`;
const parsedTemplate = engine.parse(template);
const variables = parsedTemplate.extractVariables(parsedTemplate);
// variables should be ['name', 'pet']
}
Is there an easy way to do this?
harttle commented
AFAIK, no. I assume you need top level names. But names can be nested in scopes and builtin drops like in for tag. And can be dynamic.
I would like to implement one if it can be clearly defined and still useful.
amit777 commented
yes, just top level static variable names would be sufficient for my use case. I see your point about dynamic variables though. I wrote this very hacky method:
const _extractTemplateVars = function (parsedTemplate) {
const variables = new Set();
function traverseTokens (tokens) {
for (const token of tokens) {
if (token.token.constructor.name === 'OutputToken') {
for (let p of token.value?.initial?.postfix) {
let prop = p.props[0];
if (prop.constructor.name === 'IdentifierToken') {
variables.add(prop.content);
}
}
}
else if (token.token.constructor.name === 'TagToken') {
for (let branch of token.branches) {
traverseTokens(branch.templates);
}
}
}
}
traverseTokens(parsedTemplate);
return variables ;
}