Reputation: 1185
I have a json template like the following:
[
{
"type":"foo",
"config":"{config}"
},
{
"type":"bar",
"arrConfig":"{arrConfig}"
}
]
While i have a backing model like:
{
"config": {
"test1": "value1",
"test2": "value2"
},
"arrConfig": [
"test3": {
"key1": "val1"
},
"test4": {
"key1": "val1"
}
]
}
I'm wondering if there are any node modules out there which will automatically take these two and transform the placeholders in the template. So the output would look like:
[
{
"type":"foo",
"config":{
"test1": "value1",
"test2": "value2"
}
},
{
"type":"bar",
"arrConfig": [
"test3": {
"key1": "val1"
},
"test4": {
"key1": "val1"
}
]
}
]
Upvotes: 3
Views: 7119
Reputation: 1762
You can use Mustache, like so:
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"}]
Upvotes: 1
Reputation: 3661
JSON.stringify
accepts a replacer param that you could use to do it.
This should work:
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));
And if you want to transform it back to an object you can use JSON.parse
Upvotes: 6
Reputation: 3864
Here is a function to traverse an object hierarchy and replace template strings, as specified:
// 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));
Plus a proof-of-concept using raw JSON text replacement (not robust, don't actually use this; but works for the vast majority of scenarios):
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);
}
Upvotes: 4