More complicated JavaScript string tokenizer – and Twitter Conversations
(I'm not sure when I started using the term tokenizer - "formatter" may be more common...)
I’ve experimented in the past with a C# string.Format() alternative that would allow property names as tokens rather than the numeric index based tokens that string.Format() uses. Hardly a unique approach, and many others did it better.
Here’s another first-draft ‘tokenizer’, this time in JavaScript:
String.prototype.format = function(tokens) { ///<summary> ///This is an extension method for strings, using string or numeric tokens (e.g. {foo} or {0}) to format the string. ///<summary> ///<param name="tokens">One or more replacement values ///if a single object is passed, expects to match tokens with object property names, ///if a single string, number or boolean, replaces any and all tokens with the string ///if multiple arguments are passed, replaces numeric tokens with the arguments, in the order passed ///</param> ///<returns>the string with matched tokens replaced</returns> var text = this; try { switch (arguments.length) { case 0: { return this; }; case 1: { switch (typeof tokens) { case "object": { //loop through all the properties in the object and replace tokens matching the names var token; for (token in tokens) { if (!tokens.hasOwnProperty(token) || typeof tokens[token] === 'function') { break; } //else text = text.replace(new RegExp("\\{" + token + "\\}", "gi"), tokens[token]) } return text; }; case "string": case "number": case "boolean": { return text.replace(/{[a-z0-9]*}/gi, tokens.toString()); }; default: return text; }; }; default: { //if multiple parameters, assume numeric tokens, where each number matches the argument position for (var i = 0; i < arguments.length; i++) { text = text.replace(new RegExp("\\{" + i + "\\}", "gi"), arguments[i].toString()); } return text; }; }; } catch (e) { return text; } };
The comment (in VS Intellisense format) is pretty self-explanatory, note that it doesn’t allow any special formatting as String.Format does, nor does it even support escaping {}‘s – in general it is quite crude.
That said, when used within it’s limitations it works - below are a couple of actual usage scenarios, both from my ongoing Twitter Conversations experiment:
var url = "http://search.twitter.com/search.json?q=from:{p1}+to:{p2}+OR+from:{p2}+to:{p1}&since={d1}&until={d2}&rpp=50".format({ p1: $("#p1").attr("value"), p2: $("#p2").attr("value"), d1: $("#d1alt").attr("value"), d2: $("#d2alt").attr("value") });
and
$.getJSON(url + "&callback=?", function(data) { $.each(data.results, function(i, result) { content = ' \ <p> \ <a href="http://twitter.com/{from_user}"><img src="{profile_image_url}" />{from_user}</a> \ (<a href="http://twitter.com/{from_user}/statuses/{id}">{created_at}</a>): \ {text} \ </p>'.format(result);
The working Twitter Conversations sample is here, as you can tell it’s really just a wrapper around the Twitter Search API.
Labels: experiment, javascript, mashup, me-me-me
1 Comments:
Before anyone beats me to it: the (v)sprintf jQuery plugin by m0n5t3r does something very similar to this - and is much more robust.
I'm also contemplating replacing the use of this with a client side templating framework.
By Oskar Austegard, at Wednesday, June 17, 2009 1:30:00 PM
Post a Comment
<< Home