Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,28 @@ In browser:
var template2 = new UriTemplate("/prefix/{?params*}");
```

## Configuration
You can provide a configuration object as the second argument:
```javascript
new UriTemplate("/prefix/{?params*}", {
leaveUnmatchedPlaceholders: true
});
```

`leaveUnmatchedPlaceholders` defaults to `false`. When `true` any placeholders which do not have a corresponding key in the object, or their value is `null`, will be left in the built URL.

E.g.
```javascript
var template = new UriTemplate("/prefix/{a}?arg1={arg1Value}", {
leaveUnmatchedPlaceholders: true
});

console.log(template.fill({
a: "something"
}));
```
will output "/prefix/something?arg1={arg1Value}".

## Substitution using an object
```javascript
// "/categories/green/round/"
Expand Down
75 changes: 51 additions & 24 deletions test/custom-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,41 @@ var UriTemplate = require('../uri-templates');
var assert = require('proclaim');

describe("Guessing variable priority", function () {
it('GitHub issue #8', function () {
var template = new UriTemplate("{+path}/c/capture{/date,id,page}");
var guess = template.fromUri('/a/b/c/capture/20140101/1');

// we already test elsewhere that this reconstructs correctly - we just want to make sure variables are prioritised left-to-right
assert.strictEqual(guess.date, '20140101');
assert.strictEqual(guess.id, '1');
assert.strictEqual(guess.page, undefined);
})
it('GitHub issue #8', function () {
var template = new UriTemplate("{+path}/c/capture{/date,id,page}");
var guess = template.fromUri('/a/b/c/capture/20140101/1');

// we already test elsewhere that this reconstructs correctly - we just want to make sure variables are prioritised left-to-right
assert.strictEqual(guess.date, '20140101');
assert.strictEqual(guess.id, '1');
assert.strictEqual(guess.page, undefined);
})
});

describe("Original string available", function () {
it('GitHub issue #7', function () {
var template = new UriTemplate("{+path}/c/capture{/date,id,page}");
it('GitHub issue #7', function () {
var template = new UriTemplate("{+path}/c/capture{/date,id,page}");

assert.strictEqual(template.template, '{+path}/c/capture{/date,id,page}');
assert.strictEqual(template + "", '{+path}/c/capture{/date,id,page}');
})
assert.strictEqual(template.template, '{+path}/c/capture{/date,id,page}');
assert.strictEqual(template + "", '{+path}/c/capture{/date,id,page}');
})
});

describe("Query optional when decoding", function () {
it('GitHub issue #12', function () {
var template = new UriTemplate("{/type,ids,field}{?query*}");
it('GitHub issue #12', function () {
var template = new UriTemplate("{/type,ids,field}{?query*}");

var uri = '/user/1,2,3/posts';
var guess = template.fromUri(uri);
assert.isObject(guess);
var uri = '/user/1,2,3/posts';
var guess = template.fromUri(uri);
assert.isObject(guess);

var trimmed = template.fill(guess).replace(/\?$/, '');
assert.strictEqual(trimmed, uri);
});
var trimmed = template.fill(guess).replace(/\?$/, '');
assert.strictEqual(trimmed, uri);
});
});

describe("Decode empty query", function () {
it('Must return a empty object', function () {
it('Must return a empty object', function () {
var template = new UriTemplate('{?query}');

var uri = '?';
Expand All @@ -45,7 +45,7 @@ describe("Decode empty query", function () {
assert.isUndefined(guess['']);
});

it('Must return a empty object in property', function () {
it('Must return a empty object in property', function () {
var template = new UriTemplate('{?query*}');

var uri = '?';
Expand All @@ -54,3 +54,30 @@ describe("Decode empty query", function () {
assert.isUndefined(guess['']);
});
});

describe("'leaveUnmatchedPlaceholders' option enabled", function () {
it('Placeholder remains when property missing', function () {
var template = new UriTemplate('{a}/{b}{c}', {
leaveUnmatchedPlaceholders: true
});

var result = template.fill({
a: "1",
b: "2"
});
assert.strictEqual(result, "1/2{c}");
});

it('Placeholder remains when property is null', function () {
var template = new UriTemplate('{a}/{b}{c}', {
leaveUnmatchedPlaceholders: true
});

var result = template.fill({
a: "1",
b: "2",
c: null
});
assert.strictEqual(result, "1/2{c}");
});
});
14 changes: 11 additions & 3 deletions uri-templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
var varSpecMap = {};
for (var i = 0; i < varList.length; i++) {
var varName = varList[i];
var completeVarName = varName;
var truncate = null;
if (varName.indexOf(":") != -1) {
var parts = varName.split(":");
Expand All @@ -83,7 +84,8 @@
var varSpec = {
truncate: truncate,
name: varName,
suffices: suffices
suffices: suffices,
completeVarName: completeVarName
};
varSpecs.push(varSpec);
varSpecMap[varName] = varSpec;
Expand All @@ -96,6 +98,10 @@
var varSpec = varSpecs[i];
var value = valueFunction(varSpec.name);
if (value == null || (Array.isArray(value) && value.length == 0) || (typeof value == 'object' && Object.keys(value).length == 0)) {
if (value == null && this.options.leaveUnmatchedPlaceholders) {
// leave this template placeholder in the final url
result += "{"+varSpec.completeVarName+"}";
}
startIndex++;
continue;
}
Expand Down Expand Up @@ -317,7 +323,8 @@
};
}

function UriTemplate(template) {
function UriTemplate(template, options) {
options = options || {};
if (!(this instanceof UriTemplate)) {
return new UriTemplate(template);
}
Expand Down Expand Up @@ -349,7 +356,7 @@
var result = textParts[0];
for (var i = 0; i < substitutions.length; i++) {
var substitution = substitutions[i];
result += substitution(valueFunction);
result += substitution.call(this, valueFunction);
result += textParts[i + 1];
}
return result;
Expand Down Expand Up @@ -405,6 +412,7 @@
}
this.varNames = varNames;
this.template = template;
this.options = options;
}
UriTemplate.prototype = {
toString: function () {
Expand Down
2 changes: 1 addition & 1 deletion uri-templates.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.