diff --git a/nodes/core/core/80-template.js b/nodes/core/core/80-template.js index 85efaccbe..02d34e9b9 100644 --- a/nodes/core/core/80-template.js +++ b/nodes/core/core/80-template.js @@ -22,9 +22,10 @@ module.exports = function(RED) { * Custom Mustache Context capable to resolve message property and node * flow and global context */ - function NodeContext(msg, nodeContext,parent) { + function NodeContext(msg, nodeContext, parent, escapeStrings) { this.msgContext = new mustache.Context(msg,parent); this.nodeContext = nodeContext; + this.escapeStrings = escapeStrings; } NodeContext.prototype = new mustache.Context(); @@ -34,6 +35,14 @@ module.exports = function(RED) { try { var value = this.msgContext.lookup(name); if (value !== undefined) { + if (this.escapeStrings && typeof value === "string") { + value = value.replace(/\\/g, "\\\\"); + value = value.replace(/\n/g, "\\n"); + value = value.replace(/\t/g, "\\t"); + value = value.replace(/\r/g, "\\r"); + value = value.replace(/\f/g, "\\f"); + value = value.replace(/[\b]/g, "\\b"); + } return value; } @@ -73,7 +82,11 @@ module.exports = function(RED) { try { var value; if (node.syntax === "mustache") { - value = mustache.render(node.template,new NodeContext(msg, node.context())); + if (node.outputFormat === "json") { + value = mustache.render(node.template,new NodeContext(msg, node.context(), null, true)); + } else { + value = mustache.render(node.template,new NodeContext(msg, node.context(), null, false)); + } } else { value = node.template; } diff --git a/test/nodes/core/core/80-template_spec.js b/test/nodes/core/core/80-template_spec.js index 811e7f179..b59c0f46c 100644 --- a/test/nodes/core/core/80-template_spec.js +++ b/test/nodes/core/core/80-template_spec.js @@ -88,6 +88,18 @@ describe('template node', function() { }); }); + it('should handle escape characters in Mustache format and JSON output mode', function(done) { + var flow = [{id:"n1", type:"template", field:"payload", syntax:"mustache", template:"{\"data\":\"{{payload}}\"}", output:"json", wires:[["n2"]]},{id:"n2",type:"helper"}]; + helper.load(templateNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.payload.should.have.property('data', 'line\t1\nline\\2\r\nline\b3\f'); + done(); + }); + n1.receive({payload:"line\t1\nline\\2\r\nline\b3\f"}); + }); + }); it('should modify payload in plain text mode', function(done) { var flow = [{id:"n1", type:"template", field:"payload", syntax:"plain", template:"payload={{payload}}",wires:[["n2"]]},{id:"n2",type:"helper"}];