{"action":"created","issue":{"url":"https://api.github.com/repos/rethinkdb/rethinkdb/issues/3353","labels_url":"https://api.github.com/repos/rethinkdb/rethinkdb/issues/3353/labels{/name}","comments_url":"https://api.github.com/repos/rethinkdb/rethinkdb/issues/3353/comments","events_url":"https://api.github.com/repos/rethinkdb/rethinkdb/issues/3353/events","html_url":"https://github.com/rethinkdb/rethinkdb/issues/3353","id":49323653,"number":3353,"title":"ReQL proposal: string templating","user":{"login":"marshall007","id":877936,"avatar_url":"https://avatars.githubusercontent.com/u/877936?v=3","gravatar_id":"","url":"https://api.github.com/users/marshall007","html_url":"https://github.com/marshall007","followers_url":"https://api.github.com/users/marshall007/followers","following_url":"https://api.github.com/users/marshall007/following{/other_user}","gists_url":"https://api.github.com/users/marshall007/gists{/gist_id}","starred_url":"https://api.github.com/users/marshall007/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marshall007/subscriptions","organizations_url":"https://api.github.com/users/marshall007/orgs","repos_url":"https://api.github.com/users/marshall007/repos","events_url":"https://api.github.com/users/marshall007/events{/privacy}","received_events_url":"https://api.github.com/users/marshall007/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rethinkdb/rethinkdb/labels/tp:RQL_proposal","name":"tp:RQL_proposal","color":"0052cc"}],"state":"open","locked":false,"assignee":null,"milestone":{"url":"https://api.github.com/repos/rethinkdb/rethinkdb/milestones/2","html_url":"https://github.com/rethinkdb/rethinkdb/milestones/backlog","labels_url":"https://api.github.com/repos/rethinkdb/rethinkdb/milestones/2/labels","id":211054,"number":2,"title":"backlog","description":"Issues in this milestone are not an immediate priority, and will be periodically revisited. When we decide to work on an issue in backlog, we'll move it to next.","creator":{"login":"coffeemug","id":48436,"avatar_url":"https://avatars.githubusercontent.com/u/48436?v=3","gravatar_id":"","url":"https://api.github.com/users/coffeemug","html_url":"https://github.com/coffeemug","followers_url":"https://api.github.com/users/coffeemug/followers","following_url":"https://api.github.com/users/coffeemug/following{/other_user}","gists_url":"https://api.github.com/users/coffeemug/gists{/gist_id}","starred_url":"https://api.github.com/users/coffeemug/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coffeemug/subscriptions","organizations_url":"https://api.github.com/users/coffeemug/orgs","repos_url":"https://api.github.com/users/coffeemug/repos","events_url":"https://api.github.com/users/coffeemug/events{/privacy}","received_events_url":"https://api.github.com/users/coffeemug/received_events","type":"User","site_admin":false},"open_issues":358,"closed_issues":5,"state":"open","created_at":"2012-11-11T14:16:11Z","updated_at":"2015-03-04T01:49:17Z","due_on":null,"closed_at":null},"comments":4,"created_at":"2014-11-19T03:14:13Z","updated_at":"2015-03-05T05:06:53Z","closed_at":null,"body":"String building is a bit of a pain right now, at least in the JS driver. This is loosely related to #3048.\r\n```js\r\nr.table('foo').map({\r\n  id: r.row('id'),\r\n  bars: r.http(r.add(r.args(['http://example.com/foos/', r.row('id'), '/bars?type=', r.row('type')])))\r\n})\r\n```\r\n\r\nIt would be nice to have something like this:\r\n```js\r\nr.table('foo').map({\r\n  id: r.row('id'),\r\n  bars: r.http(r.fmt('http://example.com/foos/{id}/bars?type={type}', r.row))\r\n})\r\n```"},"comment":{"url":"https://api.github.com/repos/rethinkdb/rethinkdb/issues/comments/77307349","html_url":"https://github.com/rethinkdb/rethinkdb/issues/3353#issuecomment-77307349","issue_url":"https://api.github.com/repos/rethinkdb/rethinkdb/issues/3353","id":77307349,"user":{"login":"marshall007","id":877936,"avatar_url":"https://avatars.githubusercontent.com/u/877936?v=3","gravatar_id":"","url":"https://api.github.com/users/marshall007","html_url":"https://github.com/marshall007","followers_url":"https://api.github.com/users/marshall007/followers","following_url":"https://api.github.com/users/marshall007/following{/other_user}","gists_url":"https://api.github.com/users/marshall007/gists{/gist_id}","starred_url":"https://api.github.com/users/marshall007/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marshall007/subscriptions","organizations_url":"https://api.github.com/users/marshall007/orgs","repos_url":"https://api.github.com/users/marshall007/repos","events_url":"https://api.github.com/users/marshall007/events{/privacy}","received_events_url":"https://api.github.com/users/marshall007/received_events","type":"User","site_admin":false},"created_at":"2015-03-05T05:06:53Z","updated_at":"2015-03-05T05:06:53Z","body":"Here's a quick and dirty client-side implementation I've been using in case anyone else finds it useful:\r\n\r\n```js\r\nr.fmt = function (template, params) {\r\n  var parts = template.split(/(\\{\\w+\\})/g).map(function (part) {\r\n    if (part.indexOf('{') === 0) {\r\n      var name = part.slice(1, -1);\r\n      return params(name).coerceTo('string');\r\n    }\r\n    return part;\r\n  });\r\n  \r\n  return r.add(r.args(parts));\r\n};\r\n```\r\n\r\nExample usage:\r\n\r\n```js\r\nr.fmt('http://example.com/foos/{id}/bars?type={type}', r.expr({\r\n  id: 123,\r\n  type: 'tag'\r\n}))\r\n// => \"http://example.com/foos/123/bars?type=tag\"\r\n```"}}