You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从含if语句的Handlebars文本中提取所有嵌入变量?

解决Handlebars嵌套块中变量提取问题

你的问题出在当前函数只遍历了AST的顶级节点,而{{#if}}这类块语句属于BlockStatement类型,其内部的变量节点被嵌套在BlockStatement的body属性中,没有被递归遍历到。

要提取所有嵌套变量,需要编写递归逻辑遍历AST的所有节点,包括块语句内部的内容:

import Handlebars from "handlebars";

function getHandlebarsVariables(input) {
    const ast = Handlebars.parseWithoutProcessing(input);
    const variables = [];

    // 递归遍历AST节点收集变量
    function collectNodes(nodes) {
        nodes.forEach(node => {
            // 处理普通变量节点
            if (node.type === 'MustacheStatement') {
                const varName = node.params[0]?.original || node.path?.original;
                if (varName) {
                    variables.push(varName);
                }
            }
            // 处理块语句(如#if、#each),递归遍历其内部节点
            else if (node.type === 'BlockStatement') {
                collectNodes(node.body);
                // 可选:处理块语句的else分支(如果需要提取else里的变量)
                if (node.elseBody) {
                    collectNodes(node.elseBody);
                }
            }
            // 可按需扩展处理其他包含子节点的类型,比如PartialStatement
        });
    }

    collectNodes(ast.body);
    // 可选:去重,避免重复变量多次出现
    return [...new Set(variables)];
};

const text1 = '{{name}} {{age}} {{#if isAdult}} {{ Adult }} {{/if}}';
const variables = getHandlebarsVariables(text1);
console.log(variables); // 现在返回 ['name', 'age', 'Adult']

关键说明:

  • BlockStatement类型的节点包含body属性,存储了块内的所有子节点,必须递归遍历才能获取内部变量
  • 新增的collectNodes函数负责递归处理所有节点类型,覆盖顶级和嵌套场景
  • 加入了可选的去重逻辑(使用Set),避免重复变量多次出现
  • 额外处理了elseBody分支,可覆盖{{else}}块内的变量提取需求

内容的提问来源于stack exchange,提问作者Juan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:13:15