【问题标题】:json template engine in node.jsnode.js 中的 json 模板引擎
【发布时间】:2016-08-06 00:20:21
【问题描述】:

我有一个如下的 json 模板:

[
  {
    "type":"foo",
    "config":"{config}"
  },
  {
    "type":"bar",
    "arrConfig":"{arrConfig}"
  }
]

虽然我有一个支持模型,例如:

{
  "config": {
    "test1": "value1",
    "test2": "value2"
  },
  "arrConfig": [
    "test3": {
      "key1": "val1"
    },
    "test4": {
      "key1": "val1"
    }
  ]
}

我想知道是否有任何节点模块会自动获取这两个并转换模板中的占位符。所以输出看起来像:

[
  {
    "type":"foo",
    "config":{
      "test1": "value1",
      "test2": "value2"
    }
  },
  {
    "type":"bar",
    "arrConfig": [
      "test3": {
        "key1": "val1"
      },
      "test4": {
        "key1": "val1"
      }
    ]
  }
]

【问题讨论】:

  • 我的意思是一个快速而肮脏的解决方案只是在 JSON 上进行文本替换。您可以编写自己的函数来递归遍历对象层次结构并替换匹配的文本值。
  • 我认为这有点复杂,因为占位符值可能是对象、数组、字符串、数字等......因此我将不得不替换它

标签: javascript json node.js templates


【解决方案1】:

JSON.stringify 接受您可以用来执行此操作的替换参数。

这应该可行:

var template = [
  {
    "type":"foo",
    "config":"{config}"
  },
  {
    "type":"bar",
    "arrConfig":"{arrConfig}"
  }
];


var data = {
  "config": {
    "test1": "value1",
    "test2": "value2"
  },
  "arrConfig": {
    "test3": {
      "key1": "val1"
    },
    "test4": {
      "key1": "val1"
    }
  }
};

var replacer = function (key, val) {
   if (typeof val === 'string' && val.match(/^{(.+)}$/)) {
     return data[val.replace(/[{|}]/g, '')]
   }
   return val;
 }

 console.log(JSON.stringify(template, replacer));

如果你想将它转换回一个对象,你可以使用JSON.parse

【讨论】:

    【解决方案2】:

    这是一个遍历对象层次结构并替换模板字符串的函数,具体如下:

    // modifies the object passed, and returns the same object
    function applyTemplate(template, backing) {
      for (var i in template) {
        var m = /^{(.+)}$/.exec(template[i]);
        if (m && backing[m[1]]) {
          // replace with a deep clone of the value from the backing model
          template[i] = JSON.parse(JSON.stringify(backing[m[1]]));
        } else if (template[i] && "object" == typeof template[i]) {
          // traverse down recursively
          applyTemplate(template[i], backing);
        }
      }
      return template;
    }
    
    var template = [
      {
        "type":"foo",
        "config":"{config}"
      },
      {
        "type":"bar",
        "arrConfig":"{arrConfig}"
      }
    ];
    
    var backing = {
      "config": {
        "test1": "value1",
        "test2": "value2"
      },
      "arrConfig": {
        "test3": {
          "key1": "val1"
        },
        "test4": {
          "key1": "val1"
        }
      }
    };
    
    applyTemplate(template, backing);
    console.log(JSON.stringify(template, null, 2));

    加上使用原始 JSON 文本替换的概念验证(不可靠,实际上不要使用它;但适用于绝大多数场景):

    function applyTemplateStr(template, backing) {
      template = JSON.stringify(template);
      for (var key in backing) {
        template = template.split('"{'+key+'}"').join(JSON.stringify(backing[key]));
      }
      return JSON.parse(template);
    }
    

    【讨论】:

      【解决方案3】:

      你可以使用Mustache,像这样:

      var template = [
        {
          type: "foo",
          config: "{{config}}"
        }
      ];
      
      var data = {
        config: "hello"
      };
      
      const Mustache = require("mustache");
      
      function render(template, data) {
        return Mustache.render(JSON.stringify(template), data);
      }
      
      var output = render(template, data);
      console.log(output);  // [{"type":"foo","config":"hello"}]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-04
        • 2010-12-19
        • 2013-03-14
        • 1970-01-01
        相关资源
        最近更新 更多