Skip to content

Instantly share code, notes, and snippets.

@tal
Created May 1, 2014 03:34
Show Gist options
  • Save tal/73152d758862dc8d3a1b to your computer and use it in GitHub Desktop.
Save tal/73152d758862dc8d3a1b to your computer and use it in GitHub Desktop.
/**
* Path Set
* @author Tal Atlas <[email protected]>
*
* A libary for storing and generating paths for an application based on params.
* If jquery is avaialable it will encode the params using jQuery.param()
*
* ps = new PathSet({
* root: '/',
* group: '/groups/:id(.:format)',
* group_pictures: '/groups/:group_id/pictures(/:id)(.:format)'
* });
*
* ps.group_pictures_path({group_id: 123}) // => /groups/123/pictures
* ps.group_pictures_path({group_id: 123, foo: 'bar'}) // => /groups/123/pictures?foo=bar
* ps.group_pictures_path({group_id: 123, format: 'json'}) // => /groups/123/pictures.json
* ps.group_pictures_path({group_id: 123, id: 345}) // => /groups/123/pictures/345
* ps.domain = 'mydomain.com'
* ps.groups_url({id: 123}) // => http://mydomain.com/groups/123
* ps.groups_url({id: 123},'otherdomain.com') // => http://otherdomain.com/groups/123
*
* If you have jquery installed theres a helper method to make ajax calls based on the
* route name:
*
* jqXHR = ps.ajax('group_pictures',{group_id: 123, picture_name: 'Pretty'},
* {type: 'POST', dataType: 'json'});
*/
(function() {
window.PathSet = function PathSet(paths,options) {
var url, self = this, pathName;
options || (options = {});
this.paths = paths;
this.domain = options.domain || document.location.protocol+'//'+document.location.hostname;
function buildFunc(pathName) {
self[pathName+'_path'] = function(params) {
return PathSet.buildFullUrl(paths[pathName],params);
}
self[pathName+'_url'] = function(params,domain) {
domain || (domain = self.domain);
return PathSet.buildFullUrl(paths[pathName],params, domain);
}
self['build_'+pathName] = function(params) {
return PathSet.buildUrl(paths[pathName],params);
}
}
for (pathName in paths) {
buildFunc(pathName);
}
};
var PATH_REG = /(.+)(?:\((?:[^:)]*:\w[a-z0-9:\/\-_(.]*)\))/i, r20 = /%20/g;
PathSet.buildUrl = function buildUrl(path,origParams) {
var re = /:(\w+)/g, match, pathMatch, value, url, params = {};
url = path;
origParams || (origParams = {});
for (var k in origParams) {
if (origParams.hasOwnProperty(k)) {
params[k] = origParams[k];
}
}
// Match all values in url and replace them with values from the form
while (match = re.exec(path)) {
value = params[match[1]];
if (value) {
url = url.replace(match[0],value);
delete params[match[1]];
}
}
// Remove optional portions of the path
while (match = url.match(PATH_REG)) {
url = url.replace(PATH_REG,'$1');
}
url = url.replace(/[()]/g,'');
return {url: url, params: params};
}
PathSet.buildFullUrl = function buildFullUrl(path,params,domain) {
var urlData = PathSet.buildUrl(path,params), url = urlData.url;
params = urlData.params;
// Append all additional params to the query string
var additional_params = []
if (jQuery && jQuery.param) {
var jqParams = jQuery.param(params);
if (jqParams) additional_params.push(jqParams);
} else {
for (var param in params) {
additional_params.push((encodeURIComponent(param)+'='+encodeURIComponent(params[param])).replace(r20,'+'));
}
}
if (additional_params.length) {
if (url.match(/\?/)) url = url + '&';
else url = url+'?';
url = url + additional_params.join('&');
}
if (domain) {
if (domain.match(/^http(s)?:\/\//)) {
host = domain;
} else {
host = document.location.protocol + '//' + domain;
}
url = host + url;
}
return url;
};
if (jQuery && jQuery.ajax) {
PathSet.prototype.ajax = function pathSetAjax(route,routeParams,options) {
var url;
options || (options = {data: {}, headers: {}});
options.data || (options.data = {});
switch (options.type) {
case 'DELETE':
case 'delete':
case 'PATCH':
case 'patch':
case 'PUT':
case 'put':
case 'OPTIONS':
case 'options':
options.data._method = options.type;
options.type = "post";
}
url = PathSet.buildUrl(this.paths[route],routeParams);
for (var key in url.params) {
if (url.params.hasOwnProperty(key) && options.data[key] === undefined) {
options.data[key] = url.params[key];
}
}
return jQuery.ajax(url.url, options);
};
}
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment