Skip to content

Commit

Permalink
Merge pull request #1 from t00f/improvements
Browse files Browse the repository at this point in the history
Enable inner parameters in a string
  • Loading branch information
curran authored Oct 6, 2016
2 parents fd7b852 + 123c4a7 commit ce61759
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 22 deletions.
36 changes: 14 additions & 22 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// By Curran Kelleher
// September 2016

const regex = new RegExp(/{{(\w+)(:?(.*))+}}/i);

// Parses the given template object.
// Returns a function `template(context)` that will "fill in" the template
Expand All @@ -29,21 +30,22 @@ function parse(value){
// handles arrays and dates as well.
function type(value){
return (
Array.isArray(value) ? "array" :
value instanceof Date ? "date" :
Array.isArray(value) ? "array" :
value instanceof Date ? "date" :
typeof value
);
}

// Parses leaf nodes of the template object that are strings.
function parseString(str){
if(isTemplateString(str)){
var parameter = Parameter(str);
var match = str.match(regex),
parameter = Parameter(match);
return Template(function (context){
if(typeof context === "undefined"){
context = {};
}
return context[parameter.key] || parameter.defaultValue;
return str.replace(match[0], context[parameter.key] || parameter.defaultValue);
}, [parameter]);
} else {
return Template(function (){
Expand All @@ -54,29 +56,19 @@ function parseString(str){

// Checks whether a given string fits the form {{xyz}}.
function isTemplateString(str){
return (
(str.length > 5)
&&
(str.substr(0, 2) === "{{")
&&
(str.substr(str.length - 2, 2) === "}}")
);
return regex.test(str);
}

// Constructs a parameter object from the given template string.
// e.g. "{{xyz}}" --> { key: "xyz" }
// e.g. "{{xyz:foo}}" --> { key: "xyz", defaultValue: "foo" }
function Parameter(str){

// Constructs a parameter object from a match result.
// e.g. "['{{foo}}','foo','','',index:0,input:'{{foo}}']" --> { key: "foo" }
// e.g. "['{{foo:bar}}','foo',':bar','bar',index:0,input:'{{foo:bar}}']" --> { key: "foo", defaultValue: "bar" }
function Parameter(match){
var parameter = {
key: str.substring(2, str.length - 2)
key: match[1],
};

var colonIndex = parameter.key.indexOf(":");
if(colonIndex !== -1){
parameter.defaultValue = parameter.key.substr(colonIndex + 1);
parameter.key = parameter.key.substr(0, colonIndex);
}
if (match[3] && match[3].length > 0)
parameter.defaultValue = match[3];

return parameter;
}
Expand Down
12 changes: 12 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,25 @@ describe("json-template", function() {
assert.equal(template({ unknownParam: "baz" }), "bar:baz");
});

it("should compute template for a string with inner parameter", function() {
var template = parse("Hello {{foo}}, how are you ?");
assert.deepEqual(template.parameters, [{ key: "foo" }]);
assert.equal(template({ foo: "john" }), "Hello john, how are you ?");
});

});


// This section tests that the parse function recursively
// traverses objects, and applies the string templating correctly.
describe("objects", function() {

it("should compute template with an object that has inner parameter", function() {
var template = parse({ title: "Hello {{foo}}, how are you ?" });
assert.deepEqual(template.parameters, [{ key: "foo" }]);
assert.deepEqual(template({ foo: "john" }), { title: "Hello john, how are you ?" });
});

it("should compute template with an object", function() {
var template = parse({ title: "{{foo}}" });
assert.deepEqual(template.parameters, [{ key: "foo" }]);
Expand Down

0 comments on commit ce61759

Please sign in to comment.