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