-
-
Save padolsey/6008842 to your computer and use it in GitHub Desktop.
| /** | |
| * Outputs a new function with interpolated object property values. | |
| * Use like so: | |
| * var fn = makeInterpolator('some/url/{param1}/{param2}'); | |
| * fn({ param1: 123, param2: 456 }); // => 'some/url/123/456' | |
| */ | |
| var makeInterpolator = (function() { | |
| var rc = { | |
| '\n': '\\n', '\"': '\\\"', | |
| '\u2028': '\\u2028', '\u2029': '\\u2029' | |
| }; | |
| return function makeInterpolator(str) { | |
| return new Function( | |
| 'o', | |
| 'return "' + ( | |
| str | |
| .replace(/["\n\r\u2028\u2029]/g, function($0) { | |
| return rc[$0]; | |
| }) | |
| .replace(/\{([\s\S]+?)\}/g, '" + o["$1"] + "') | |
| ) + '";' | |
| ); | |
| }; | |
| }()); | |
| var url = makeInterpolator('http://something.com/{param}/{foo}?x={n}'); | |
| url({ | |
| param: '123', | |
| foo: '456', | |
| n: 789 | |
| }); |
@calvinmetcalf AFAICT that runs the replace(...) at runtime when passing the data, right? My intent with this interpolator was runtime performance, sacrificing creation-time performance, hence the creation of a compiled Function with a straight-up concatenation inside.
@mathiasbynens: tbh I wasn't inspired by RFC6570 -- but looking at it now it seems v. useful. I also found https://github.com/fxa/uritemplate-js
@padolsey FWIW, @rodneyrehm’s URI.js also supports it: http://medialize.github.io/URI.js/uri-template.html
Only special-casing \n and \r is not enough. Having \u2028 or \u2029 in the input string still throws an error. Just replace them with their (double-)escaped equivalents and you’ll be fine.
@mathiasbynens: cool, thanks! -- just edited it.
@padolsey I got what you were going for after I read your blog post
@JamesMGreene: I tried something like this:
But since we would then be replacing a literal
\nwith\\\nit won't work. The compiled Function requires the actual literal string\\nbut this cannot be generated in such a meta way without directly writing it AFAIK. (brain silently implodes)Give it a try though -- I may have missed something very obvious...