Home >
This is a great technique I picked up from a friend of mine, Myles Bieniasz, on his blog here. I modified his code and created this utility that will search through a given string for words wrapped in a ${ } and replace them with matching properties on an given object. Lets take a look at this utility in action:
First we need to create a new project called TokenTutorial and use the following code for the TokenTutorial Class:
package {
import com.oreilly.utils.TokenUtil;
import flash.display.Sprite;
public class TokenTutorial extends Sprite
{
public function TokenTutorial()
{
demo1();
demo2();
}
/**
* Demo 1 shows you how we can take a string and replace values inside
* of it by running it through the TokenUtil.
*/
public function demo1():void
{
var sampleText:String = "Hello ${text}, ${message}.";
var token:Object = { text: "World", message: "this is my token demo" };
var replacedText:String = TokenUtil.replaceTokens(sampleText, token);
trace( "Demo 1 - String Replace:" );
trace( "Original Text: ", sampleText );
trace( "Replaced Text: ", replacedText, "\n" );
}
/**
* Demo 2 shows you how you can take a api call, and dynamically change
* parameters in it through the TokenUtil.
*/
public function demo2():void
{
var twitterAPI:String = "http://twitter.com/statuses/${method}/${user}.xml";
var token:Object = { method: "user_timeline", user: "theflashbum" };
var replacedAPI:String = TokenUtil.replaceTokens(twitterAPI, token);
trace( "Demo 2 - Twitter API Call:" );
trace( "Original Text: ", twitterAPI );
trace( "Replaced Text: ", replacedAPI, "\n" );
}
}
}
Next we will create the TokenUtil in a com.oreilly.utils package:
package com.oreilly.utils
{
public class TokenUtil
{
public static const CURLY_BRACES_PATTERN:RegExp = /\$\{([\w'-]+)\}/g;
public static const BRACKET_PATTERN:RegExp = /\$\[([\w'-]+)\]/g;
/**
* This util will take a string, search for ${tokens} and replace them
* with the values in the supplied object.
* @param text - text you would like to search for tokens
* @param paramObj - an object to use to find and replace tokens with
* @param replaceUndefineds - string to use when undefined are found
* @param overrideRegEx - override the default regex pattern
* @return
*
*/
public static function replaceTokens(text:String, paramObj: Object = null, replaceUndefineds:String = "", overrideRegEx:RegExp = null) : String{
if(!paramObj){
return text;
}else{
var myRegEx:RegExp = overrideRegEx ? overrideRegEx : CURLY_BRACES_PATTERN;
var cleanText:String = text.replace(myRegEx,function():*{return paramObj[arguments[1]]});
cleanText = cleanText.replace(/undefined/gi,replaceUndefineds);
return cleanText;
}
}
}
}
Once we have our utility in place we can give it a test. After running the demo you will see the following output:
Demo 1 - String Replace:
Original Text: Hello ${text}, ${message}.
Replaced Text: Hello World, this is my token demo.
Demo 2 - Twitter API Call:
Original Text: http://twitter.com/statuses/${method}/${user}.xml
Replaced Text: http://twitter.com/statuses/user_timeline/theflashbum.xml
As you can see this is a powerful utility that allows you to create string templates of your applications' text and api calls, then dynamically fill in the values you need at run time. Hope you find this as useful as I do!




Facebook Application Development
Nice class, I see alot of instances where this would be useful.
One question though,
Why use
function():*{return paramObj[arguments[1]]}
and not just
paramObj[arguments[1]]
Thanks for the question. Without the return, the replace will not get a value to put in the place of the token it finds.
Hope that helps,
Jesse
Jesse, could you give an example of when this would be useful? I don't interface with external APIs ever. Would it be used if I had built an app that consumes Twitter services. With the data Twitter sends to me, I would use a search and replace to extract certain properties, i.e ${some tweet from Twitter}.
Here are two useful examples:
Email Message- Lets say you have some text in your app and you want to replace specific part of the text like in a email, take a look at this:
"Hello ${username}, This is a Flash Email message."You could run the above string through the util and replace the ${username} on the fly. Along the same line I use this idea for error messages:
"There was an ${errorNumber} with the following message ${errorMessage}"The next example is for API/URL calls. If you are not using an API you still may be loading in images from a server. Check out this url I have loaded in from an xml:
image src="${baseURL}/${imageFolder}/image.jpg"You may want to change the baseURL and the imageFolder on the fly depending on if you are on a local server testing or production but if your XML is not server generated you have to do it by hand at runtime. If you load the XML in as a string (which happens by default) then run it through the util, you can replace values in the XML before you turn it into XML.
I think it would also be good to have it as a package function instead of a class which is not needed in this case.
The AS3 API also has mx.utils.StringUtil.substitute which can replace curly bracket values like:
StringUtil.substitute("There was an {0} with the following message {1}", errorNumber, errorMessage).
That's also used for localization placeholders.
You may want to change the baseURL and the imageFolder on the fly depending on if you are on a local server testing or production but if your XML is not server generated you have to do it by hand at runtime. If you load the XML in as a string (which happens by default) then run it through the util, you can replace values in the XML before you turn it into XML.